OpenCVで二値化された領域の輪郭座標は、findContours関数を使えば取得することができます。
このときの戻り値である輪郭情報(contours)をcontourArea関数へ渡し面積を求めます。
ただし、求まる面積は、あくまでも輪郭線の内側の面積(画素数ではない)となります。
(下図の例では、面積は 35 となります。)
さらに、白の領域の内側に黒の領域があっても、考慮されません。
構文
contourArea(contour[, oriented]) ->retval
contour | 輪郭座標 |
oriented | 輪郭の向きを考慮するか(True)、しないか(False)を指定します。 初期値)False Trueのとき、輪郭座標の向きが時計周りのときは正、反時計周りのときは負となります。 Falseのとき、向きに関係なく、常に正となります。 下図参照 |
(戻り値)retval | 輪郭の内側の面積 |
サンプルプログラム
import cv2
import numpy as np
# 画像データ
img = np.array(
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 255, 255, 255, 255, 255, 255, 255, 255, 0],
[0, 255, 255, 255, 255, 255, 255, 255, 255, 0],
[0, 255, 255, 0, 0, 0, 0, 255, 255, 0],
[0, 255, 255, 0, 0, 0, 0, 255, 255, 0],
[0, 255, 255, 255, 255, 255, 255, 255, 255, 0],
[0, 255, 255, 255, 255, 255, 255, 255, 255, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
],
dtype = np.uint8
)
# 輪郭情報の取得
contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
# 画像表示用に入力画像をカラーデータに変換する
img_disp = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
# 輪郭ごとの処理
for i, contour in enumerate(contours):
# 輪郭の面積を求める
area = cv2.contourArea(contour, True)
print(f"面積[{i}]: {area}")
# 輪郭座標
for point in contour:
print(point[0])
cv2.namedWindow("Image", cv2.WINDOW_NORMAL)
cv2.imshow("Image", img_disp)
# キー入力待ち(ここで画像が表示される)
cv2.waitKey()
実行結果
このサンプルでは、画像データはnumpyの配列で疑似的に作りましたが、画像にすると下図の用な画像に対して輪郭処理をしています。
この画像では、白の外側の輪郭の面積は 35 となります。
白の内側の輪郭の面積は 13 となります。
内側の輪郭の座標は、黒の画素の上下左右方向(4近傍)に隣接している白の画素の座標となります。