如何使用Python对图片进行霍夫变换

1. 介绍霍夫变换

霍夫变换是一种经典的计算机视觉算法,常用来识别图像中的直线和圆等基本几何形状。霍夫变换的基本思想是将原始图像中的每个像素进行变换,变换后的结果是一个参数空间(Hough Space),它与原始图像可以建立对应关系,霍夫变换就是通过在参数空间中对像素进行计数,然后根据像素点的最大值匹配出对应的几何形状。

1.1 表示一条直线

霍夫变换最常见的应用是检测直线,我们可以将一条直线表示为:

y = mx + b

其中m表示直线斜率,b表示直线截距。

在霍夫变换中,我们使用两个参数来表示一条直线,即:

参数r:表示直线距离原点的距离

参数theta:表示直线与x轴的夹角

对于每条直线,我们可以在参数空间中用一个点来表示。对于每一个在直线上的点(x,y),我们可以计算出对应的r和theta:

r = x * cos(theta) + y * sin(theta)

这个方程式在数学中被称作极坐标方程式,它将直线的表示从直角坐标系转换到了极坐标系。

1.2 表示一条圆

同样的,我们也可以使用霍夫变换来检测圆。以Cartesian坐标表示一个圆心为(c_x,c_y),半径为r的圆。则它可以被表示为:

(x-c_x)^2 + (y-c_y)^2 = r^2

我们可以将该公式转换成极坐标系下的形式:

x = c_x + r*cos(theta)

y = c_y + r*sin(theta)

将上述方程式转化成三个参数:

r:圆心到圆心的距离

theta_c:圆心在单位圆上的极角

theta_p:该圆上的一点在单位圆上的极角

在参数空间中,可以用一个三元组(r,theta_c,theta_p)来表示圆的所有可能。

2. 霍夫变换的实现

2.1 霍夫变换检测直线

在OpenCV中,计算霍夫变换可以使用函数cv2.HoughLines(),它有四个参数:

第一个参数是一个二值化图像,即只有非黑即白的图像。

第二个参数rho表示以像素为单位的距离精度,一般取1。

第三个参数theta表示以弧度为单位的角度精度,一般取pi/180。

第四个参数threshold表示直线的最短长度,超过threshold才被认为是直线。

下面是一个简单的例子,假设我们有一张图片,我们需要在图片中检测出直线:

import cv2

import numpy as np

img = cv2.imread('lines.jpg')

gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

edges = cv2.Canny(gray,50,150,apertureSize = 3)

cv2.imshow('edges',edges)

lines = cv2.HoughLines(edges,1,np.pi/180,200)

for line in lines:

rho,theta = line[0]

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(img,(x1,y1),(x2,y2),(0,0,255),2)

cv2.imshow('image',img)

cv2.waitKey(0)

cv2.destroyAllWindows()

上述程序一共有三个部分:

首先读入一个图片,将其转化为灰度图。

通过Canny边缘检测找到所有的边缘。

使用霍夫变换检测所有的直线,并在图片上画出。

运行后的图片如下所示:

2.2 霍夫变换检测圆

在OpenCV中,计算霍夫变换可以使用函数cv2.HoughCircles(),它有五个参数:

第一个参数是一个二值化图像,即只有非黑即白的图像。

第二个参数表示使用的检测方法,一般选默认值cv2.HOUGH_GRADIENT。

第三个参数表示两个圆中心之间的最小距离。

第四个参数表示Canny边缘检测的高阈值,低阈值将自动设为高阈值的一半。

第五个参数表示检测到圆的最小半径,一般设为0。

第六个参数表示检测到圆的最大半径,一般设为0。

下面是一个简单的例子,假设我们有一张图片,我们需要在图片中检测出圆:

import cv2

import numpy as np

img = cv2.imread('coins.jpg')

gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

gray_blur = cv2.medianBlur(gray, 5)

circles = cv2.HoughCircles(gray_blur,cv2.HOUGH_GRADIENT,1,20,param1=50,param2=30,minRadius=0,maxRadius=0)

for i in circles[0,:]:

# draw the outer circle

cv2.circle(img,(i[0],i[1]),i[2],(255,0,0),2)

# draw the center of the circle

cv2.circle(img,(i[0],i[1]),2,(0,0,255),3)

cv2.imshow('output', img)

cv2.waitKey(0)

cv2.destroyAllWindows()

上述程序一共有三个部分:

首先读入一张硬币图片,将其转化为灰度图。

通过中值模糊算法将图片平滑。

使用霍夫变换检测所有的圆,并在图片上画出。

运行后的图片如下所示:

3. 总结

霍夫变换是图像处理中非常重要的算法之一,它可以帮助我们检测出图像中的基本几何形状,如直线和圆等。在实际的图像处理中,我们经常需要使用霍夫变换来检测出图像中的某些关键信息,如识别出车道线等。在OpenCV中,实现霍夫变换非常简单,只需要使用cv2.HoughLines()和cv2.HoughCircles()等函数即可。

后端开发标签