计算机视觉 (八) -- 霍夫变换Hough

霍夫变换Hough

霍夫变换(Hough)是一个非常重要的检测间断点边界形状的方法。它通过将图像坐标空间变换到参数空间,来实现直线与曲线的拟合。主要用途就是找到图片中的直线或圆形区域。

1.直线检测

1.1 直线坐标参数空间

在图像xy

坐标空间中,经过点 (xi,yi)

的直线表示为:

yi=axi+b(1)

ab


通过 (xi,yi)的直线有无数条,且对应于不同的 ab

值。

如果将xi

yi

视为常数,而将原本的参数a和b看作变量,则式子(1)可以表示为:

b=xia+yi(2)

这样就变换到了参数平面ab

。这个变换就是直角坐标中对于 (xi,yi)

点的Hough变换。

该直线是图像坐标空间中的点(xi,yi)

在参数空间的唯一方程。考虑到图像坐标空间中的另一袋奶 (xj,yj)

,它在参数空间中也有相应的一条直线,表示为:

b=xja+yj(3)

这条直线与点(xi,yi)

在参数空间的直线相交于一点 (a0,b0),如图所示:
这里写图片描述
图像坐标空间中过点 (xi,yi)和点 (xj,yj)的直线上的每一点在参数空间 ab上各自对应一条直线,这些直线都相交于点 (a0,b0),而 a0b0就是图像坐标空间 xy中点 (xi,yi)和点 (xj,yj)

所确定的直线的参数。
反之,在参数空间相交于同一点的所有直线,在图像坐标空间都有共线的点与之对应。根据这个特性,给定图像坐标空间的一些边缘点,就可以通过Hough变换确定连接这些点的直线方程。

具体计算时,可以将参数空间视为离散的。建立一个二维累加数组A(a,b)

,第一维的范围是图像坐标空间中直线斜率的可能范围,第二维的范围是图像坐标空间中直线截矩的可能范围。开始时A(a,b)初始化为0,然后对图像坐标空间的每一个前景点(xi,yi),将参数空间中每一个a的离散值代入式子(2)中,从而计算出对应的b值。每计算出一对(a,b),都将对应的数组元素A(a,b)加1,即A(a,b)=A(a,b)+1。所有的计算结束之后,在参数计算表决结果中找到A(a,b)的最大峰值,所对应的a0b0就是源图像中共线点数目最多(共A(a,b)个共线点)的直线方程的参数;接下来可以继续寻找次峰值和第3峰值和第4峰值等等,它们对应于原图中共线点略少一些的直线。


import numpy as np
import matplotlib.pyplot as plt
import cv2
import imgHelp
image = cv2.imread( 'imgs/5.jpg' )

gray = cv2.GaussianBlur(cv2.cvtColor(image,cv2.COLOR_RGB2GRAY),( 7 , 7 ), 3 )

fft_img = imgHelp.fftPic(gray, 30 )

h_threshold = 100
l_threshold = 50


edges = cv2.Canny(gray,l_threshold,h_threshold)

rho = 1
theta = np.pi / 180
threshold = 150
min_line_length = 1
max_line_gap = 10
line_image = np.copy(image)
lines = cv2.HoughLinesP(edges, rho, theta, threshold, np.array([]),min_line_length, max_line_gap)
for line in lines:
for x1,y1,x2,y2 in line:
cv2.line(line_image,(x1,y1),(x2,y2),( 255 , 0 , 0 ), 5 )

circles_im = np.copy(image)
circles = cv2.HoughCircles(edges, cv2.HOUGH_GRADIENT, 1 , minDist = 35 , param1 = 100 , param2 = 20 , minRadius = 20 , maxRadius = 40 )
circles = np.uint32(np.around(circles))
for i in circles[ 0 ,:]:
cv2.circle(circles_im,(i[ 0 ],i[ 1 ]),i[ 2 ],( 0 , 255 , 0 ), 2 )
f,(a1,a2,a3,a4,a5,a6) = plt.subplots( 1 , 6 , figsize = ( 600 , 400 ))

a1.set_title( "oraginal image" )
a1.imshow(image)

a2.set_title( "gra" )
a2.imshow(gray, cmap = "gray" )

a3.set_title( "fft" )
a3.imshow(fft_img, cmap = "gray" )

a4.set_title( "edges" )
a4.imshow(edges, cmap = "gray" )

a5.set_title( "line_image" )
a5.imshow(line_image)

a6.set_title( "circles_im" )
a6.imshow(circles_im)
plt.show()


猜你喜欢

转载自blog.csdn.net/u010676526/article/details/80110868