つれづれなる備忘録

日々の発見をあるがままに綴る

OpenCVの使い方25 ~ 輪郭抽出2

今回はOpenCVを用いて画像の輪郭を抽出する際の検出手法の違いについて紹介したい。

前回紹介したように輪郭検出方法は次の4種類:cv2.RETR_EXTERNAL, cv2.RETR_LIST, cv2.RETR_CCOMP, cv2.RETR_TREEがあり、前回はcv2.RETR_TREEを使用した。

atatat.hatenablog.com

今回は他の輪郭検出手法を用いて輪郭抽出したときの結果の違いを調べる。

画像はOpenCVのモノクロロゴをグレーで読み込むところまでは前回と同じ。

ret,thresh = cv2.threshold(gray,127,255,0)
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
cnt_img = np.zeros_like(gray, dtype=np.uint8) 
cnt_img_tree = cv2.drawContours(cnt_img, contours, -1, 255, 2)

contours_ex, hierarchy = cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cnt_img = np.zeros_like(gray, dtype=np.uint8) 
cnt_img_ex = cv2.drawContours(cnt_img, contours, -1, 255, 2)

contours_list, hierarchy = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
cnt_img = np.zeros_like(gray, dtype=np.uint8) 
cnt_img_list = cv2.drawContours(cnt_img, contours, -1, 255, 2)

contours_comp, hierarchy = cv2.findContours(thresh,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_SIMPLE)
cnt_img = np.zeros_like(gray, dtype=np.uint8) 
cnt_img_comp = cv2.drawContours(cnt_img, contours, -1, 255, 2)

plt.figure(figsize=(15,25))
plt.subplot(1,4,1)
plt.imshow(cnt_img_tree,cmap='gray')
plt.title('RETR_TREE')
plt.subplot(1,4,2)
plt.imshow(cnt_img_ex,cmap='gray')
plt.title('RETR_EXTERNAL')
plt.subplot(1,4,3)
plt.imshow(cnt_img_list,cmap='gray')
plt.title('RETR_LIST')
plt.subplot(1,4,4)
plt.imshow(cnt_img_comp,cmap='gray')
plt.title('RETR_CCOMP')

"輪郭検出比較"
輪郭検出比較

RETR_EXTERNALは外側の輪郭のみを抽出するためO,P,eの内側が輪郭として抽出されない。RETR_EXTERNAL以外はすべて同じ結果になる。

RETR_EXERNALで抽出した輪郭を輪郭リストの番号で示すと以下のようになる。

n=len(contours_ex)
plt.figure(figsize=(12,12))
for i in np.arange(n):
  cnt_img = np.zeros_like(thresh, dtype=np.uint8) 
  cnt_img = cv2.drawContours(cnt_img, contours_ex,i, 255, 2)
  plt.subplot(3,4,i+1)
  plt.imshow(cnt_img,cmap='gray')
  plt.title('Cont Num'+str(i))

"RETR_EXTERNALの各輪郭"
RETR_EXTERNALの各輪郭

cv2.RETR_LIST, cv2.RETR_CCOMP, cv2.RETR_TREEは輪郭抽出については差がなかったが、内側の輪郭の階層構成について差がある。

www.learning-nao.com

抽出した輪郭をさらに処理するときに違いを理解しておくことが必要になる。