这是给Python部落翻译的文章,请在这里看原文。
在图像处理中,霍夫变换用来检测任意能够用数学公式表达的形状,即使这个形状被破坏或者有点扭曲。
下面我们将看到利用HoughLine算法来阐述霍夫变化进行直线检测的原理,把此算法应用到特点图像的边缘检测是可取的。边缘检测方法请参考这篇文章–边缘检测。
直线可以表示为 y=mx+c ,或者以极坐标形式表示为 r=xcosθ+ysinθ ,其中 r 是原点到直线的垂直距离, θ 是水平轴顺时针方向到垂直线的夹角(这个方向取决于坐标的形式,在OpenCV就是采用这种极坐标形式)。
因此任意的曲线都可以用两个参数 (r,θ) 表示。
假设一幅100x100的图像,在图像中间有一条水平直线。设直线的第一个点的坐标为 (x,y) ,在直线方程中,令参数 θ=0,12,⋯,180 ,观查参数 r 变化。对每一个参数对 (r,θ) ,在累加器中将 (r,θ) 对应的单元格中的值递增1,比如现在在累加器中,某个单元(50,90)的值等于1,其它的值也如此。
对于直线上的第二个点,重复上述操作。将得到的参数对 (r,θ) 的对应值继续递增,然后(50,90)对应的值等于2。实现上我们是对参数对 (r,θ) 进行投票,对直线上的每一个点重复上述操作,对每一个点,单元格(50,90)对应的值会递增,或者说投票给参数对(50,90),而会或者不会投票给其它参数对。以这种方式,最后单元格(50,90)的值将会是最大的值。然后搜索累加器的最大值,将会找到参数对(50,90)。也就是说,在图像中找到了到原点距离为50,角度为90的一条直线。
上述算法的过程被封装成OpenCV函数cv2.HoughLines()
,函数返回 (r,θ) 的一个数组,其中 r 的单位为像素, θ 的单位为弧度。
# 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('xyz.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]:
# 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('houghlines3.jpg', img)
cv2.HoughLines(edges, 1, np.pi/180,200)
)文章作者是Pratima Upadhyay,如果你喜欢GeeksforGeeks,并且愿意分享,可以利用contribute.geeksforgeeks.org写文章,然后发送到[email protected],在GeeksforGeeks中看到自己的文章,帮助更多的Geeks。
若发现错误欢迎指正,也欢迎评论。