領域(輪郭)の属性情報¶
ここでは物体の特徴を表す時によく使われる輪郭の属性情報(ソリディティ, 等価直径, マスク画像,平均値など)について学びます. より詳細な情報については Matlab regionprops documentation を参照してください.
(NB : 重心,面積,周囲長なども輪郭の属性情報ですが,前のチュートリアルで既に扱いました)
1. アスペクト比¶
アスペクト比(Aspect Ratio)は物体を囲む外接長方形の縦幅(height)に対する横幅(width)の比です.
x,y,w,h = cv2.boundingRect(cnt)
aspect_ratio = float(w)/h
2. Extent¶
Extentは外接矩形の面積に対する輪郭が占める面積の比です.
area = cv2.contourArea(cnt)
x,y,w,h = cv2.boundingRect(cnt)
rect_area = w*h
extent = float(area)/rect_area
3. Solidity¶
Solidityは凸包(領域を囲む最小の外接多角形)の面積に対する輪郭の面積の比です.
area = cv2.contourArea(cnt)
hull = cv2.convexHull(cnt)
hull_area = cv2.contourArea(hull)
solidity = float(area)/hull_area
4. 等価直径¶
等価直径(Equivalent Diameter)は輪郭の面積と同じ面積を持つ円の直径です.
area = cv2.contourArea(cnt)
equi_diameter = np.sqrt(4*area/np.pi)
5. 傾き¶
傾き(Orientation)は物体が向いている方向を意味します.以下の計算方法で長径(MA: Major Axis)と短径(ma: Minor Axis)も同時に計算できます.
(x,y),(MA,ma),angle = cv2.fitEllipse(cnt)
6. マスクと画素点¶
マスク(Mask)とは物体が占める領域とそれ以外の領域を区別するためのもので,画素点(Pixel Point)とはマスクを構成する全ての点を指します.物体を構成する全ての点の情報が必要になる時は,以下のようにします:
mask = np.zeros(imgray.shape,np.uint8)
cv2.drawContours(mask,[cnt],0,255,-1)
pixelpoints = np.transpose(np.nonzero(mask))
#pixelpoints = cv2.findNonZero(mask)
3行目と4行目はそれぞれNumpyの関数とOpenCVの関数を使っていますが,全く同じ処理です.結果も同じ結果が得られますが,若干の違いがあります.Numpyは座標を (row, column) の形式で出力するのに対して,OpenCVは (x,y) の形式で出力します.そのため,それぞれの結果は置き換えられます.ここで row = x と column = y という関係になります.
7. 最大値,最小値とその位置¶
画像中(対象領域中)の画素値の最大値,最小値及び対応する画素の位置を調べるには以下のようにします.
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(imgray,mask = mask)
8. 平均色と平均値¶
物体の平均色の計算もできます.グレースケール画像であれば平均値になります.マスクを指定すると,注目領域を対象とした計算をします.
mean_val = cv2.mean(im,mask = mask)
9. 端点¶
端点(Extreme Points)は物体の上橋(topmost),下端(bottommost),右端(rightmost),左端(leftmost)の点を意味します.
leftmost = tuple(cnt[cnt[:,:,0].argmin()][0])
rightmost = tuple(cnt[cnt[:,:,0].argmax()][0])
topmost = tuple(cnt[cnt[:,:,1].argmin()][0])
bottommost = tuple(cnt[cnt[:,:,1].argmax()][0])
例えばインドの地図に対して端点を求めると,以下のようになります :
補足資料¶
課題¶
- このチュートリアルで紹介した以外にも,MatLabの領域に関する属性情報はまだまだあるので,自分で実装してみてください.