OpenCV

【OpenCV-Python】円形度

円形度とは、図形の面積と周囲長の関係から、円らしさの値を求めます。

円形度の詳細は以下のページを参照ください。

円形度
輪郭追跡を行うと周囲長を求めることができますが、この周囲長を用いた代表的な特徴量の円形度を紹介します。 円形度とは円らしさを表す値で値が1となる時、もっとも円に近くなります。 定義は面積(画素数)をS、周囲長をLとすると、 ...

 

OpenCV的には、図形の面積はcontourArea()関数で、周囲長はarcLength()関数で求める事ができるので、これを使って円形度を求めます。

 

今回は、下図のように手書きで書いた図形の中から円らしい部分を見つけたいと思います。

OpenCV-Python 円形度

 

サンプルプログラム

contourArea()関数と、周囲長はarcLength()関数を使って円らしい部分を抽出するサンプルプログラムを作成しました。
円形度を求める部分は関数(circularity)にしてあります。

import cv2
import numpy as np

def circularity(contour):
    '''
    円形度を求める

    Parameters
    ----------
    contour : ndarray
        輪郭の(x,y)座標の配列

    Returns
    -------
        円形度

    '''
    # 面積
    area = cv2.contourArea(contour)
    # 周囲長
    length = cv2.arcLength(contour, True)

    # 円形度を返す
    return 4*np.pi*area/length/length

# 8ビット1チャンネルのグレースケールとして画像を読み込む
img = cv2.imread("image.jpg", cv2.IMREAD_GRAYSCALE) 

# 白黒反転して二値化
ret, img = cv2.threshold(img, 128, 255, cv2.THRESH_BINARY_INV)

# 一番外側の輪郭のみを取得
contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE ) 

# 画像表示用に入力画像をカラーデータに変換する
img_disp = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)

# 全ての輪郭を描画
cv2.drawContours(img_disp, contours, -1, (0, 0, 255), 2)

# 輪郭の点の描画
for contour in contours:
    # 円形度の計算
    val = circularity(contour)
    # 輪郭の矩形領域
    x,y,w,h = cv2.boundingRect(contour)
    # 円形度の描画
    cv2.putText(img_disp, f"{val:.3f}", (x, y-10), cv2.FONT_HERSHEY_PLAIN, 2, (0, 255, 0), 1, cv2.LINE_AA)
    # 円らしい領域(円形度が0.85以上)を囲う
    if val > 0.85:
        cv2.rectangle(img_disp,(x-5,y-5),(x+w+5,y+h+5),(255,0,0),2) # 少し外側を囲う

cv2.imshow("Image", img_disp)

# キー入力待ち(ここで画像が表示される)
cv2.waitKey()

実行結果

OpenCV-Python 円形度

 

実行結果を見ると、だいたい円っぽい部分は円形度を使うと抽出することが出来ますが、真円度的な円の正確さを求めるのには、円形度は不向きな感じがします。

 

関連記事

【OpenCV-Python】findContoursによる輪郭検出
OpenCV(Python)で二値化された画像中の白の部分または黒の部分の輪郭のデータを取得するにはfindContours()関数を用います。 findContours()関数で取得できる情報は、輪郭を構成している点の座標群と輪郭の...
【OpenCV-Python】輪郭(contour)の面積(contourArea)
OpenCVで二値化された領域の輪郭座標は、findContours関数を使えば取得することができます。 このときの戻り値である輪郭情報(contours)をcontourArea関数へ渡し面積を求めます。 ただし、求まる面積は...
【OpenCV-Python】輪郭の周囲長(arcLength)
findContours()関数などで取得した輪郭の座標から輪郭の長さを求めるにはarcLength()関数を用います。 構文 arcLength(curve, closed) ->retval curve ...

コメント

タイトルとURLをコピーしました