- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
PAGE
PAGE 1
实验内容
1.拍摄一张包含硬币、橡皮等物品的照片,通过 Hough 变换检测出圆形的硬币个数并区分不同半径的硬币。最终计算出照片中的总钱数。
解:Hough 变换的实质是对图像进行坐标的变换,将图像空间的线条变为参数空间的聚集点,从而将原始图像中检测给定形状的曲线问题,变成寻找参数空间中的峰点的问题。
它不仅可以检测直线,而且可以很方便地检测圆、椭圆和抛物线等形状。由于这里需要检测圆形的硬币,所以下面给出检测圆的具体方法:
因为圆的图像空间方程为:(x ? a)2 ? ( y ? b)2 ? r 2 ,我们需要通过 Hough 变换,
将图像空间( x, y) 对应到参数空间(a, b, r) ,然后对其进行累加完成检测。但是显
然这种方法的计算量是非常大的,所以一般都是先对灰度图像进行边缘提取,利用边界像素的灰度梯度信息估计出下式中的角度? ,以此来降低计算量:
??a ? x ? r ?cos?
?
? ……(1)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 变换的思想将图像的中的圆给检测出来了。并且可以将圆心坐标和圆的半径都显示出来。
那接下来按照题目的意思是需要我们计算总的钱数,所以首先需要区分一元和五角的硬币,也就是区分圆的半径。由于这里我们设置搜索出来的圆的半径是逐渐递增的,所以只需要判断在两个相邻点之间圆的半径是否存在跳变即可。因为如果是不同的一元硬币,那么他们的半径即使相差一点也不会很多。这样我们便可以得出首先将圆分成两类(这里只考虑一元和五角的两种情况),然后在每一类中再寻找半径相似的圆位于不同坐标的个数,也就是同样面值的硬币的个数了。
可以通过如下代码实现:
total_wu
total_wu = 0;
for idx = 1 : length-1
total_wu = total_wu + para(3,idx); if (para(3,idx+1) - para(3,idx) 5)
break;
end
end
total_yi = sum(para(3,:)) - total_wu; Ave_wu = total_wu / idx;
Ave_yi = total_yi / (length(1,1)-idx);
从以上代码我们可以看出,这里只要当相邻两个半径相差超过 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; % 设
文档评论(0)