霍夫变换检测圆形
一、霍夫变换基本原理
霍夫变换的核心思想是:将笛卡尔坐标系中的边缘像素点,映射到霍夫空间中,通过“投票机制”寻找局部最大值,从而提取出几何形状如直线、圆。
以最基础的直线检测为例:
1、在图像空间中,一条直线的方程可以写成极坐标形式: 。
2、图像空间中的一个点 代入上述方程后,在参数空间 中就变成了一条正弦曲线。
3、如果图像空间中有多个点共线,那么这多个点在参数空间中对应的多条正弦曲线,必然会相交于同一点。
4、算法会在参数空间中建立一个二维数组。曲线每经过一个点,该点的计数值加 1。最后寻找计数值最高的峰值点将其反代回图像空间,就得到了直线的方程。
二、检测圆形的基本原理
圆的解析方程为: ,其中有圆心坐标 (a,b) 和半径 𝑟。
当圆的半径 r 已知时,对于图像中通过边缘检测器(如Canny)提取出的每一个边缘点,由于r已知,它在参数空间(a,b)中对应的方程为: ,这在参数空间中也是一个圆,也就是说,图像空间中属于同一个真实圆的边缘点,它们在参数空间中画出的所有圆,都会相交于一点,这个交点就是真实圆的圆心。
当圆的半径 r 未知时,此时参数空间变成了三维 (a,b,r)。图像空间中的一个边缘点,在三维参数空间中对应的是一个圆锥面。计算所有边缘点的圆锥面相交点,计算量极其巨大,极其耗时。
为了解决计算量问题,MATLAB和OpenCV等图像库实际上使用的是优化的“霍夫梯度法”,分为两步:
找圆心: 对于图像上的每个边缘点,计算其梯度方向。几何学上,圆的法线一定经过圆心。因此,沿着边缘点的梯度方向在二维累加器中“画线”投票,这些线相交最多的地方就是圆心。
定半径: 找到圆心后,计算边缘图上的非零像素点到圆心的距离。出现频率最高的那几个距离,就被判定为该圆的半径。
三、代码示例
MATLAB 提供了内置函数 imfindcircles 来实现基于霍夫变换的圆检测。以下是一段可以直接运行的完整示例代码,使用了MATLAB自带的硬币图像:
% 使用 MATLAB 自带的测试图像 coins.png
I = imread('coins.png');
if size(I, 3) == 3
gray_img = rgb2gray(I);
else
gray_img = I;
end
% 观察硬币图,大致估算半径在 15 到 30 像素之间
Rmin = 15;
Rmax = 30;
% 使用霍夫变换(imfindcircles)寻找圆
% 'ObjectPolarity', 'bright':表示我们要找的圆(硬币)比背景亮
% 'Sensitivity':灵敏度(0到1),值越大越容易检测出圆,但设得太高容易产生误检(假圆)
[centers, radii, metric] = imfindcircles(gray_img, [Rmin Rmax], ...
'ObjectPolarity', 'bright', ...
'Sensitivity', 0.90);
% 可视化结果
figure;
imshow(I); % 显示原图
title('霍夫变换检测圆形结果');
hold on;
% 在原图上绘制检测到的圆边界(蓝色)
viscircles(centers, radii, 'EdgeColor', 'b');
% 在圆心位置画红色的十字
plot(centers(:,1), centers(:,2), 'r+', 'MarkerSize', 10, 'LineWidth', 2);
hold off;
更多推荐


所有评论(0)