opencv チュートリアルチャレンジ13 ハフ変換による直線検出

ハフ変換による直線検出 — OpenCV-Python Tutorials 1 documentation

直線を検出したい

cv2.HoughLines

標準ハフ変換

void HoughLines(Mat& image, vector<Vec2f>& lines, double rho, double theta, int threshold, double srn=0, double stn=0)
標準ハフ変換を用いて,2値画像から直線を検出します.

パラメタ:   
image – 8ビット,シングルチャンネルの2値入力画像.この画像は関数により書き換えられる可能性があります.
lines – 検出された直線が出力されるベクトル.各直線は,2要素のベクトル  (\rho, \theta) で表現されます.  \rho は原点(画像の左上コーナー)からの距離,  \theta はラジアン単位で表される直線の回転角度(0  \sim 垂直線, \pi/2 \sim 水平線)です.
rho – ピクセル単位で表される投票空間の距離分解能.
theta – ラジアン単位で表される投票空間の角度分解能.
threshold – 投票の閾値パラメータ.十分な票(  >\texttt{threshold} )を得た直線のみが出力されます.
srn – マルチスケールハフ変換において,距離分解能 rho の除数となる値.投票空間の粗い距離分解能は rho となり,細かい分解能は rho/srn となります.もし srn=0 かつ stn=0 の場合は,古典的ハフ変換が利用されます.そうでない場合は,両方のパラメータが正値である必要があります.
stn – マルチスケールハフ変換において,角度分解能 theta の除数となる値.

やってみる

lines = cv2.HoughLines(edges, 1, np.pi/180, 200)

for line in lines:
    rho, theta = line[0]
    a = np.cos(theta)
    b = np.sin(theta)
    x0 = a*rho
    y0 = b*rho
    x1 = int(x0 + 1000*(-b))
    y1 = int(y0 + 1000*(a))
    x2 = int(x0 - 1000*(-b))
    y2 = int(y0 - 1000*(a))
    cv2.line(img,(x1,y1),(x2,y2),(0,0,255),1)

これが f:id:pongsuke:20170519145721p:plain

こう f:id:pongsuke:20170519160959p:plain

cv2.HoughLinesP

確率的ハフ変換

void HoughLinesP(Mat& image, vector<Vec4i>& lines, double rho, double theta, int threshold, double minLineLength=0, double maxLineGap=0)
確率的ハフ変換を利用して,2値画像から線分を検出します.

パラメタ:   
image – 8ビット,シングルチャンネルの2値入力画像.この画像は関数により書き換えられる可能性があります.
lines – 検出された線分が出力されるベクトル.各線分は,4要素のベクトル  (x_1, y_1, x_2, y_2) で表現されます.ここで  (x_1,y_1) および  (x_2, y_2) は,検出された各線分の端点です.
rho – ピクセル単位で表される投票空間の距離分解能.
theta – ラジアン単位で表される投票空間の角度分解能.
threshold – 投票の閾値パラメータ.十分な票(  >\texttt{threshold} )を得た直線のみが出力されます.
minLineLength – 最小の線分長.これより短い線分は棄却されます.
maxLineGap – 2点が同一線分上にあると見なす場合に許容される最大距離.

やってみる

lines = cv2.HoughLinesP(edges, 1, np.pi/180, 200, 100, 10)
for line in lines:
    x1,y1,x2,y2 = line[0]
    cv2.line(img,(x1,y1),(x2,y2),(0,255,0),2)

これが f:id:pongsuke:20170519145721p:plain

こう f:id:pongsuke:20170519154453p:plain