opencv learning fifteen: straight line detection

Line detection

Principle introduction:

1. For any point A (x0, y0) in the rectangular coordinate system, the line passing through point A satisfies Y0=k*X0+b. (k is the slope, b is the intercept)

2. Then the cluster of lines passing through point A(x0, y0) on the XY plane can be represented by Y0=k*X0+b, but it cannot be represented if the slope of the line perpendicular to the X axis is infinite. Therefore, converting the rectangular coordinate system to the polar coordinate system can solve this special situation.

3. The equation representing a straight line in the polar coordinate system is ρ=xCosθ+ySinθ (ρ is the distance from the origin to the straight line), as shown in the figure: the two methods of
Insert picture description hereInsert picture description here transforming the
Insert picture description here
Hough line detection
1. Obtain grayscale image
2 .canny edge detection
3. Obtain Hough line information
4. Calculate the position of the line and draw each line

Linear detection code implementation method 1

One: Standard Hough line transformation

void HoughLines(InputArray image, OutputArray lines, double rho, double theta, int threshold, double srn=0, double stn=0)
Parameters:
image: the output image of edge detection. It should be a grayscale image (but in fact it is a two (Valued map)
lines: a container that stores the parameter pairs of the detected straight line, which stores rho, theta
rho: the resolution of the parameter polar diameter in pixels. We use 1 pixel.
theta: the parameter polar angle in radians Is the resolution in units. We use 1 degree (ie CV_PI/180)
theta: the minimum curve intersection point required to "detect" a straight line
srn and stn: the parameter defaults to 0.

The output of the cv2.HoughLines function is an ndarray in the form of [float, float], where each value represents the parameter of the floating point value in the detected line (ρ, θ).

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

Run screenshot:
Insert picture description hereBut this will lead to false detections in some cases, such as accidental alignment of pixels or multiple detections caused by multiple straight lines crossing the same aligned pixels.

Two: HoughLinesP probabilistic Hough transform (an enhanced version) is simple to use and has a better effect. It detects segmented straight lines in the image (rather than straight lines running through the entire image)

void HoughLinesP(InputArray image, OutputArray lines, double rho, double theta, int threshold, double minLineLength=0, double maxLineGap=0)
Parameters:
image: the output image of edge detection. It should be a grayscale image (but in fact it is a two (Valued map) *
lines: a container that stores the parameter pairs of the detected line, that is, the coordinates of the two end points of the line segment.
rho: the resolution of the parameter polar diameter in the unit of pixel value. We use 1 pixel.
theta: parameter polar The angle is the resolution in radians. We use 1 degree (ie CV_PI/180)
threshold: the minimum curve intersection point required to "detect" a straight line
minLinLength: the minimum number of points that can form a straight line. The number of points is insufficient The straight line will be discarded. The minimum length of the
line segment maxLineGap: the threshold between the two nearest points on the line segment The
code is as follows:

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

Run shot:
Insert picture description here
DEF HoughLinesP (Image, Rho, Theta, threshold, Lines = None, minLineLength = None, maxLineGap = None):
The first parameter is the original image to be processed, the image must be cannay image after edge detection;
first The second and third parameters: a radius with a step length of 1 and an angle with a step length of π/180 to search for all possible straight lines. The fourth parameter is the threshold, and the concept is the same as the Hough transform. The fifth parameter: minLineLength- the shortest length of the line , Anything shorter than this line will be ignored.

The sixth parameter: maxLineGap-the maximum gap between two lines, if less than this value, the two lines will be regarded as one line.

Guess you like

Origin blog.csdn.net/weixin_44145452/article/details/112767669