opencv学習15:直線検出

ライン検出

原則の紹介:

1.直交座標系の任意の点A(x0、y0)について、点Aを通る線はY0 = k * X0 + bを満たします(kは傾き、bは切片)

2.次に、XY平面上の点A(x0、y0)を通過する線のクラスターは、Y0 = k * X0 + bで表すことができますが、X軸に垂直な線の傾きが無限大の場合は表すことができません。 。したがって、直交座標系を極座標系に変換すると、この特殊な状況を解決できます。

3.極座標系で直線を表す方程式は、図に示すように、ρ=xCosθ+ySinθ(ρは原点から直線までの距離)です。ハフ線検出を
ここに画像の説明を挿入ここに画像の説明を挿入変換する
ここに画像の説明を挿入
2つの方法
1。グレースケール画像の取得
2.キャニーエッジ検出
3.ハフライン情報の取得
4.ラインの位置を計算し、各ラインを描画します

線形検出コードの実装方法1

1つ:標準のハフライン変換

void HoughLines(InputArray image、OutputArray lines、double rho、double theta、int threshold、double srn = 0、double stn = 0)
パラメーター:
image:エッジ検出の出力画像。グレースケール画像である必要があります(実際にはは2本の(値のあるマップ)
線です:検出された直線のパラメーターペアを格納するコンテナー、rho、theta
rho:パラメーターの極直径の解像度(ピクセル単位)。1ピクセルを使用します
。theta:パラメーターの極角ラジアン単位の解像度です。1度(つまりCV_PI / 180)の
シータを使用します。直線
srnおよびstnを「検出」するために必要な最小曲線交点:パラメータのデフォルトは0です。

cv2.HoughLines関数の出力は、[float、float]の形式のndarrayです。ここで、各値は、検出されたラインの浮動小数点値のパラメーター(ρ、θ)を表します。

import cv2 as cv
import numpy as np


def line_detection(image):
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    edges = cv.Canny(gray, 50, 150, apertureSize=3)#apertureSize,Canny边缘检测梯度那一步,窗口大小是3   apertureSize是sobel算子大小,只能为1,3,5,7
    lines = cv.HoughLines(edges, 1, np.pi/180, 200) #函数将通过步长为1的半径和步长为π/180的角来搜索所有可能的直线
    for line in lines:
        print(type(lines))
        rho, theta = line[0]  #获取极值ρ长度和θ角度
        a = np.cos(theta) #获取角度cos值
        b = np.sin(theta)#获取角度sin值
        x0 = a * rho #获取x轴值
        y0 = b * rho #获取y轴值  x0和y0是直线的中点
        x1 = int(x0 + 1000 * (-b)) #获取这条直线最大值点x1
        y1 = int(y0 + 1000 * (a)) #获取这条直线最大值点y1
        x2 = int(x0 - 1000 * (-b)) #获取这条直线最小值点x2
        y2 = int(y0 - 1000 * (a)) #获取这条直线最小值点y2  其中*1000是内部规则
        cv.line(image, (x1, y1), (x2, y2), (0, 0, 255), 2) #开始划线
    cv.imshow("image_lines", image)

src = cv.imread("C:/Users/lenovo/Desktop/opencv/daima/banknum/template-matching-ocr/images/sudoku.png")  #读取图片位置
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
line_detection(src)
cv.waitKey(0)
cv.destroyAllWindows()

スクリーンショットを実行する:
ここに画像の説明を挿入ただし、これにより、ピクセルの誤った位置合わせや、同じ位置合わせされたピクセルと交差する複数の直線によって引き起こされる複数の検出など、誤検出が発生する場合があります。

2:HoughLinesP確率的ハフ変換(拡張バージョン)は使いやすく、より良い結果が得られます(画像全体を通る直線ではなく)画像内のセグメント化された直線を検出します

void HoughLinesP(InputArray image、OutputArray lines、double rho、double theta、int threshold、double minLineLength = 0、double maxLineGap = 0)
パラメーター:
image:エッジ検出の出力画像。グレースケール画像である必要があります(実際にはは2つの(値のあるマップ)*
ライン:検出されたラインのパラメーターペア、つまりラインセグメントの2つの端点の座標を格納するコンテナーです
。rho:パラメーターの極径の解像度(単位は)ピクセル値。1ピクセルを使用し
ますシータ:パラメータ極角度はラジアン単位の解像度です。1度(つまりCV_PI / 180)の
しきい値を使用します:直線を「検出」するために必要な最小曲線交点
minLinLength:最小数直線を形成できる点の数点の数が不足している直線は破棄されます。
線セグメントの最小長maxLineGap:線セグメント上の2つの最も近い点の間のしきい値
コードは次のとおりです。

import cv2 as cv
import numpy as np


def line_detect_possible_demo(image):
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    edges = cv.Canny(gray, 50, 150, apertureSize=3)  # apertureSize,Canny边缘检测梯度那一步,窗口大小是3
    lines = cv.HoughLinesP(edges, 1, np.pi / 180, 100, minLineLength=50, maxLineGap=10)  #函数将通过步长为1的半径和步长为π/180的角来搜索所有可能的直线
    #minLineLength-线的最短长度,比这个线短的都会被忽略
    #maxLineGap-两条线之间的最大间隔,如果小于此值,这两条线就会被看成一条线。
    for line in lines:
        print(type(line))
        x1, y1, x2, y2 = line[0]
        cv.line(image, (x1, y1), (x2, y2), (0, 0, 255), 2)
    cv.imshow("line_detect_possible_demo", image)

src = cv.imread("C:/Users/lenovo/Desktop/opencv/daima/banknum/template-matching-ocr/images/sudoku.png")  #读取图片位置
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
line_detect_possible_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()

:ランショット
ここに画像の説明を挿入
:DEF HoughLinesP(イメージ、Rhoの、シータ、しきい値、ライン=なし、minLineLength =なし、maxLineGap =なし)
最初のパラメータは、処理対象の原画像であり、画像はエッジ検出後cannay画像てはならない。
第一ザ2番目と3番目のパラメーター:ステップ長が1の半径と、ステップ長がπ/ 180の角度で、すべての可能な直線を検索します。4番目のパラメーターはしきい値であり、概念はハフ変換と同じです。 5番目のパラメータ:minLineLength-行の最短の長さ。この行より短いものはすべて無視されます。

6番目のパラメーター:maxLineGap-2つの線の間の最大ギャップ。この値よりも小さい場合、2つの線は1つの線と見なされます。

おすすめ

転載: blog.csdn.net/weixin_44145452/article/details/112767669