用OpenCV | Houghline方法在python中进行行检测

Hough变换是一种在图像处理中用于检测任何形状的方法,前提是该形状可以用数学形式表示。即使形状有点破损或变形,它也能检测到。 我们将看到Hough变换如何使用HoughLine变换方法进行直线检测。为了应用Houghline方法,首先需要对特定图像进行边缘检测。对于边缘检测技术,请通读本文 边缘检测

null

Houghline方法基础

直线可以表示为y=mx+c或参数形式,如r=xcosθ+ysinθ,其中r是从原点到直线的垂直距离,θ是该垂直线与水平轴形成的角度,以逆时针方向测量(该方向随坐标系的表示方式而变化。此表示用于OpenCV)。

Houghline Method

所以任何一条线都可以用这两项来表示,(r,θ)。 Houghline方法的工作原理:

  • 首先,它创建一个二维数组或累加器(用于保存两个参数的值),并在初始设置为零。
  • 让行表示r,列表示(θ)θ。
  • 阵列的大小取决于所需的精度。假设希望角度的精度为1度,则需要180列(直线的最大角度为180)。
  • 对于r,最大可能的距离是图像的对角线长度。因此,以一个像素的精度,行数可以是图像的对角线长度。

例子: 考虑一个100×100的图像,中间有一条水平线。以这条线的第一个点为例。你知道它的(x,y)值。现在在直线方程中,把θ(θ)=0,1,2,…。,180并检查你得到的r。对于每个(r,0)对,在累加器中相应的(r,0)单元格中增加一个值。现在在累加器中,电池(50,90)=1和其他一些电池。 现在再看第二点。如上所述。增加对应于(r,0)的单元格中的值。这一次,单元格(50,90)=2。我们实际上是在投票(r,0)值。您可以对线上的每个点继续此过程。在每一点上,单元格(50,90)都将递增或递增,而其他单元格可能会或可能不会递增。这样,到最后,单元格(50,90)将拥有最多的投票权。因此,如果你搜索累加器的最大投票数,你会得到一个值(50,90),这个值表示,在这张图像中,有一条线距离原点50,角度90度。

Hough_transform_diagram

上面解释的所有内容都封装在OpenCV函数cv2中。HoughLines()。它只返回一个(r,0)值数组。r以像素为单位,0以弧度为单位。

python

# Python program to illustrate HoughLine
# method for line detection
import cv2
import numpy as np
# Reading the required image in
# which operations are to be done.
# Make sure that the image is in the same
# directory in which this python program is
img = cv2.imread( 'image.jpg' )
# Convert the img to grayscale
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# Apply edge detection method on the image
edges = cv2.Canny(gray, 50 , 150 ,apertureSize = 3 )
# This returns an array of r and theta values
lines = cv2.HoughLines(edges, 1 ,np.pi / 180 , 200 )
# The below for loop runs till r and theta values
# are in the range of the 2d array
for r_theta in lines[ 0 ]:
r,theta = r_theta[ 0 ]
# Stores the value of cos(theta) in a
a = np.cos(theta)
# Stores the value of sin(theta) in b
b = np.sin(theta)
# x0 stores the value rcos(theta)
x0 = a * r
# y0 stores the value rsin(theta)
y0 = b * r
# x1 stores the rounded off value of (rcos(theta)-1000sin(theta))
x1 = int (x0 + 1000 * ( - b))
# y1 stores the rounded off value of (rsin(theta)+1000cos(theta))
y1 = int (y0 + 1000 * (a))
# x2 stores the rounded off value of (rcos(theta)+1000sin(theta))
x2 = int (x0 - 1000 * ( - b))
# y2 stores the rounded off value of (rsin(theta)-1000cos(theta))
y2 = int (y0 - 1000 * (a))
# cv2.line draws a line in img from the point(x1,y1) to (x2,y2).
# (0,0,255) denotes the colour of the line to be
#drawn. In this case, it is red.
cv2.line(img,(x1,y1), (x2,y2), ( 0 , 0 , 255 ), 2 )
# All the changes made in the input image are finally
# written on a new image houghlines.jpg
cv2.imwrite( 'linesDetected.jpg' , img)


功能细化(cv2.HoughLines(Edge,1,np.pi/180200)):

  1. 第一个参数,输入图像应该是一个二值图像,所以在应用hough变换查找之前应用阈值边缘检测。
  2. 第二和第三个参数分别是r和θ(θ)精度。
  3. 第四个参数是阈值,这意味着它应该获得的最低投票权,才能被视为一条线。
  4. 记住,投票数取决于线上的点数。所以它代表了应该被检测到的线的最小长度。

The output image will look like:

直接提取点的另一种更简单的方法:

Python3

import cv2
import numpy as np
# Read image
image = cv2.imread( 'path/to/image.png' )
# Convert image to grayscale
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
# Use canny edge detection
edges = cv2.Canny(gray, 50 , 150 ,apertureSize = 3 )
# Apply HoughLinesP method to
# to directly obtain line end points
lines = cv2.HoughLinesP(
edges, # Input edge image
1 , # Distance resolution in pixels
np.pi / 180 , # Angle resolution in radians
threshold = 100 , # Min number of votes for valid line
minLineLength = 5 , # Min allowed length of line
maxLineGap = 10 # Max allowed gap between line for joining them
)
# Iterate over points
for points in lines:
# Extracted points nested in the list
x1,y1,x2,y2 = points[ 0 ]
# Draw the lines joing the points
# On the original image
cv2.line(image,(x1,y1),(x2,y2),( 0 , 255 , 0 ), 2 )
# Maintain a simples lookup list for points
lines_list.append([(x1,y1),(x2,y2)])
# Save the result image
cv2.imwrite( 'detectedLines.png' ,image)


总结过程

  • 在图像分析环境中,图像中边缘段(即X,Y)的点坐标是已知的,因此在参数线方程中用作常数,而R(rho)和θ(θ)是我们寻求的未知变量。
  • 如果我们绘制每个(θ)定义的可能(r)值,笛卡尔图像空间中的点映射到极性霍夫参数空间中的曲线(即正弦曲线)。这种点到曲线的变换是直线的Hough变换。
  • 该变换通过将Hough参数空间量化为有限区间或累加器单元来实现。当算法运行时,每个(X,Y)被转换成一条离散的(r,0)曲线,沿着该曲线的累加器(2D数组)单元递增。
  • 累加器阵列中产生的峰值有力地证明了图像中存在相应的直线。

Hough变换的应用:

  1. 它用于隔离图像中特定形状的特征。
  2. 能够容忍特征边界描述中的间隙,并且相对不受图像噪声的影响。
  3. 广泛用于条形码扫描、验证和识别

本文由 普拉蒂玛·乌帕迪亚 .如果你喜欢GeekSforgek,并想贡献自己的力量,你也可以使用 写极客。组织 或者把你的文章寄去评论-team@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。 如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写下评论。

© 版权声明
THE END
喜欢就支持一下吧
点赞8 分享