OpenCVの使い方27 ~ 輪郭抽出4
今回は前回のOpenCVを用いた輪郭近似の続きについて紹介したい。
1. 円・楕円近似
円:最小外接円で近似する場合は、cv2.minEnclosingCircle
により中心座標と半径を求める。描画は円を描画するcv2.circle
を用いる。
(x,y),radius = cv2.minEnclosingCircle(cnt) center = (int(x),int(y)) radius = int(radius) cnt_img = np.zeros_like(gray, dtype=np.uint8) cnt_img = cv2.circle(cnt_img,center,radius,255,2) plt.imshow(cnt_img+cnt_img_tree,cmap='gray')
C字が丸いので、円に対してかなりフィッティングできていることがわかる。
正円ではなく楕円で近似する場合はcv2.fitEllipse
を用いる。楕円中心、長軸・短軸長さ、回転角が出力されるが、cv2.ellipse
で描画することができる。
ellipse = cv2.fitEllipse(cnt) cnt_img = np.zeros_like(gray, dtype=np.uint8) cnt_img = cv2.ellipse(cnt_img,ellipse,255,2) plt.imshow(cnt_img+cnt_img_tree,cmap='gray')
C字のくぼみの関係で若干横方向に長い楕円として近似される。
2. 三角形近似
三角形で近似する場合は、cv2.minEnclosingTriangle
を用いる。三角形の座標が出力されるので、cv2.polylines
で多角形を描画する。
retval, triangle = cv2.minEnclosingTriangle(cnt) cnt_img = np.zeros_like(gray, dtype=np.uint8) tr = triangle.astype(np.int32).reshape((-1, 2)) cnt_img=cv2.polylines(cnt_img, [tr], True, 255, 2) plt.imshow(cnt_img+cnt_img_tree,cmap='gray')
三角形の頂点が収まっていないので、三角形の座標値を調べてみる。
tr >array([[ 90, 146], [285, 146], [181, -10]], dtype=int32)
3点目のy座標値が負になっていて、画像の範囲外に近似点があることをあらわしている。
3. 直線近似
最後に直線で近似する場合を紹介する。直線近似はデータ処理の直線近似を画像にあてはめたものでcv2.fitLine
を用いることで、傾き(vy/vx)・直線が通過する点(x,y)を用いてcv2.line
で直線を描画する。
rows,cols = gray.shape[:2] [vx,vy,x,y] = cv2.fitLine(cnt, cv2.DIST_L2,0,0.01,0.01) lefty = int((-x*vy/vx) + y) righty = int(((cols-x)*vy/vx)+y) cnt_img = np.zeros_like(gray, dtype=np.uint8) cnt_img = cv2.line(cnt_img,(cols-1,righty),(0,lefty),255,2) plt.imshow(cnt_img+cnt_img_tree,cmap='gray')
3. まとめ
今回は輪郭の近似としてとして円、楕円、三角形、直線について紹介した。