Python OpenCV3でSobelメソッドを使ってエッジ(輪郭)抽出

Facebook にシェア
Pocket
LINEで送る
このエントリーを Google ブックマーク に追加

OpenCV3では微分オペレータでのエッジ検出のメソッドが用意されていない。
(というよりもあまり必要ない)
そのため、Sobelメソッドでのエッジ検出を行う。

[amazonjs asin=”4061538225″ locale=”JP” title=”OpenCVによる画像処理入門 (KS情報科学専門書)”]

 

前提

ディレクトリ構成などはこことかこことか。

 

元画像

縦横の線がはっきりしているとわかりやすいため、蔵の画像(kura.jpg)を使う。

kura

 

Sobelメソッドの使い方

Sobelメソッドの使い方は次の通り。

[python title=”Sobelメソッドの使い方”] cv2.Sobel(img_src, 出力画像のbit深度, xに関する微分の次数, yに関する微分の次数)
[/python]

出力画像のbit深度は以下の中から選択できる。

cv2.CV_16S    cv2.CV_16UC2  cv2.CV_32FC4  cv2.CV_64FC1  cv2.CV_8SC3
cv2.CV_16SC1  cv2.CV_16UC3  cv2.CV_32S    cv2.CV_64FC2  cv2.CV_8SC4
cv2.CV_16SC2  cv2.CV_16UC4  cv2.CV_32SC1  cv2.CV_64FC3  cv2.CV_8U
cv2.CV_16SC3  cv2.CV_32F    cv2.CV_32SC2  cv2.CV_64FC4  cv2.CV_8UC1
cv2.CV_16SC4  cv2.CV_32FC1  cv2.CV_32SC3  cv2.CV_8S     cv2.CV_8UC2
cv2.CV_16U    cv2.CV_32FC2  cv2.CV_32SC4  cv2.CV_8SC1   cv2.CV_8UC3
cv2.CV_16UC1  cv2.CV_32FC3  cv2.CV_64F    cv2.CV_8SC2   cv2.CV_8UC4

xに関する微分の次数, yに関する微分の次数は例えば、(1, 0)だと横方向のエッジ検出、(0, 1)だと縦方向のエッジ検出、(1, 1)だと右斜め45°のエッジ検出となる。

 

横方向のエッジ検出

横方向のエッジ検出をしてみる。
sourceディレクトリにsobel.pyを作成する。

[python title=”sobel.pyの内容”] # -*- coding: utf-8 -*-

import cv2
import numpy as np

if __name__ == ‘__main__’:

# 画像の読み込み
img_src = cv2.imread("./image/kura.jpg", 1)

# 横方向のSobelオペレータのエッジ検出
img_tmp = cv2.Sobel(img_src, cv2.CV_32F, 1, 0)

img_sobel = cv2.convertScaleAbs(img_tmp)

# 表示
cv2.imshow("Show SOBEL Image", img_sobel)
cv2.waitKey(0)
cv2.destroyAllWindows()

[/python]

実行してみる。

[shell] (opencv_python)$ python sobel.py
[/shell]

スクリーンショット 2015-07-04 23.15.14

 

元画像と比較すると、横方向のSobelメソッドでのエッジ検出を行うと、縦のラインのエッジが検出できることがわかる。ここで12行目のSobelメソッドのところを

[python] img_tmp = cv2.Sobel(img_src, cv2.CV_32F, 0, 1)
[/python]

に変えると、今度は縦方向のエッジ検出をし、横のラインを抽出できる。

スクリーンショット 2015-07-04 23.15.56

 

x,yの次数を変えれば色々な角度の方向のエッジを抽出できる。