opencv learning quinze: détection de ligne droite

Détection de ligne

Introduction du principe:

1. Pour tout point A (x0, y0) dans le repère rectangulaire, la droite passant par le point A satisfait Y0 = k * X0 + b. (K est la pente, b est l'intersection)

2. Ensuite, le groupe de droites passant par le point A (x0, y0) sur le plan XY peut être représenté par Y0 = k * X0 + b, mais il ne peut pas être représenté si la pente de la droite perpendiculaire à l'axe X est infinie . Par conséquent, la conversion du système de coordonnées rectangulaires en système de coordonnées polaires peut résoudre cette situation particulière.

3. L'équation représentant une droite dans le système de coordonnées polaires est ρ = xCosθ ​​+ ySinθ (ρ est la distance de l'origine à la droite), comme le montre la figure: les deux méthodes de
Insérez la description de l'image iciInsérez la description de l'image ici transformation de la
Insérez la description de l'image ici
détection de la ligne de Hough
1. Obtenir l'image en niveaux de gris
2. Détection des bords de la cage
3. Obtenir les informations sur la ligne Hough
4. Calculer la position de la ligne et dessiner chaque ligne

Méthode d'implémentation du code de détection linéaire 1

Un: transformation de ligne Hough standard

void HoughLines (image InputArray, lignes OutputArray, double rho, double theta, int threshold, double srn = 0, double stn = 0)
Paramètres:
image: l'image de sortie de la détection des contours . Cela devrait être une image en niveaux de gris (mais en fait elle est une ligne à deux (Valued map)
: un conteneur qui stocke les paires de paramètres de la droite détectée, qui stocke rho, theta
rho: la résolution du paramètre diamètre polaire en pixels. Nous utilisons 1 pixel.
theta: le paramètre angle polaire en radians C'est la résolution en unités Nous utilisons 1 degré (c.-à-d. CV_PI / 180)
thêta: le point d'intersection de courbe minimum requis pour "détecter" une ligne droite
srn et stn: le paramètre vaut par défaut 0.

La sortie de la fonction cv2.HoughLines est un ndarray sous la forme de [float, float], où chaque valeur représente le paramètre de la valeur en virgule flottante dans la ligne détectée (ρ, θ).

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()

Exécuter une capture d'écran:
Insérez la description de l'image iciMais cela entraînera de fausses détections dans certains cas, comme l'alignement accidentel de pixels ou plusieurs détections causées par plusieurs lignes droites traversant les mêmes pixels alignés.

Deuxièmement: la transformation probabiliste de Hough HoughLinesP (une version améliorée) est simple à utiliser et donne de meilleurs résultats. Elle détecte les lignes droites segmentées dans l'image (plutôt que les lignes droites traversant l'image entière)

void HoughLinesP (image InputArray, lignes OutputArray, double rho, double thêta, seuil int, double minLineLength = 0, double maxLineGap = 0)
Paramètres:
image: l'image de sortie de la détection de bord. Cela devrait être une image en niveaux de gris (mais en fait elle est une (Valued map) *
lignes: un conteneur qui stocke les paires de paramètres de la ligne détectée, c'est-à-dire les coordonnées des deux extrémités du segment de ligne.
rho: la résolution du paramètre diamètre polaire dans l'unité de valeur de pixel. Nous utilisons 1 pixel.
thêta: paramètre polaire L'angle est la résolution en radians. Nous utilisons le
seuil de 1 degré (c.-à-d. CV_PI / 180) : le point d'intersection de courbe minimum requis pour "détecter" une ligne droite
minLinLength: le nombre minimum de points pouvant former une ligne droite. Le nombre de points est insuffisant. La ligne droite sera ignorée. La longueur minimale du
segment de ligne maxLineGap: le seuil entre les deux points les plus proches sur le segment de ligne Le
code est le suivant:

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()


Insérez la description de l'image ici
Prise de vue: DEF HoughLinesP (Image, Rho, Theta, threshold, Lines = None, minLineLength = None, maxLineGap = None):
Le premier paramètre est l'image d'origine à traiter, l'image doit être une image après la détection des contours; d'
abord deuxième et troisième paramètres: un rayon avec une longueur de pas de 1 et un angle avec une longueur de pas de π / 180 pour rechercher toutes les droites possibles. Le quatrième paramètre est le seuil, et le concept est le même que la transformée de Hough. Le cinquième paramètre: minLineLength - la longueur la plus courte de la ligne, tout ce qui est plus court que cette ligne sera ignoré.

Le sixième paramètre: maxLineGap - l'écart maximal entre deux lignes, s'il est inférieur à cette valeur, les deux lignes seront considérées comme une seule ligne.

Je suppose que tu aimes

Origine blog.csdn.net/weixin_44145452/article/details/112767669
conseillé
Classement