Contents
はじめに
こんにちは、でめきんです。
今回はopenCVを使って輪郭を識別することをやってみたいと思います。
今回の輪郭抽出はDICOM画像ではなく、以下のjpg画像を用います。
輪郭抽出の手順
- 画像の読み込み
- 画像の2値化
- 閾値設定を行う
- 領域を抽出
- 領域を重ね合わせ
- 画像表示
画像の読み込み
openCVの画像読み込みは
img = cv2.imread(“img.JPG”)
画像の2値化 cv2.cvtColor
領域抽出をする際に、色情報があると領域の境が曖昧になってしまいますのでグレイスケールに変換します。
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
閾値設定 cv2.threshold
閾値設定をして画像の領域の調整します。
ret, thresh = cv2.threshold(img_gray,127,255,cv2.THRESH_BINARY)
閾値設定とは、第2引数(上のコードでは’127’)よりも大きい値が第3引数の値(255)に第2引数よりも小さい数字は0に置き換わります。
領域を抽出 cv2.findContours
いよいよ本題に入っていきます。
領域の抽出は一度画像上のすべての領域を検出します。その後、表示の際に大きさであったり、輪郭線の長さであったりで抽出条件を指定して表示します。
(私は、初めから抽出条件を指定して領域を探し出すものと勘違いしていたので理解するのに苦労しました・・・・そんな人はいないかな・・・・)
まずは、領域抽出
ret, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
第1引数は画像を指し、第2引数に抽出方法、第3引数として近似手法を指定します。
抽出方法
cv2.RETR_EXTERNAL | 輪郭のうち、最も外側のみ抽出 | |
cv2.RETR_LIST | 全ての輪郭を抽出 | |
cv2.RETR_CCOMP | 全ての輪郭を2レベルの階層に分けて出力 | |
cv2.RETR_TREE | 抽出した内側の輪郭も抽出 |
近似方法
cv2.CHAIN_APPROX_NON | 輪郭上の全点をの情報を保持 |
cv2.CHAIN_APPROX_SIMPLE | 輪郭を圧縮し情報を保持 |
領域を重ね合わせ cv2.drawContours
領域の抽出が済みましたら、今度は元画像との重ね合わせとなります。
cv2.drawContours
cv2.drawContours(img, contours, 3, color, 2)
第1引数 | 重ね合わせる画像 |
第2引数 | 領域抽出したリスト |
第3引数 | リストの中の何番目を表示するか (すべてを表示する場合は-1を指定します。) |
第4引数 | 線のカラー |
第5引数 | 線の太さ |
画像表示
cv2.imshow(‘conturing’,img)
と忘れてはいけない
cv2.waitKey(0)
cv2.destroyAllWindows()
コード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import cv2 img = cv2.imread(“img.JPG”) img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(img_gray,127,255,cv2.THRESH_BINARY) ret, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) color = (255, 255, 0) for contour in contours: # 境界の描画 ( img データに contours データをマージ ) cv2.drawContours(img, contours, –1, color, 2) cv2.imshow(‘conturing’,img) cv2.waitKey(0) cv2.destroyAllWindows() |
最後に
いかがでしたか?
今回は概要となりますが、今後機会があれば、もう少し詳しく記事にしていきたいと思います。
お疲れ様でした。