# coding: utf-8
# OpenCVを学ぶ
画素値は(B,G,R) 0-255で表現する。
画像の左上が原点(0,0)
#画像処理=解析しやすくする。情報を抽出する
(1)グレースケール化+平滑化
①Gray=0.1140B+0.5870G+0.2989R
②平滑化出力画像=(I*G)
ノイズ画素を指定したとき、その周辺の画素データになじむように自分の画素データを修正する。
ガウシアンカーネル(代表的な平滑化カーネル) グレースケールの画像に畳み込む
gaussian=np.array([[1/16,2/16,/1/16],
[2/16,4/16,/2/16],
[1/16,2/16,/1/16]])
(2)グレースケール化+Canny
①Gray=0.1140B+0.5870G+0.2989R
②canny
ぼかす→微分→エッジを残す
sift surfは特許で使えないものもある
# In[ ]:
#OpenCVのコンテンツ
グレースケール
2値化
リサイズ
ガンマ変換
ヒストグラム均一化
アフィン変換
畳み込み(平滑化の一部)
平滑化
モルフォロジー演算
インペイント
#特徴抽出
線 円の検出
輪郭の検出
ブロブの検出
特徴点抽出
#動画解析
オプティカルフロー
Meansift / Camshift
背景差分
パーティクルフィルター
#そのほか
カメラモデル 機械学習 sift surf
# In[ ]:
#on anaconda pronpt
#conda create :新たな環境を作る
#-n opencv : opencvというnameの環境
#python=3.5:opencv3はpython3.5が最大 3.6には対応していないのでダウングレードして使用する
conda create -n opencv python=3.5 anaconda
#環境が作成されているか確認する
conda info -e
activate opency #環境に入る
deactivate #環境から抜ける
conda remove -n opencv --all #環境を削除(今回はやらない)
#OpenCVのインストール (環境名opencv 上にインストール)
conda install -c menpo opencv3
#インストールされたか確認
ipython #ipythonに入る
import cv2 # cv3でもcv2と記載する。ややこしいので注意
# In[ ]:
#画像の基礎知識
import cv2
img=cv2.imread(r"C:\Users\omoiy\data/src/Berry.jpg")
print(type(img))#画素値は(B,G,R) 0-255で表現する。<class 'numpy.ndarray'>
h,w=img.shape[0:2] #高さ、幅 、3つ目の成分もあるが なぞ
img.shape #(589, 960, 3)
print(h,w) #589 960
# In[ ]:
#y,x座標を指定して blue成分の値を取得する
img[300][500][0] # 104 img[y][x][color] color:B=0 ro G=1 or R=2
# In[ ]:
#画像の読み込み,表示と出力
import cv2 , os
img=cv2.imread(r"C:\Users\omoiy\data/src/Berry.jpg")
img.shape #(589, 960, 3)
img[0][0] #原点での色情報BGR array([128, 176, 194], dtype=uint8)
cv2.imshow("title",img)
cv2.waitKey(0) #3を入れると3msecキーボード入力を受け付ける。0はなにか押されるまで待つ という意味
cv2.destroyAllWindows()
os.mkdir("./output")
cv2.imwrite("output/test.jpg",img) # True
# In[ ]:
import cv2 , sys
cap=cv2.VideoCapture(r"C:\Users\omoiy\data\movie/Cosmos.mp4")#読み込む
if cap.isOpened()==False: #開けたかチェックする
sys.exit()
ret,frame=cap.read()#ret=開けたかどうか , frame=1フレーム読んだ画像
h,w=frame.shape[:2] #動画の解像度を取得。3番目の色情報は不要
print(h,w) #1080 1920
fourcc=cv2.VideoWriter_fourcc(*"XVID")#コーデックの設定情報
fps=30.0 #fpsを設定する
dst=cv2.VideoWriter("output/test.avi",fourcc,fps,(w,h))#書き込む用 。解像度の入力は(x,y)で入れるので注意
#プログラムの本体
while True:
ret,frame=cap.read() #ret=開けたかどうか , frame=1フレーム読んだ画像
if ret==False:#ちゃんと読み込めなかった場合はブレークする
break
cv2.imshow("title",frame)#1コマを表示させる
dst.write(frame)#動画を書き込む
if cv2.waitKey(30)==27:#escキーが押されるとブレークする
break
cv2.destroyAllWindows()
cap.release()
# In[ ]:
#ウィンドウの調整
import cv2
img=cv2.imread(r"C:\Users\omoiy\data\src/Lena.jpg")
cv2.namedWindow("window",cv2.WINDOW_AUTOSIZE)#ウィンドウの設定
cv2.imshow("window",img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
import cv2
img=cv2.imread(r"C:\Users\omoiy\data\src/Lena.jpg")
cv2.namedWindow("window",cv2.WINDOW_NORMAL)#ウィンドウの設定 リサイズ可能になる
cv2.imshow("window",img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
import cv2
img=cv2.imread(r"C:\Users\omoiy\data\src/Lena.jpg")
cv2.namedWindow("window",cv2.WINDOW_NORMAL)#ウィンドウの設定 リサイズ可能になる
cv2.resizeWindow("window",640,480)#解像度を指定する(アスペクト比は変わる)
cv2.imshow("window",img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
#画像のリサイズ
import cv2
img=cv2.imread(r"C:\Users\omoiy\data\src/Grapes.jpg")
#cv2.imshow("window",img)
#cv2.waitKey(0)
#cv2.destroyAllWindows()
img.shape # (640, 960, 3) =(高さ,幅,カラー画像)
size=(300,200) # 幅、高さ ※リサイズするときのパラメータは(幅,高さ)と逆になるので注意すること。
img_resize=cv2.resize(img,size)#imgをリサイズする
img_resize.shape #(200, 300, 3)
cv2.imshow("resized_img",img_resize)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
#画質を比べてみる
img_area=cv2.resize(img,size,interpolation=cv2.INTER_AREA)
img_linear=cv2.resize(img,size,interpolation=cv2.INTER_LINEAR)#デフォルトの設定はインターリニア
cv2.imshow("img_area",img_area)
cv2.imshow("ing_linear",img_linear)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
#色空間・グレースケール
RGB表現 赤 緑 青 0-255
HSV表現
色相 Hue 0-359deg 色の種類 例)黄色っぽい色=30~60
彩度 Saturation 0-100% 選んだ色相の深さ
明度 Value 0-100% 明るさ
※OpenCVでは 0-179 0-255 0-255の範囲になっているので、割合を変換して使用すること
グレースケール
Gray=0.1140B+0.5870G+0.2989R
色強度という1つの数値に簡略化するので扱いやすい。
ここから二値化をしやすい
# In[ ]:
#やってみよう
import cv2
img=cv2.imread(r"C:\Users\omoiy\data/src/grapes.jpg")
img_gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # cvt=convert の略,BGR2GRAY=BGR to グレイスケールの略
img_hsv=cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
# In[ ]:
#シェイプの内容を比較
img.shape #(640, 960, 3)
img_gray.shape #(640, 960) 色情報がなくなっている
img_hsv.shape #(640, 960, 3)
# In[ ]:
#オリジナル画像とグレースケールを比較
cv2.imshow("img",img)
cv2.imshow("img_gray",img_gray)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
#もっと簡単にグレースケール化する方法
import cv2
img_gray2=cv2.imread(r"C:\Users\omoiy\data/src/grapes.jpg",0)#cvtColor を使わない方法。imreadで読み込んだ時点で オプション0をつける
cv2.imshow("img_gray2",img_gray2)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
img_hsv
"""
h , s , v の順に並んでいるが h=46の場合、本当は2倍の92であることに注意
array([[[ 46, 138, 175],
[ 46, 152, 159],
[ 45, 128, 177],
...,
"""
# In[ ]:
#ヒストグラム
import cv2
import matplotlib.pyplot as plt
get_ipython().run_line_magic('matplotlib', 'inline')
# In[ ]:
img=cv2.imread(r"C:\Users\omoiy\data/src/Lena.jpg")
cv2.imshow("img_title",img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
color_list=["blue","green","red"]
for i,j in enumerate(color_list):
print(i,j)
hist=cv2.calcHist([img],[i],None,[256],[0,256])#カッコでくくるのがポイント 画像,番号BGR,マスク,binの数,binの数
plt.plot(hist,color=j)
# In[ ]:
img_gray=cv2.imread(r"C:\Users\omoiy\data/src/Lena.jpg",0)#グレースケールで読む
hist_gray=cv2.calcHist([img_gray],[0],None,[256],[0,256])
plt.plot(hist_gray,color="gray")
# In[ ]:
#ヒストグラムの均一化
# 結果:暗いところはより暗く 明るいところはより明るく
import cv2
import matplotlib.pyplot as plt
get_ipython().run_line_magic('matplotlib', 'inline')
img=cv2.imread(r"C:\Users\omoiy\data/src/Lena.jpg",0)
hist=cv2.calcHist([img],[0],None,[256],[0,256])
plt.plot(hist,color="gray")
# In[ ]:
img_eq=cv2.equalizeHist(img)
hist_e=cv2.calcHist([img_eq],[0],None,[256],[0,256])
plt.plot(hist_e)
# In[ ]:
cv2.imshow("img",img)
cv2.imshow("img_eq",img_eq)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
#ガンマ変換 明るさの変換
#y=255*(x/255)**(1/gamma)# γ<1:暗くなる , γ>1 :明るくなる
import cv2
import numpy as np
gamma=0.4
img=cv2.imread(r"C:\Users\omoiy\data/src/Berry.jpg")
gamma_cvt=np.zeros((256,1),dtype=np.uint8) # 256行x1列の行列を用意する
for i in range(256):#ガンマ変換
gamma_cvt[i][0]=255*(float(i)/255)**(1.0/gamma)
img_gamma=cv2.LUT(img,gamma_cvt)
cv2.imshow("img",img)
cv2.imshow("img_gamma",img_gamma)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
#トラックバーの作成
#パラメータをカンタンに調整できるように
import cv2
def onTrackbar(position):
global trackValue#グルーバル変数
trackValue=position#トラックバーを動かすと反映される
trackValue=100 #初期値
cv2.namedWindow("img")
cv2.createTrackbar("track1","img",trackValue,255,onTrackbar)
cv2.createTrackbar("track2","img",trackValue,255,onTrackbar)
cv2.createTrackbar("track3","img",trackValue,255,onTrackbar)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
#マウスイベント
import numpy as np
import cv2
def print_position(event,x,y,flags,param):#ボタンを押したときの動作を定義
if event== cv2.EVENT_LBUTTONDBLCLK:#左ボタンをダブルクリックしたとき
print(x,y)#座標を出力する
#適当な画像を用意する
img=np.zeros((512,512),np.uint8)#真っ黒
cv2.namedWindow("img")
cv2.setMouseCallback("img",print_position)
cv2.imshow("img",img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
#図形の描画
import cv2
import numpy as np
img=np.ones((500,500,3))*255#真っ白な画像を用意する
cv2.line(img,(0,0),(150,190),(255,0,0),2) #始点,終点,色,太さ
cv2.rectangle(img,(100,25),(300,150),(0,255,0),4) #始点,終点,色,太さ
cv2.circle(img,(100,100),55,(0,0,255),-1)#中心,半径,色,太さ 太さがマイナスの場合は塗りつぶしになる
cv2.ellipse(img,(250,250),(100,50),20,0,360,(255,0,0),1)#中心,(長軸,短軸),回転,書き始め角度,書き終わり角度,色,太さ
points=np.array([[100,30],[200,30],[200,80],[100,50]])
cv2.polylines(img,[points],False,(100,255,0),3)#False=閉じない , 色,太さ
font=cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img,"OpenCV",(100,300),font,1,(0,255,0),3,cv2.LINE_AA)
cv2.imshow("img",img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
#画像の二値化
#高速で処理できるように軽くする
img=cv2.imread(r"C:\Users\omoiy\data/src/grapes.jpg",0) #グレースケールとして読み込み
cv2.imshow("img",img)#画像確認
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
threshold=100#閾値
ret,img_th=cv2.threshold(img,threshold,255,cv2.THRESH_BINARY)# theresholdより大きい場合は255にする,変換方法
ret #100.0 retはリターンの意味 thresholdの値100が返ってくる
# In[ ]:
cv2.imshow("img_th",img_th)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
#オーツの方法でthresholdを自動化する
ret2,img_o=cv2.threshold(img,0,255,cv2.THRESH_OTSU)
ret2 #自動的に決まる
# In[ ]:
#オーツの方法 アルゴリズム確認
"""
仮定:暗いところと 明るいところ 分けるべきところがあるだろう
→山が二つ存在することが多いだろう。
"""
import cv2
import matplotlib.pyplot as plt
get_ipython().run_line_magic('matplotlib', 'inline')
hist=cv2.calcHist([img],[0],None,[256],[0,256])
plt.plot(hist,color="gray")
# In[ ]:
#画像比較
cv2.imshow("img_th",img_th)
cv2.imshow("img_otsu",img_o)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
#アダプティブ スレショルドを使用する
#画像全体ではなく、小さな区間に分けてやっていく
img_ada=cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,3,1)
# In[ ]:
#画像比較
cv2.imshow("img",img)
cv2.imshow("img_th",img_th)
cv2.imshow("img_otsu",img_o)
cv2.imshow("img_ada",img_ada)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
#二値化とトラックバーを組み合わせる
import cv2
img=cv2.imread(r"C:\Users\omoiy\data/src/floor.jpg",0)
"""
cv2.imshow("img",img)
cv2.waitKey(0)
cv2.destroyAllWindows()
"""
# In[ ]:
def onTrackber(position):
global threshold
threshold=position
cv2.namedWindow("img")
threshold=100#初期値
cv2.createTrackbar("track","img",threshold,255,onTrackber)
while True:
#ret,img_th=cv2.threshold(img,threshold,255,cv2.THRESH_BINARY) #通常の二値化
img_th=cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,3,threshold) #アダプティブスレショルド
cv2.imshow("img",img_th)
cv2.imshow("src",img)
if cv2.waitKey(10)==27:
break
cv2.destroyAllWindows()
#アファイン変換
回転・移動などの線形変換
変換後 回転移動 変換前 平行移動
[[x_prime] [[a,b] [[x] [[t_x]
[y_prime]] = [c,d]] ・ [y]] + [t_y]]
まとめると
[[x_prime] [[a,b,t_x] [[x]
[y_prime] = [c,d,t_y] ・ [y]
[1 ]] [0,0,1 ]] [1]]
# In[ ]:
#アファイン変換を実装する
import cv2
import numpy as np
img=cv2.imread(r"C:\Users\omoiy\data/src/grapes.jpg")
h,w=img.shape[:2]
dx,dy=30,30 #基礎説明の t_x , t_y のこと
# In[ ]:
afn_mat=np.float32([[1,0,dx],[0,1,dy]])
img_afn=cv2.warpAffine(img,afn_mat,(w,h))
cv2.imshow("trans",img_afn)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
rot_mat=cv2.getRotationMatrix2D((w/2,h/2),40,1) #回転中心,回転角度deg,スケール
img_afn2=cv2.warpAffine(img,rot_mat,(w,h))
# In[ ]:
cv2.imshow("rotation",img_afn2)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
#透視変換
import cv2
import numpy as np
img=cv2.imread(r"C:\Users\omoiy\data/src/drive.jpg")
h,w=img.shape[:2]
cv2.imshow("img",img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
per1=np.float32([[100,500],[300,500],[300,100],[100,100]])
per2=np.float32([[100,500],[300,500],[280,200],[150,200]])#per1に対応する点群
psp_matrix=cv2.getPerspectiveTransform(per1,per2)#変換前,変換後
img_psp=cv2.warpPerspective(img,psp_matrix,(w,h))
cv2.imshow("psp",img_psp)
cv2.waitKey(0)
cv2.destroyAllWindows()
#畳み込み
周囲の情報から自分の情報を更新すること
1)フィルターを用意する
2)着目画素の周囲で 画素値xフィルター を行い足していく=畳み込み
3)全ての画素について畳み込みを行う
画素値(真ん中が着目画素=ノイズと考える)
[[5,5,4],
[4,0,5],
[5,4,5]]
平滑化フィルター
[[1/9 , 1/9 , 1/9],
[1/9 , 1/9 , 1/9]
[1/9 , 1/9 , 1/9]]
5*1/9 + 5*1/9 + 4*1/9 ....=4.11
→4 として現在値0を更新する
これでノイズが除去できたことになる
しかし、ぼけてしまう
# In[ ]:
#畳み込みを実装する
import cv2
import numpy as np
kernel=np.ones((3,3))/9.0 #フィルター
"""平滑化フィルター
array([[0.11111111, 0.11111111, 0.11111111],
[0.11111111, 0.11111111, 0.11111111],
[0.11111111, 0.11111111, 0.11111111]])
"""
img=cv2.imread(r"C:\Users\omoiy\data/src/Lena.jpg",0)
img_ke1=cv2.filter2D(img,-1,kernel)#ビット深度 負の値をしておくと良い,kernel
cv2.imshow("img_ke1",img_ke1)
cv2.imshow("img",img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
kernel2=np.zeros((3,3))
kernel2[0,0]=1
kernel2[1,0]=2
kernel2[2,0]=1
kernel2[0,2]=-1
kernel2[1,2]=-2
kernel2[2,2]=-1
"""横方向のエッジを検出するフィルター(sobelフィルターは縦方向)
array([[ 1., 0., -1.],
[ 2., 0., -2.],
[ 1., 0., -1.]])
"""
img_ke2=cv2.filter2D(img,-1,kernel2)
cv2.imshow("img",img)
cv2.imshow("img_ke1",img_ke1)
cv2.imshow("img_ke2",img_ke2)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
#画像の平滑化 ブラー処理
import cv2
img=cv2.imread(r"C:\Users\omoiy\data/src/buildings.jpg")
img_blur=cv2.blur(img,(3,3))
cv2.imshow("img",img)
cv2.imshow("img_blur",img_blur)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
#画像の平滑化 ガウシアン ブラー処理
import cv2
img=cv2.imread(r"C:\Users\omoiy\data/src/buildings.jpg")
img_ga=cv2.GaussianBlur(img,(9,9),2)#範囲が広いので、かなりボケボケ
cv2.imshow("img",img)
cv2.imshow("img_blur",img_blur)
cv2.imshow("img_ga",img_ga)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
#画像の平滑化 メディアンフィルター
import cv2
img=cv2.imread(r"C:\Users\omoiy\data/src/buildings.jpg")
img_me=cv2.medianBlur(img,5)#5x5の中の最頻値で全部を塗りつぶしてしまうので、かなりボケボケ
cv2.imshow("img",img)
cv2.imshow("img_blur",img_blur)
cv2.imshow("img_ga",img_ga)
cv2.imshow("img_me",img_me)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
#画像の平滑化 バイラテラルフィルタ
#輝度変化が激しいところはほっといて、緩やかな部分だけ平滑化をする
#エッジを残しながら、ノイズを除去することができる。
img=cv2.imread(r"C:\Users\omoiy\data/src/buildings.jpg")
img_bi=cv2.bilateralFilter(img,20,30,20)#窓の大きさ20,エッジを保存するためのシグマ,ガウシアンブラーでも渡したシグマ
cv2.imshow("img",img)
cv2.imshow("img_bi",img_bi)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
#画像の微分
①傾き=[f(x+dx)-f(x)]/dx
しかし、画像ではdx=constなので
②傾き=隣の画素値-自分の画素値
でよい
# In[ ]:
#エッジの検出 Sobel と Laplacian
import cv2
img=cv2.imread(r"C:\Users\omoiy\data/src/Lena.jpg",0)
cv2.imshow("img",img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
# Sobel フィルター
import cv2
img=cv2.imread(r"C:\Users\omoiy\data/src/Lena.jpg",0)
img_sobelx=cv2.Sobel(img,cv2.CV_32F,1,0,ksize=3) # ビット深度 1,0 x方向の微分
img_sobely=cv2.Sobel(img,cv2.CV_32F,0,1,ksize=3) # ビット深度 0,1 y方向の微分
cv2.imshow("img_sobelx",img_sobelx)
cv2.imshow("img_sobely",img_sobely)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
# Laplacian フィルター
#方向性がない。二次微分なので、細かいエッジも検出してしまう。
import cv2
img=cv2.imread(r"C:\Users\omoiy\data/src/Lena.jpg",0)
img_lap=cv2.Laplacian(img,cv2.CV_32F) # ビット深度
cv2.imshow("img_lap",img_lap)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
#ガウシアンの後にLaplacianする
#ぼかしてからエッジを検出するのでエッジが太く検出される
import cv2
img=cv2.imread(r"C:\Users\omoiy\data/src/Lena.jpg",0)
img_ga=cv2.GaussianBlur(img,(21,21),2)
img_lap=cv2.Laplacian(img,cv2.CV_32F)
img_ga_lap=cv2.Laplacian(img_ga,cv2.CV_32F)
cv2.imshow("img",img)
cv2.imshow("img_ga",img_ga)
cv2.imshow("img_lap",img_lap)
cv2.imshow("img_ga_lap",img_ga_lap)
cv2.waitKey(0)
cv2.destroyAllWindows()
#エッジの検出 Canny
#Laplacianのような輝度変化の細かいエッジ検出を抑制してくれる
①ガウシアンでぼかす(ノイズを除去する)
②Sobelフィルター x方向微分,y方向微分 を得る
2乗和(いわゆる強度のこと)を採用する
③極大点を探す=エッジ
除去:エッジではないノイズ(右肩上がり)、グラデーション(微分値が小さい)
④2段階の閾値処理でエッジを残す
1)閾値1以上の大きなエッジは残す
2)閾値1よりは小さいが、閾値2以上でエッジにつながっている場合は細かいエッジとして残す
# In[ ]:
#エッジの検出 Cannyを実装する
import cv2
img=cv2.imread(r"C:\Users\omoiy\data/src/Lena.jpg",0)
img_canny=cv2.Canny(img,10,180)#低い閾値,高い閾値
img_canny2=cv2.Canny(img,120,150)#低い閾値,高い閾値
cv2.imshow("img_canny",img_canny)
cv2.imshow("img_canny2",img_canny2)
cv2.waitKey(0)
cv2.destroyAllWindows()
#直線 円の検出
直線は2つのパラメータで決まる
y=ax+b が一般的だが
ρ:原点から直線までの距離
θ:原点を通る直線の法線とx軸とのなす角
とすると
y=-(cosθ/sinθ)x + (ρ/sinθ)
でもいい
でも、この方法はθが小さいとき yが発散してしまうので使えない。
べつの方法としベクトルを使ってみる
# In[ ]:
#直線の検出
import cv2
import numpy as np
img=cv2.imread(r"C:\Users\omoiy\data/src/road.jpg")
img_gray=cv2.imread(r"C:\Users\omoiy\data/src/road.jpg",0)
img_canny=cv2.Canny(img_gray,300,400)
cv2.imshow("img",img)
cv2.imshow("img_gray",img_gray)
cv2.imshow("img_canny",img_canny)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
lines=cv2.HoughLines(img_canny,1,np.pi/180,100)#1はρの刻み幅,θの刻み幅,集計表の閾値
# In[ ]:
for i in lines[:]:
rho = i[0][0]
theta = i[0][1]
a = np.cos(theta)
b = np.sin(theta)
x0 = rho*a
y0 = rho*b
x1 = int(x0+1000*(-b))
y1 = int(y0+1000*(a))
x2 = int(x0-1000*(-b))
y2 = int(x0-1000*(a))
cv2.line(img,(x1,y1),(x2,y2),(255,0,0),1)
cv2.imshow("img",img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
#円の検出
import cv2
img2=cv2.imread(r"C:\Users\omoiy\data/src/grapes.jpg")
img2_gray=cv2.imread(r"C:\Users\omoiy\data/src/grapes.jpg",0)
cv2.imshow("img",img2)
cv2.imshow("img_gray",img2_gray)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
get_ipython().set_next_input('circles=cv2.HoughCircles');get_ipython().run_line_magic('pinfo', 'cv2.HoughCircles')
# In[ ]:
circles=cv2.HoughCircles(img2_gray,cv2.HOUGH_GRADIENT,dp=1,minDist=1,param1=20,param2=35,minRadius=1,maxRadius=30)
# In[ ]:
for i in circles[0]:
cv2.circle(img2,(i[0],i[1]),i[2],(255,0,0),1)
cv2.imshow("img",img2)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
#モルフォロジー演算
モノの形についての演算(黒の中に白の図形があるとき)
収縮 erode :白が小さくなる。モノとモノを分離したいとき
膨張 dilate:白が大きくなる。モノとモノを連結したいとき
黒画像中に白いノイズがある場合
オープニング:収縮→膨張 白いノイズを小さくして、ノイズが消えてから、再びサイズを戻す。
クロージング:膨張→収縮 ノイズの大きさはそのまま。変化なし
# In[ ]:
import cv2
import numpy as np
img=cv2.imread(r"C:\Users\omoiy\data/src/floor.jpg",0)#グレースケール
#モルフォロジー演算をするためには2値化画像が必要になる
ret,img_th=cv2.threshold(img,110,255,cv2.THRESH_BINARY)
cv2.imshow("img",img)
cv2.imshow("img_th",img_th)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
kernel=np.ones((3,3),dtype=np.uint8) #着目画素の大きさを定義する
img_d=cv2.dilate(img_th,kernel)#膨張 着目画素に白画素があったら自分も白にする
img_e=cv2.erode(img_th,kernel)#収縮 着目画素に黒画素があったら自分も黒にする
#cv2.imshow("img",img)
#cv2.imshow("img_th",img_th)
cv2.imshow("img_dilate",img_d) #白が増える
cv2.imshow("img_erode",img_e) #黒が増える
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
#クロージング (膨張と比較する)
img_c=cv2.morphologyEx(img_th,cv2.MORPH_CLOSE,kernel)
cv2.imshow("img_dilate",img_d) #膨張のみ 白が増える
cv2.imshow("img_clising",img_c) #膨張→収縮 膨張で白飛びした穴を収縮で黒く埋めていく。
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
#インペイント
#画像の中の落書きを消す
#周囲の画像を使って消していく
import cv2
import numpy as np
img=cv2.imread(r"C:\Users\omoiy\data/src/Bus.jpg") #落書き入りの元画像
img_mask=cv2.imread(r"C:/Users/omoiy/data/src/Mask.jpg",0)#落書き部分を抜き出した画像 グレースケールで
cv2.imshow("img",img)
cv2.imshow("img_mask",img_mask)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
#img_mask グレースケールを二値化する
thresh=1 #閾値
ret,img_bi=cv2.threshold(img_mask,thresh,255,cv2.THRESH_BINARY)
cv2.imshow("img_binary",img_bi)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
#マスクした部分の周辺画像を拾って、マスク内に繰り返し何回も侵入させていく。
img_dst=cv2.inpaint(img,img_bi,3,cv2.INPAINT_NS)#ナビエストークス
cv2.imshow("img",img)
cv2.imshow("img_dst",img_dst) #うまく落書きが消えた
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
#特徴抽出
#Harirsのコーナー検出
情報量:フラット<エッジ<コーナー
フラット: n個の固有ベクトルの固有値に大小がない。ほぼ均一
エッジ : n個の固有ベクトルのうち1つの固有値が大きくなる
コーナー: n個の固有ベクトルのうち2つの固有値が大きくなる
#そのほか
ORB(早い), KAZE , AKAZEがお手軽で良い
#商用利用不可
SIFT:徴量128次元
SURF:SIFTを高速化
# In[ ]:
#オリジナルデータを読み込む
import cv2
import numpy as np
import copy
img=cv2.imread(r"C:\Users\omoiy\data/src/buildings.jpg")#オリジナル画像
img_gray=cv2.imread(r"C:\Users\omoiy\data/src/buildings.jpg",0)#グレースケール画像
cv2.imshow("img",img)
cv2.imshow("img_gray",img_gray)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
#harrisのコーナー検出をやってみる
import cv2
import numpy as np
import copy
img_harris=copy.deepcopy(img) #特徴点が元画像に上書きされてしまうので、imgのディープコピーをimg_harrisとしてとっておく
img_dst=cv2.cornerHarris(img_gray,2,3,0.04)#コーナー検出の範囲サイズ,ソーベルフィルターの大きさ,0.04~0.05がいいらしい
img_dst
"""2つの固有値を掛け算した=値が大きいと固有値が2つあるということ
array([[ 4.5360382e-12, 4.5360382e-12, 1.1455559e-12, ...,
3.5410072e-10, 1.2930142e-10, -5.0405020e-11],
[ 4.5360382e-12, 4.5360382e-12, 1.1455559e-12, ...,
3.5410072e-10, 1.2930142e-10, -5.0405020e-11],
[ 4.2316191e-09, 4.2316191e-09, 3.0776899e-09, ...,
-5.2589849e-10, 3.0621861e-10, 2.3705888e-09],
"""
#harrisデータimg_dstの内、5%以上であれば、特徴点とみなすことにする
img_harris[img_dst > 0.05*img_dst.max()]=[0,0,255]#BGR 特徴点を赤でマーキングする ,
cv2.imshow("img_harris",img_harris) #コーナーが検出されている
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
# kaze(ケイズ)のコーナー検出をやってみる
import cv2
import numpy as np
import copy
img_kaze=copy.deepcopy(img) #特徴点が元画像に上書きされてしまうので、imgのディープコピーをとっておく
kaze=cv2.KAZE_create() #特徴抽出器のインスタンスkazeを生成しておく
kp1=kaze.detect(img,None) #特徴点を探してkp1に代入する
img_kaze=cv2.drawKeypoints(img_kaze,kp1,None)#特徴点kp1を描く
cv2.imshow("img_kaze",img_kaze)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
# accerate kaze(アクセレイト ケイズ)のコーナー検出をやってみる
import cv2
import numpy as np
import copy
img_akaze=copy.deepcopy(img) #特徴点が元画像に上書きされてしまうので、imgのディープコピーをとっておく
akaze=cv2.AKAZE_create() #特徴抽出器のインスタンスkazeを生成しておく
kp1=akaze.detect(img,None) #特徴点を探してkp1に代入する
img_akaze=cv2.drawKeypoints(img_akaze,kp1,None)#特徴点kp1を描く
cv2.imshow("img_akaze",img_akaze)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
# orb(オーブ)のコーナー検出をやってみる
import cv2
import numpy as np
import copy
img_orb=copy.deepcopy(img)
orb=cv2.ORB_create()#インスタンスを生成する
kp2=orb.detect(img_orb)
img_orb=cv2.drawKeypoints(img_orb,kp2,None)
cv2.imshow("img_orb",img_orb)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[ ]:
#コーナー検出を比較する
import cv2
import numpy as np
import copy
cv2.imshow("img_harris",img_harris)
cv2.imshow("img_kaze",img_kaze)
cv2.imshow("img_akaze",img_akaze)
cv2.imshow("img_orb",img_orb)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[4]:
#顏検出
import cv2
#ハールファイル 特徴検出器:すでにopencvに入っている
HAAR_FILE="C:/Users/omoiy/Anaconda3/pkgs/opencv3-3.1.0-py35_0/Library/etc/haarcascades/haarcascade_frontalface_default.xml"
cascade=cv2.CascadeClassifier(HAAR_FILE)#分類検出器のインスタンスを作成する
img=cv2.imread(r"C:/Users/omoiy/data/src/Solvay_conference_1927.jpg")
img_gray=cv2.imread(r"C:/Users/omoiy/data/src/Solvay_conference_1927.jpg",0)
cv2.imshow("img",img)
cv2.imshow("img_gray",img_gray)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[8]:
face=cascade.detectMultiScale(img_gray)
face
""" 座標x,座標y,幅w,高さh
array([[1061, 877, 37, 37],
[ 115, 570, 53, 53],
[ 421, 568, 60, 60],
"""
for x,y,w,h in face:
cv2.rectangle(img,(x,y),(x+w,y+h),(0,0,255),1) #顔を四角で囲む
cv2.imshow("img",img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[21]:
#ブロブの検出
import cv2 ,copy
img=cv2.imread(r"C:\Users\omoiy\data/src/Blob.png")
img_gray=cv2.imread(r"C:\Users\omoiy\data/src/Blob.png",0)
cv2.imshow("img",img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[23]:
ret,img_bi=cv2.threshold(img_gray,100,255,cv2.THRESH_BINARY) #グレースケールを二値化
cv2.imshow("img_bi",img_bi)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[34]:
nLabels,labelImage,stats,centroids=cv2.connectedComponentsWithStats(img_bi) #ブロブの検出
nLabels # 5 :ブロブが5個検出された 背景も1個として検出される
labelImage
"""ラベルのIDが ふられる
array([[0, 0, 0, ..., 0, 0, 0],←背景
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
"""
stats
"""あるブロブの最小のx 最小のy 幅w 高さh 面積s
array([[ 0, 0, 1672, 1078, 1578760],←背景
[ 818, 88, 365, 311, 56799],
[ 256, 143, 150, 150, 17656],
[ 163, 471, 336, 363, 89208],
[ 1048, 574, 302, 288, 59993]], dtype=int32)
"""
img_blob=copy.deepcopy(img)
h,w=img_gray.shape
color=[[255,0,255],[0,255,0],[0,0,255],[255,255,0]]#塗る色のリストが必要
for y in range(h):
for x in range(w):
if labelImage[y,x]>0:#背景のlabel Imageは0なので、それ以外の時、色を塗る
img_blob[y,x]=color[labelImage[y,x]-1]
for i in range(1,nLabels):#背景(0)は除く
xc=int(centroids[i][0])
yc=int(centroids[i][1])
font=cv2.FONT_HERSHEY_COMPLEX
scale=1
color=(255,255,255)
cv2.putText(img_blob,str(stats[i][-1]),(xc,yc),font,scale,color)
# In[35]:
cv2.imshow("img_blob",img_blob)
cv2.waitKey(0)
cv2.destroyAllWindows()
# In[36]:
#輪郭検出
import cv2
img=cv2.imread(r"C:\Users\omoiy\data/src/Blob.png")
img_gray=cv2.imread(r"C:\Users\omoiy\data/src/Blob.png",0) #グレースケール
ret,img_bi=cv2.threshold(img_gray,100,255,cv2.THRESH_BINARY) #二値化
# In[40]:
img_con,contours,hierarchy=cv2.findContours(img_bi,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)#3角形の中の3角形まで検出する,最低限の輪郭を検出
img_contour=cv2.drawContours(img,contours,-1,(255,0,0),5)#全ての輪郭を描く(-1) , 色 , 太さ
# In[41]:
cv2.imshow("img",img)
cv2.imshow("img_gray",img_gray)
cv2.imshow("img_contour",img_contour)
cv2.waitKey(0)
cv2.destroyAllWindows()