Hough变换实例 很清晰的

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

数字图像处理第八次作业

实验内容

1、拍摄一张包含硬币、橡皮等物品的照片,通过Hough 变换检测出圆形的硬币个数并区分不同半径的硬币。最终计算出照片中的总钱数。

解:Hough 变换的实质是对图像进行坐标的变换,将图像空间的线条变为参数空间的聚集点,从而将原始图像中检测给定形状的曲线问题,变成寻找参数空间中的峰点的问题。

它不仅可以检测直线,而且可以很方便地检测圆、椭圆和抛物线等形状。由于这里需要检测圆形的硬币,所以下面给出检测圆的具体方法:

因为圆的图像空间方程为:222()()x a y b r -+-=,

我们需要通过Hough 变换,将图像空间(,)x y 对应到参数空间(,,)a b r ,然后对其进行累加完成检测。但是显然这种方法的计算量是非常大的,所以一般都是先对灰度图像进行边缘提取,利用边界像素的灰度梯度信息估计出下式中的角度θ,以此来降低计算量:

cos cos a x r b y r θ

θ=-*⎧⎨=-*⎩ (1)

一般在检测过程中需要对图像进行预处理,使得检测更加准确和容易。检测过程如下所示:

1真彩色图像转为灰度图像; ○

2去除噪声,进行中值滤波; ○

3转为二值图像,利用边缘算子进行图像边缘提取; ○

4最后进行图像的平滑和填充。 这里处理的图像并没有太多噪声,所以处理的时候略去了中值滤波的步骤,直接对边缘提取后的图像进行Hough 变换检测圆形。

根据式(1),我们需要对半径r 和角度θ进行搜索,所以这里应该首先设置半径和角度方向的搜索步长step_r 和step_angle ,接着给出半径搜索的最大和最小值,当然这两个数值需要根据经验来自己确定。最后就可以根据这些确定半径和角度的最大搜索次数。

由于Hough变换需要用到稀疏矩阵,也即首先得找到图像矩阵中的非零量,针对这些非零量进行进一步的处理。这个操作可以直接通过Matlab中的find语句来实现:

>> [rows, cols] = find(BW); %找出矩阵中的非零值

接着只需要根据式(1)计算出对应参数空间的参数a b

和,根据,a b的范围确定hough空间累加器hough_adder是否自增。

由于这里的图像中不止一个圆形,所以不能直接利用hough_adder中的最大值来确定半径,需要设置一定的阈值thre来确定一定半径的圆,当阈值设置合理后才可以找出图像中的圆。接着对阈值范围内的点进行搜索,当满足圆周内外各5个像素点时,该点可以认为是我们搜寻的圆上的点。对其相应的坐标赋1即可。

经过上述的步骤,便通过hough变换的思想将图像的中的圆给检测出来了。并且可以将圆心坐标和圆的半径都显示出来。

那接下来按照题目的意思是需要我们计算总的钱数,所以首先需要区分一元和五角的硬币,也就是区分圆的半径。由于这里我们设置搜索出来的圆的半径是逐渐递增的,所以只需要判断在两个相邻点之间圆的半径是否存在跳变即可。因为如果是不同的一元硬币,那么他们的半径即使相差一点也不会很多。这样我们便可以得出首先将圆分成两类(这里只考虑一元和五角的两种情况),然后在每一类中再寻找半径相似的圆位于不同坐标的个数,也就是同样面值的硬币的个数了。

可以通过如下代码实现:

从以上代码我们可以看出,这里只要当相邻两个半径相差超过5即可认定为

是不同的硬币了。

接着在相同的硬币中,通过循环搜索当前半径和之前像素点的半径,当横纵坐标相差都小于10的时候可以认为是同一个点,也即是同一个硬币,否则将硬币数加一。

最后通过统计得到的总硬币数计算出总钱数。

下面先给出具体代码:

clc,clear all

Image = imread('final.bmp');

imshow(Image),title('原始图像');

Gray = rgb2gray(Image);

bw = im2bw(Gray); % 先转为二值图像

BW = edge(bw); % 然后提取边缘

figure

imshow(BW),title('图像边缘);

step_r = 1; % 设定半径搜索步长

step_angle = 0.1; % 设定角度搜索步长

r_min = 50; % 最小半径和最大半径,确定搜索范围

r_max = 100;

thre = 0.8; % 设定阈值

%***************hough变换*********************************

[m, n] = size(BW);

Count_r = round((r_max-r_min)/step_r)+1; % °半径最大搜索次数

hough_adder = zeros(m, n, Count_r);

Count_angle = round(2*pi/step_angle); % 角度最大搜索次数

[rows, cols] = find(BW); % 找出矩阵中的非零值

count = size(rows); % 计算非零值的个数

for Count_Num = 1 : count

for Count_R = 1 : Count_r

for Count_Angle = 1 : Count_angle

a =

round(rows(Count_Num)-(r_min+(Count_R-1)*step_r)*cos(Count_Angle*step_angle ));

b =

round(cols(Count_Num)-(r_min+(Count_R-1)*step_r)*sin(Count_Angle*step_angle) );

isTrue = (a>0 && a<=m && b>0 && b<=n);

if(isTrue)

hough_adder(a,b,Count_R) = hough_adder(a,b,Count_R) + 1;

% 参数空间累加器加1

end

end

相关文档
最新文档