OpenCVとPythonによるハフ変換を用いた形状検出の理解と実装

Feature Image

本日は、ハフ変換という手法を使って画像内の直線や円を検出する方法を学びます。

ハフ空間とは

ハフ変換を画像に適用する前に、ハフ空間とは何かについて理解する必要があります。

パラメータ空間

画像を扱うとき、画像はいくつかのxとy座標上の2次元行列であると想像することができます。 ハフ空間と呼ぶことにしますが、同じ線をmbと表すことができるので、画像空間での線の特徴は、ハフ空間ではm-bの位置にある1点になります。

Hough Space

Hough Space

しかし問題があります、y = mx + bでは傾きが無限大なので、垂直線を表すことができないのです。 そこで、より良い方法として、極座標(rhoとtheta)のパラメトリゼーションが必要です。

ハフ空間

  • rho: 原点からの線の距離を表す
  • theta: 水平からの角度を表す
Line Polar Coordinates

Line Polar Coordinate

しかし1つ非常に大切なことは、ある線を中心に複数の点を持って、ハフ空間に変換するとどうなるか、ということです。

Dots and Line relation in Hough Space
Dots and Line relation in Hough Space

Image Space上の1つのドットはHough Space上の曲線に翻訳され、特にImage Space上の線の中の点は1タッチポイントで複数の曲線で表現されることが特徴です。

そして、これが私たちの目標である、曲線の集まりが交差する点を見つけることです。

ハフ変換とは

ハフ変換とは、画像中の円や線などの単純な形を検出する特徴抽出手法の一つです。 たとえば、直線はその傾きと切片で表現でき、円は x、y、半径で表現できます。

直線の例では、ハフ変換が画像上のドットを処理してハフ空間内の値を計算する役割を果たします。

Detecting lines using OpenCV

OpenCV では,ハフ変換を用いた線の検出は,関数 HoughLinesHoughLinesP (Probabilistic Hough Transform) で実装されています. この関数は,以下のパラメータを持ちます:

  • image: 8ビット,シングルチャンネルの2値画像. この画像は関数によって変更される可能性があります。 線の出力ベクトル. 各線分は4要素のベクトル (x_1, y_1, x_2, y_2) で表され、 (x_1,y_1) と (x_2, y_2) は検出された各線分の終点となる。 アキュムレータの距離分解能(ピクセル).
  • theta: アキュムレータの角度分解能(ラジアン).
  • threshold: アキュムレータの閾値パラメータ。 十分な投票数を得た行だけが返されます
  • minLineLength: 行の長さの最小値です。 これより短い線分は拒否されます。
  • maxLineGap:
  • maxLineGap: 同じ線上にある点を結ぶために許される最大の間隔(max gap between the points on the same line)

複雑すぎますか?

# Read image img = cv2.imread('lanes.jpg', cv2.IMREAD_COLOR)# Convert the image to gray-scalegray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# Find the edges in the image using canny detectoredges = cv2.Canny(gray, 50, 200)# Detect points that form a linelines = cv2.HoughLinesP(edges, 1, np.pi/180, max_slider, minLineLength=10, maxLineGap=250)# Draw lines on the imagefor line in lines: x1, y1, x2, y2 = line cv2.line(img, (x1, y1), (x2, y2), (255, 0, 0), 3)# Show resultcv2.imshow("Result Image", img)

そしてこれがその結果です:

Line Detection Example

Line Detection Example

Hough変換のパラメータとして実際に端だけの画像を使用することが非常に重要で、さもないとアルゴリズムは意図したように機能しないのです。

OpenCV を使用して円を検出する

このプロセスは線の場合とほぼ同じですが、今回は OpenCV ライブラリの別の関数を使用するという例外があります。

  • image: 8-bit, single-channel, grayscale input image.
  • circles: 見つかった円の出力ベクトル。 各ベクトルは3要素の浮動小数点ベクトル(x, y, radius)としてエンコードされる。
  • circle_storage: C関数では、これは見つかった円の出力シーケンスを格納するメモリストレージである。 使用する検出方法。 現在,実装されている唯一の方法は CV_HOUGH_GRADIENT で,基本的には 21HT
  • dp: アキュムレータの分解能と画像の分解能の逆比率です. 例えば, dp=1 の場合,アキュムレータの解像度は入力画像と同じになります. dp=2 の場合、アキュムレータの幅と高さは半分になります。
  • minDist: 検出された円の中心間の最小距離。 このパラメータが小さすぎると、真の円だけでなく、複数の隣接する円が誤って検出されることがある。 大きすぎると、いくつかの円を見落とす可能性がある。
  • param1: 最初のメソッド固有のパラメータです。 CV_HOUGH_GRADIENT の場合,Canny() のエッジ検出器に渡される2つの閾値のうち高い方を指定します(低い方は2倍小さくなります). CV_HOUGH_GRADIENT の場合,これは検出ステージにおける円の中心に対するアキュムレータの閾値です. これが小さいほど,より多くの偽円が検出される可能性があります. 5260>
  • minRadius: 円の最小半径.
  • maxRadius:
  • maxRadius: 円の最大半径.

パラメータが異なる必要があることに注意してください。線に対して使用したのと同じパラメトリックでは円を記述できず、代わりに、(x - x0)^^2 + (y - y0)^^2 = r^^2のような方程式を使用する必要があるからです。

円検出の例

円検出の例

結論

ハフ変換は画像内の単純形状を検出する優れた手法で、X線、CT、MRI 分析などの医療アプリケーションから自動運転車までさまざまに使用されています。 Hough 空間についてもっと知りたいという方は、実際にコードを実行し、自分でさまざまな設定を試し、さらに OpenCV のドキュメントをチェックしてみることをお勧めします。

お読みいただきありがとうございました!

Hough 空間についてもっと知りたいという方は、実際にコードを実行して、自分でさまざまな設定を試し、さらに OpenCV のドキュメントをチェックしてみてください。

コメントを残す

メールアドレスが公開されることはありません。