五、边缘检测
5.4 Hough变换
该技术主要用于检测图像中的基本形状,如直线、圆、椭圆等。
Hough变换的基本原理
Hough变换的基本原理是将图像空间中的直线或曲线变换到参数空间中,通过检测参数空间中的极值点(局部最大值),确定出该曲线的描述参数,从而提取影像中的规则曲线。具体来说,Hough变换利用点与线的对偶性,将原始图像空间中的曲线或直线通过其数学表达式映射到参数空间中的一个点或曲线,进而将检测问题转化为统计峰值问题。
Hough变换通过投票机制在参数空间中寻找局部最大值点,从而实现了对图像中基本图形的检测。其的优点是能够减少一定程度的噪声还有形状的不完整性造成的误差,因为它是在统计意义上寻找形状的存在。
Hough变换的步骤
①边缘检测:首先对图像进行边缘检测,提取出图像中的边缘点,这些边缘点通常是曲线或直线上的点。
②参数空间量化:将参数平面量化,然后设置二维(或三维)累计矩阵。
③投票:对每一个边缘点,在参数空间中计算所有可能经过该点的曲线(或直线)的参数值,并对相应的参数空间坐标进行投票(累加)。
④检测峰值:在参数空间中检测出投票数较大的局部最大值点,这些点对应的参数值即为图像中存在的曲线的参数。
⑤结果输出:根据检测到的参数值,在原图像中绘制出相应的曲线或直线。
直线检测的基本原理
通常情况下直线方程为y=kx+b,其中k是斜率,b是截距。但在Hough变换中,为了处理垂直于x轴的直线(斜率无穷大)的情况,常采用极坐标形式(ρ,θ)来表示直线,其中ρ表示原点到直线的距离,θ表示直线与x轴的夹角。
=
对于图像中的每一个点(x,y),可以绘制出经过该点的所有直线,这些直线在参数空间(ρ,θ)中对应一系列的点。如果多个点在图像空间中位于同一条直线上,那么它们在参数空间中对应的点将会相交于一个点,这个点即为该直线的参数(ρ,θ)。因此,通过统计参数空间中各点的交点数(即累加值),可以得到局部最大值点,从而确定图像中的直线。
圆检测的基本原理
圆检测参数空间变为三维,包括圆心坐标(x0,y0)和半径r。对于图像中的每一个点,可以绘制出经过该点的所有可能的圆,这些圆在参数空间(x0,y0,r)中对应一系列的点。如果多个点在图像空间中位于同一个圆上,那么它们在参数空间中对应的点将会相交于一个点,这个点即为该圆的参数。
圆形检测的实现
import cv2 # 导入OpenCV库,用于图像处理
import numpy as np # 导入NumPy库,用于处理数组和矩阵
# 读取图片
image = cv2.imread('img3.jpg') # 使用cv2.imread函数读取名为'img3.jpg'的图片
# 转换为灰度图
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 使用cv2.cvtColor函数将图片转换为灰度图
# 应用高斯模糊,减少图像噪声
gray_blurred = cv2.GaussianBlur(gray, (9, 9), 2, 2) # 使用cv2.GaussianBlur函数对灰度图应用高斯模糊
# 使用Hough圆变换检测圆形区域
circles = cv2.HoughCircles(gray_blurred, cv2.HOUGH_GRADIENT, dp=1, minDist=50,
param1=50, param2=30, minRadius=0, maxRadius=0) # 使用cv2.HoughCircles函数检测圆形区域
# 在原图上绘制圆形区域
if circles is not None: # 如果检测到了圆形区域
circles = np.uint16(np.around(circles)) # 对检测到的圆形区域进行四舍五入并转换为无符号16位整数
for i in circles[0, :]: # 遍历所有检测到的圆形区域
center = (i[0], i[1]) # 获取当前圆形的圆心坐标(这里获得了圆心的信息)
radius = i[2] # 获取当前圆形的半径
# 绘制圆心
cv2.circle(image, center, 1, (0, 100, 100), 3) # 在原图上绘制圆心
# 绘制圆轮廓
cv2.circle(image, center, radius, (255, 0, 255), 3) # 在原图上绘制圆轮廓
# 缩小图片尺寸
resized_image = cv2.resize(image, (0, 0), fx=0.5, fy=0.5) # 将处理后的图片缩小一半
resized_original = cv2.resize(cv2.imread('img3.jpg'), (0, 0), fx=0.5, fy=0.5) # 将原始图片缩小一半
# 显示原图和结果图
cv2.imshow('Original Image', resized_original) # 显示缩小后的原始图片
cv2.imshow('Detected Circles', resized_image) # 显示缩小后的处理图片(包含检测到的圆形)
cv2.waitKey(0) # 等待用户按键
cv2.destroyAllWindows() # 关闭所有窗口
# 使用Hough圆变换检测圆形区域
circles = cv2.HoughCircles(gray_blurred, cv2.HOUGH_GRADIENT, dp=1, minDist=50,
param1=50, param2=30, minRadius=0, maxRadius=0) # 使用cv2.HoughCircles函数检测圆形区域
1.gray_blurred
:这是要进行圆形检测的灰度图像,通常已经经过了模糊处理以减少噪声。
2.cv2.HOUGH_GRADIENT
:这是检测圆形所使用的方法。OpenCV 提供了几种不同的圆形检测方法,HOUGH_GRADIENT
是其中一种基于梯度的方法。
3.dp
:累加器分辨率与图像分辨率的反比。dp=1
时,累加器具有与输入图像相同的分辨率。dp=2
时,累加器具有输入图像一半大小的宽度和高度。
4.minDist
:检测到的圆的中心之间的最小距离。如果检测到的两个圆的中心太靠近,则只返回其中一个。
5.param1
:用于 Canny 边缘检测器的高阈值(低阈值是这个值的一半)。这个参数决定了边缘检测的灵敏度。
6.param2
:检测阶段累加器阈值。这个阈值用于决定一个圆是否足够“圆”。它越小,检测到的圆就越多(包括不规则的圆形);它越大,检测到的圆就越少,但检测结果会更加精确。
7.minRadius
:圆半径的最小大小。
8.maxRadius
:圆半径的最大大小。如果设置为 0,则函数会自动选择最大半径,这取决于图像的大小和其他参数。
注:本人为在校学生,博客是边学边写的,主要是为了巩固知识,如有错误请积极指正。
本文的内容主要基于我对张运楚教授编著的《数字图像处理》一书的学习和理解。这本书深入浅出地介绍了数字图像处理的基本理论以及经典算法等,并且提供了丰富的示例代码和实际用例,极大地帮助了我学习图像处理知识。在此,我推荐大家阅读这本书,更加深入的学习有关图像处理的知识。