Hough变换思想(参数空间变换):

在原始图像坐标系下的一个点对应了参数坐标系中的一条直线,同样参数坐标系的一条直线对应了原始坐标系下的一个点,然后,原始坐标系下呈现直线的所有点,它们的斜率和截距是相同的,所以它们在参数坐标系下对应于同一个点。这样在将原始坐标系下的各个点投影到参数坐标系下之后,看参数坐标系下有没有聚集点,这样的聚集点就对应了原始坐标系下的直线。

在实际应用中,y=kx+b形式的直线方程没有办法表示x=c形式的直线(这时候,直线的斜率为无穷大)。所以实际应用中,是采用参数方程p=xcos(theta)+y*sin(theta)。这样,图像平面上的一个点就对应到参数p—theta平面上的一条曲线上,其它的还是一样。

Hough变换思想(参数空间划分网格统计):

为了检测出直角坐标X-Y中由点所构成的直线,可以将极坐标a-p量化成许多小格。根据直角坐标中每个点的坐标(x,y),在a = 0-180°内以小格的步长计算各个p值,所得值落在某个小格内,便使该小格的累加记数器加1。当直角坐标中全部的点都变换后,对小格进行检验,计数值最大的小格,其(a,p)值对应于直角坐标中所求直线。

Hough变换的程序实现:

import cv2

import numpy as np

#hough变换的程序实现

img = cv2.imread("building.jpg")#读取图片

img2 = img.copy()

gray =cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#将图片转换为灰度图

edges = cv2.Canny(gray,50,150,apertureSize = 3)#canny算法提取轮廓

#基于概率的hough变换......................................................

lines_Probabilitys = cv2.HoughLinesP(edges,1,np.pi/180,30,minLineLength=100,maxLineGap=10)#概率hough变换

lines_Probability = lines_Probabilitys[:,0,:]#提取为二维

for x1,y1,x2,y2 in lines_Probability[:]:

cv2.line(img,(x1,y1),(x2,y2),(255,0,0),1)

cv2.namedWindow("HoughLines_Probabilitys", 2) #创建一个窗口

cv2.imshow('HoughLines_Probabilitys', img) #显示原始图片

#标准的hough变换......................................................

lines_standards = cv2.HoughLines(edges,1,np.pi/180,200) #标准hough变换查找直线

#绘制hough变换后找到的所有直线,返回数据是一个二位数组

for lines_standard in lines_standards:

for rho,theta in lines_standard:

a = np.cos(theta)

b = np.sin(theta)

x0 = a*rho

y0 = b*rho

x1 = int(x0 + 1000*(-b))

y1 = int(y0 + 1000*(a))

x2 = int(x0 - 1000*(-b))

y2 = int(y0 - 1000*(a))

cv2.line(img2,(x1,y1),(x2,y2),(0,0,255),2)

print(lines_standards)#打印出找到的直线的极坐标系坐标、

cv2.namedWindow("HoughLines_standards", 2) #创建一个窗口

cv2.imshow('HoughLines_standards', img2) #显示原始图片

cv2.waitKey()

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

函数参数解释:

HoughLinesP(image, rho, theta, threshold, lines=None, minLineLength=None, maxLineGap=None)

image: 必须是二值图像,推荐使用canny边缘检测的结果图像;

rho: 线段以像素为单位的距离精度,double类型的,推荐用1.0

theta: 线段以弧度为单位的角度精度,推荐用numpy.pi/180

threshod: 累加平面的阈值参数,int类型,超过设定阈值才被检测出线段,值越大,基本上意味着检出的线段越长,检出的线段个数越少。根据情况推荐先用100试试

lines:这个参数的意义未知,发现不同的lines对结果没影响,但是不要忽略了它的存在

minLineLength:线段以像素为单位的最小长度,根据应用场景设置

maxLineGap:同一方向上两条线段判定为一条线段的最大允许间隔(断裂),超过了设定值,则把两条线段当成一条线段,值越大,允许线段上的断裂越大,越有可能检出潜在的直线段

cvHoughLines2( CvArr* image, void* line_storage, int method,double rho, double theta, int threshold,double param1=0, double param2=0 );

image输入 8-比特、单通道 (二值) 图像,其内容可能被函数所改变

line_storage检测到的线段存储.

method

CV_HOUGH_STANDARD - 传统或标准 Hough 变换. 每一个线段由两个浮点数 (ρ, θ)表示,其中 ρ 是点与原点 (0,0) 之间的距离, θ 线段与 x-轴之间的夹角。因此,矩阵类型必须是 CV_32FC2 type.

CV_HOUGH_PROBABILISTIC - 概率 Hough 变换(如果图像包含一些长的线性分割,则效率更高). 它返回线段分割而不是整个线段。每个分割用起点和终点来表示,所以矩阵(或创建的序列)类型是 CV_32SC4.

CV_HOUGH_MULTI_SCALE - 传统 Hough 变换的多尺度变种。线段的编码方式与CV_HOUGH_STANDARD 的一致。

rho与象素相关单位的距离精度

theta弧度测量的角度精度

threshold阈值参数。如果相应的累计值大于 threshold, 则函数返回的这个线段.

param1第一个方法相关的参数:

对传统 Hough 变换,不使用(0).

对概率 Hough 变换,它是最小线段长度.

对多尺度 Hough 变换,它是距离精度 rho 的分母 (大致的距离精度是 rho 而精确的应该是 rho / param1 ).

param2第二个方法相关参数:

对传统 Hough 变换,不使用 (0).

对概率 Hough 变换,这个参数表示在同一条直线上进行碎线段连接的最大间隔值(gap), 即当同一条直线上的两条碎线段之间的间隔小于 param2 时,将其合二为一。

对多尺度 Hough 变换,它是角度精度 theta 的分母 (大致的角度精度是 theta 而精确的角度应该是 theta / param2).

检测效果:

---------------------

opencv+python Hough变换的基本原理

作者:逗创创

原文:https://blog.csdn.net/u014005758/article/details/88403937

版权声明:本文为博主原创文章,转载请附上博文链接!

相关文章