4
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

pythonで一から画像処理 (3)エッジ検出、モルフォロジー変換

Posted at

基本となる画像処理を一から勉強していくシリーズ (3)。

OpenCV-Pythonチュートリアルを参考に、
画像認識本 https://www.amazon.co.jp/dp/4061529129/
でやっている処理の理解を進める方針です。

目次

  1. 環境
  2. Sobel、Laplacianフィルタ
  3. Cannyエッジ検出
  4. モルフォロジー変換
  5. 輪郭抽出トライ

1. 環境

Python 3.7.0
OpenCV 4.1.0
Jupyter Notebook

2. Sobel、Laplacianフィルタ

Sobelフィルタは1次微分によるエッジの検出で、注目画素を重要視したもの。
Laplacianフィルタは2次微分によるエッジの検出。

Sobel_LaplacianFilter.py
img = cv2.imread('brabra/1.jpg',0)

# Laplacianフィルタ
laplacian = cv2.Laplacian(img,cv2.CV_64F)
# Sobelフィルタx方向
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=15)
# Sobelフィルタy方向
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=15)

plt.subplot(2,2,1),plt.imshow(img,cmap = 'gray')
plt.title('Original'), plt.xticks([]), plt.yticks([])
plt.subplot(2,2,2),plt.imshow(laplacian,cmap = 'gray')
plt.title('Laplacian'), plt.xticks([]), plt.yticks([])
plt.subplot(2,2,3),plt.imshow(sobelx,cmap = 'gray')
plt.title('Sobel X'), plt.xticks([]), plt.yticks([])
plt.subplot(2,2,4),plt.imshow(sobely,cmap = 'gray')
plt.title('Sobel Y'), plt.xticks([]), plt.yticks([])

plt.show()

SobelLaplacian.png

Sobelフィルタではx,y方向のエッジに反応している。

3. Cannyエッジ検出

・ガウシアンフィルタにより平滑化後(5x5のカーネル)、
・Sobelフィルタによってx,y方向の1次微分(Gx,Gy)を取得して
 √(Gx^2 + Gy^2)のgradientを得る。勾配方向も(Gx,Gy)から得ます。
・次に、その注目画素の勾配方向の両隣の画素と比較し、
 注目画素が極大値でなければエッジとしない処理(細線化)を行う。
・次に、minVal,maxValを設定し、minValより小さければ除去、
 maxValより大きければ残す、minVal~maxValでは隣がmaxValより大きければ
 残す処理を行う。これにより輪郭を繋げることと、誤検出を取り除くそう。

Canny.py
img = cv2.imread('brabra/1.jpg',0)
minVal = 50
maxVal = 250
SobelSize = 10

edges = cv2.Canny(img,minVal,maxVal,SobelSize)

plt.subplot(251),plt.imshow(img,cmap = 'gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(252),plt.imshow(edges,cmap = 'gray')
plt.title('Edge Image'), plt.xticks([]), plt.yticks([])

plt.show()

CAnny.png

輪郭はうまく繋がってはいないが、形状は認識できている感じ。

4. モルフォロジー変換

モルフォロジー=形態。全体的に太くしたり細くしたりする。
・Erosion(収縮)
・Dilation(膨張)
・Opening(収縮⇒膨張 小さい点のようなノイズ除去)
・Closing(膨張⇒収縮 小さい箇所の穴埋め)
・勾配(膨張-収縮で輪郭を得る)
・トップハット(入力-Opening)
・ブラックハット(入力-Closing)

演習には2値化されたパンダを使用。

Mol.py
img = cv2.imread('brabra/6.jpg',0)
# 大津の2値化されたパンダ
abc,two = cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
# 白黒反転(白に適用されるため)
two = cv2.bitwise_not(two)

# Erositon
kernel = np.ones((35,35),np.uint8)
erosion = cv2.erode(two,kernel,iterations = 1)
# Dilation
kernel = np.ones((35,35),np.uint8)
dilation = cv2.dilate(two,kernel,iterations = 1)
# Opening
kernel = np.ones((35,35),np.uint8)
opening = cv2.morphologyEx(two, cv2.MORPH_OPEN, kernel)
# Closing
kernel = np.ones((35,35),np.uint8)
closing = cv2.morphologyEx(two, cv2.MORPH_CLOSE, kernel)
# Gradient
kernel = np.ones((35,35),np.uint8)
gradient = cv2.morphologyEx(two, cv2.MORPH_GRADIENT, kernel)
# Tophat
kernel = np.ones((35,35),np.uint8)
tophat = cv2.morphologyEx(two, cv2.MORPH_TOPHAT, kernel)
# Blackhat
kernel = np.ones((35,35),np.uint8)
blackhat = cv2.morphologyEx(two, cv2.MORPH_BLACKHAT, kernel)

plt.subplot(251),plt.imshow(img,cmap = 'gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(252),plt.imshow(two,cmap = 'gray')
plt.title('2value Image'), plt.xticks([]), plt.yticks([])
plt.subplot(253),plt.imshow(erosion,cmap = 'gray')
plt.title('Erosion Image'), plt.xticks([]), plt.yticks([])
plt.subplot(254),plt.imshow(dilation,cmap = 'gray')
plt.title('Dilation Image'), plt.xticks([]), plt.yticks([])
plt.subplot(255),plt.imshow(opening,cmap = 'gray')
plt.title('Opening Image'), plt.xticks([]), plt.yticks([])
plt.subplot(256),plt.imshow(closing,cmap = 'gray')
plt.title('Closing Image'), plt.xticks([]), plt.yticks([])
plt.subplot(257),plt.imshow(gradient,cmap = 'gray')
plt.title('Gradient Image'), plt.xticks([]), plt.yticks([])
plt.subplot(258),plt.imshow(tophat,cmap = 'gray')
plt.title('Tophat Image'), plt.xticks([]), plt.yticks([])
plt.subplot(259),plt.imshow(blackhat,cmap = 'gray')
plt.title('Blackhat Image'), plt.xticks([]), plt.yticks([])

plt.show()

mol.png

5. 輪郭抽出トライ

Cannyでエッジ検出した後、Closingで中空部をくっつけてガイコツの領域を抽出してみた。

Rinkaku.py
img = cv2.imread('brabra/1.jpg',0)
edges = cv2.Canny(img,50,250,10)

# Closing
kernel = np.ones((5,5),np.uint8)
closing = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel)
kernel = np.ones((35,35),np.uint8)
closing2 = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel)
kernel = np.ones((135,135),np.uint8)
closing3 = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel)

plt.subplot(251),plt.imshow(img,cmap = 'gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(252),plt.imshow(edges,cmap = 'gray')
plt.title('Edge Image'), plt.xticks([]), plt.yticks([])
plt.subplot(253),plt.imshow(closing,cmap = 'gray')
plt.title('Closing Image'), plt.xticks([]), plt.yticks([])
plt.subplot(254),plt.imshow(closing2,cmap = 'gray')
plt.title('Closing2 Image'), plt.xticks([]), plt.yticks([])
plt.subplot(255),plt.imshow(closing3,cmap = 'gray')
plt.title('Closing3 Image'), plt.xticks([]), plt.yticks([])

plt.show()

rinkaku.png

まとめ

エッジ検出とモルフォロジー変換について理解を深めた。

参考文献

4
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?