yutapuu
@yutapuu

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

直線検出について

解決したいこと

画像を二値化して直線検出を行おうとしています。HoughLine関数の引数をいろいろ試しながら行っているのですが左淵にのみ線が検出されるか、線が無数に検出されるかの二通りしかでてきません。線が無数に検出されてしまうのはまだわかるのですが左淵にのみ検出されるのはなぜなのか教えていただきたいです。元画像と二値化画像と直線検出の結果を以下に載せておきます。
xyz.jpg

xyzmono.jpg

lines.jpg

該当するソースコード

import cv2
import numpy as np
import os

os.chdir("C:\\suzuki2")

img = cv2.imread("CRT_OK_03_001.JPG") 

imgg = cv2.imread("xyzmono.jpg", 0)

lines = cv2.HoughLines(imgg, 1, np.pi/360, 600, 600, 100)

rows, cols = img.shape[:2]

for rho, theta in lines[:, 0]:

    a = np.cos(theta)
    b = np.sin(theta)
    x0 = a*rho
    y0 = b*rho
    cv2.line(img,
            (int(x0 - cols*(b)), int(y0 + cols*(a))),
            (int(x0 + cols*(b)), int(y0 - cols*(a))),
            (0, 0, 255), 2)


cv2.imwrite("lines.jpg", img)
0

1Answer

しきい値パラメータ600が厳しすぎます。600点投票されるのはかなりノルマが厳しいので、200程度でよいのではないでしょうか。
それと、エッジ検出をしてから、ハフ変換をすればより良いと思います。

ハフ変換では、二値画像の各白ピクセルに対して、直線をくるくると回転させて、その上にのっている白ピクセルの数を投票していきます。そして、投票の多かったピクセルとその時の角度を「直線」であるとするアルゴリズムです。

単純な画像の二値化では、次のような問題でうまく働きません。

  1. 白画素が多すぎて、どこをとっても投票数が多くなってしまい、「直線」と認識される。(左側に直線が多く出てしまうのはこのためです。)
  2. 探索する「各白ピクセル」が多すぎて重たい

なので、一旦エッジ検出をして輝度変化のみの状態にしてはどうでしょうか?

コードとしては以下のような感じになります。

import cv2
import numpy as np

img = cv2.imread("CRT_OK_03_001.JPG")

edge_img = cv2.Canny(img, 100, 200)

rows, cols = edge_img.shape[:2]

lines = cv2.HoughLines(edge_img, 1, np.pi/360, 200, 100, 100)

for rho, theta in lines[:, 0]:

    a = np.cos(theta)
    b = np.sin(theta)
    x0 = a*rho
    y0 = b*rho

    cv2.line(img, (int(x0 - cols*(b)), int(y0 + cols*(a))), (int(x0 + cols*(b)), int(y0 - cols*(a))),(0, 0, 255), 2)


cv2.imwrite("lines.jpg", img)

あくまで参考程度にですが上の実行結果はこうなります。

エッジ画像
edge_image.jpg
検出画像
lines.jpg

1Like

Comments

  1. @yutapuu

    Questioner

    なるほど、まずはエッジ検出からってことですね、ありがとうございます!

Your answer might help someone💌