画像処理において、物体の輪郭を検出し、その輪郭に基づいて形状をフィッティングするのはよく行われる手法です。本記事では、PythonとOpenCVを使用して線分フィッティングを行う方法について詳しく説明します。
1. 必要なライブラリのインポート
まず、必要なライブラリをインポートします。OpenCVとNumPyを使います。OpenCVは画像処理、NumPyは配列操作に役立ちます。
import cv2
import numpy as np
2. 画像の読み込みとグレースケール変換
次に、解析対象となる画像を読み込み、グレースケールに変換します。グレースケール化することで、画像の情報量を減らし、エッジ検出を行いやすくします。
# 入力画像の読み込み
image = cv2.imread("input.jpg")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
ここでinput.jpgは解析対象の画像ファイルのパスです。
3. エッジ検出
エッジ検出にはCanny法を使います。Cannyエッジ検出は、画像内のエッジ(急激な輝度の変化部分)を抽出する手法です。OpenCVのcv2.Canny関数を使ってエッジを抽出します。
# エッジ検出 (Canny)
edges = cv2.Canny(gray, 100, 200)
ここで、100と200はCannyエッジ検出の閾値です。
4. 輪郭検出
次に、エッジから輪郭を検出します。輪郭検出は、画像中の連続したエッジを集めて輪郭として扱う処理です。cv2.findContours関数を使用し、抽出したエッジから輪郭を検出します。
# 輪郭の検出
contours, _ = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cv2.RETR_TREEは、階層的な輪郭情報を取得するためのモードです。cv2.CHAIN_APPROX_SIMPLEは、輪郭の近似法を指定しており、輪郭を単純化してメモリ効率を向上させます。
5. 線分フィッティング
各輪郭に対して線分フィッティングを行います。cv2.fitLine関数は、最小二乗法を使って指定した輪郭に線をフィッティングします。
# 線分フィッティングの処理
for contour in contours:
# 輪郭が2点以上の場合のみ線分フィッティングが可能
if len(contour) >= 2:
# cv2.fitLineを使って線をフィッティング
[vx, vy, x, y] = cv2.fitLine(contour, cv2.DIST_L2, 0, 0.01, 0.01)
# フィッティングした線の始点と終点を計算して描画
lefty = int((-x * vy / vx) + y)
righty = int(((image.shape[1] - x) * vy / vx) + y)
cv2.line(image, (image.shape[1] - 1, righty), (0, lefty), (0, 255, 0), 2)
ここでは、次のようにして線分フィッティングを行います
・cv2.fitLine関数により、最小二乗法で線の方向(vx, vy)と線上の1点(x, y)を取得します。
・フィッティングされた線を描画するために、画像の左端と右端のy座標を計算し、cv2.lineで線を引きます。
6. 結果の表示
最後に、フィッティングの結果を表示し、線分フィッティングの結果を確認します。
# 結果を表示
cv2.imshow("Ellipses", image)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imshowで画像を表示し、cv2.waitKey(0)でキーが押されるまでウィンドウを開いたままにします。cv2.destroyAllWindows()はすべてのOpenCVウィンドウを閉じます。