此示例说明如何自动检测图像中的圆形目标并可视化检测到的圆。

步骤 1:加载图像
读取并显示包含各种颜色的圆形塑料片的图像。除了有大量要检测的圆之外,从圆检测的角度来看,此图像还有一些有趣的特点:

有不同颜色的塑料片,它们相对于背景有不同对比度。一方面,蓝色和红色塑料片在此背景上形成强烈的对比。另一方面,一些黄色塑料片与背景的对比不明显。

请注意一些塑料片重叠在一起,而另一些塑料片则靠得很近,几乎互相接触。对于目标检测来说,场景中存在重叠的对象边缘和对象遮挡通常具有挑战性。

rgb = imread('coloredChips.png');    %加载图像
imshow(rgb);
title('coloredChips');

步骤 2:确定搜索圆的半径范围
使用 drawline 函数找到合适的圆半径范围。在塑料片的近似直径上绘制一条线。

rgb = imread('coloredChips.png');    %加载图像
imshow(rgb);
title('coloredChips');
d = drawline;         %使用 drawline 函数找到合适的圆半径范围
pos = d.Position;
diffPos = diff(pos);
diameter = hypot(diffPos(1),diffPos(2));

步骤 3:寻找圆的初步尝试
imfindcircles 函数搜索符合半径范围的圆。搜索半径在 20 到 25 个像素范围内的圆。在此之前,最好要清楚对象是比背景亮还是比背景暗。要回答该问题,请看此图像的灰度版本。

rgb = imread('coloredChips.png');    %加载图像
subplot(1,2,1);
imshow(rgb);
title('coloredChips');
%d = drawline;         %使用 drawline 函数找到合适的圆半径范围
% pos = d.Position;
% diffPos = diff(pos);
% diameter = hypot(diffPos(1),diffPos(2));
gray_image = rgb2gray(rgb);        %转为灰度图像
subplot(1,2,2);
imshow(gray_image);                %显示灰度图像
title('coloredChips灰度图');


背景相当亮,大多数塑料片比背景暗。但是,默认情况下,imfindcircles 会找到比背景亮的圆形目标。因此,在 imfindcircles 中将参数 ‘ObjectPolarity’ 设置为 ‘dark’ 以搜索较暗的圆。

>> [centers,radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','dark')   %在 imfindcircles 中将参数 'ObjectPolarity' 设置为 'dark' 以搜索较暗的圆centers =[]radii =[]

请注意,输出 centers 和 radii 为空,这意味着未找到圆。这种情况经常发生,因为 imfindcircles 是圆形检测器,与大多数检测器类似,imfindcircles 有内部检测阈值决定其敏感度。简而言之,这意味着检测器对某个(圆形)检测的信心必须大于某个水平,才将其视为有效检测。imfindcircles 有参数 ‘Sensitivity’,可用于控制此内部阈值,从而控制算法的敏感度。较高的 ‘Sensitivity’ 值会将检测阈值设置得较低,并导致检测到更多圆。这类似于家庭安全系统中使用的运动检测器的敏感度控制。

步骤 4:提高检测敏感度
回到塑料片图像,在默认敏感度水平下,可能所有圆都低于内部阈值,因此未检测到圆。‘Sensitivity’ 是介于 0 和 1 之间的数字,默认设置为 0.85。将 ‘Sensitivity’ 提高到 0.9。

>> [centers,radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','dark', 'Sensitivity',0.9)    %将 'Sensitivity' 设置为 0.9centers =146.1895  198.5824328.8132  135.5883130.3134   43.8039175.2698  297.0583312.2831  192.3709327.1316  297.0077243.9893  166.4538271.5873  280.8920radii =23.160422.571022.957623.735622.955122.999522.905523.0298

这次,imfindcircles 发现了一些圆 - 准确地说是八个centers 包含圆心的位置,radii 包含这些圆的估计半径。

步骤 5:在图像上绘制圆
函数 viscircles 可用于在图像上绘制圆。来自 imfindcircles 的输出变量 centers 和 radii 可以直接传递给 viscircles。

rgb = imread('coloredChips.png');    %加载图像
subplot(2,2,1);
imshow(rgb);
title('coloredChips');[centers,radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','dark', 'Sensitivity',0.9);
subplot(2,2,2);
imshow(rgb);
h = viscircles(centers,radii);           %在图像上绘制灵敏度为0.9时找到的圆
title('灵敏度为0.9时找到的圆');
a1 = length(centers)       %计算找到绘制灵敏度为0.9时的圆的个数[centers,radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','dark', 'Sensitivity',0.92);
subplot(2,2,3);
imshow(rgb);
h = viscircles(centers,radii);           %在图像上绘制灵敏度为0.92时找到的圆
title('灵敏度为0.92时找到的圆');
a2 = length(centers)        %计算找到绘制灵敏度为0.92时的圆的个数[centers,radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','dark', 'Sensitivity',0.95);
subplot(2,2,4);
imshow(rgb);
h = viscircles(centers,radii);           %在图像上绘制灵敏度为0.95时找到的圆
title('灵敏度为0.95时找到的圆');
a3 = length(centers)         %计算找到绘制灵敏度为0.95时的圆的个数%计算结果
a1 =8a2 =16a3 =22


步骤 6:使用第二种方法(两阶段)寻找圆
此方法的结果看起来更好。imfindcircles 有两种不同寻找圆的方法。到当前为止,默认方法(称为相位编码方法)用于检测圆。在 imfindcircles 中还可以使用另一种方法,通常称为两阶段方法。使用两阶段方法并显示结果。

rgb = imread('coloredChips.png');    %加载图像
subplot(2,2,1);
[centers,radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','dark', 'Sensitivity',0.9);
imshow(rgb);
h = viscircles(centers,radii);           %用相位编码方法在图像上绘制灵敏度为0.9时找到的圆
title('相位编码方法:灵敏度为0.9时找到的圆');
a1 = length(centers)       %计算相位编码方法找到绘制灵敏度为0.9时的圆的个数subplot(2,2,2);
[centers,radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','dark', 'Sensitivity',0.9,'Method','twostage');
imshow(rgb);
h = viscircles(centers,radii);           %用两阶段方法在图像上绘制灵敏度为0.9时找到的圆
title('两阶段方法:灵敏度为0.9时找到的圆');
a2 = length(centers)       %计算两阶段方法找到绘制灵敏度为0.9时的圆的个数subplot(2,2,3);
[centers,radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','dark', 'Sensitivity',0.92);
imshow(rgb);
h = viscircles(centers,radii);           %用相位编码方法在图像上绘制灵敏度为0.92时找到的圆
title('相位编码方法:灵敏度为0.92时找到的圆');
a3 = length(centers)       %计算相位编码方法找到绘制灵敏度为0.92时的圆的个数subplot(2,2,4);
[centers,radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','dark', 'Sensitivity',0.92,'Method','twostage');
imshow(rgb);
h = viscircles(centers,radii);           %用两阶段方法在图像上绘制灵敏度为0.92时找到的圆
title('两阶段方法:灵敏度为0.92时找到的圆');
a4 = length(centers)       %计算两阶段方法找到绘制灵敏度为0.92时的圆的个数!%统计结果
a1 =8     %相位编码方法找到绘制灵敏度为0.9时的圆的个数为8个a2 =22    %两阶段方法找到绘制灵敏度为0.9时的圆的个数为22个a3 =16    %相位编码方法找到绘制灵敏度为0.92时的圆的个数为16个a4 =22   %两阶段方法找到绘制灵敏度为0.92时的圆的个数为22个


两阶段方法使用敏感度0.9和 0.92 检测更多圆。一般来说,这两种方法是互补的,因为它们有不同优点。相位编码方法通常比两阶段方法更快,抗噪声的稳定性稍强。但是,它也可能需要更高的 ‘Sensitivity’ 水平才能实现与两阶段方法相同数量的检测。例如,如果 ‘Sensitivity’ 水平提高到 0.95,相位编码方法也会找到相同的塑料片。

rgb = imread('coloredChips.png');    %加载图像
subplot(1,2,1);
[centers,radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','dark', 'Sensitivity',0.95);
imshow(rgb);
h = viscircles(centers,radii);           %用相位编码方法在图像上绘制灵敏度为0.95时找到的圆
title('相位编码方法:灵敏度为0.95时找到的圆');
a1 = length(centers)       %计算相位编码方法找到绘制灵敏度为0.95时的圆的个数subplot(1,2,2);
[centers,radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','dark', 'Sensitivity',0.95,'Method','twostage');
imshow(rgb);
h = viscircles(centers,radii);           %用两阶段方法在图像上绘制灵敏度为0.95时找到的圆
title('两阶段方法:灵敏度为0.95时找到的圆');
a2 = length(centers)       %计算两阶段方法找到绘制灵敏度为0.95时的圆的个数%统计结果
a1 =22   %相位编码方法找到绘制灵敏度为0.95时的圆的个数为22个a2 =22    %两阶段方法找到绘制灵敏度为0.95时的圆的个数为22个


请注意,imfindcircles 中的两种方法都能准确找到部分可见(遮挡)塑料片的中心和半径。

步骤 7:为什么有些圆仍检测不到?
查看最后一个结果,很奇怪 imfindcircles 没有在图像中找到黄色塑料片。黄色塑料片与背景的对比不够强烈。事实上,它们看起来和背景的强度非常相似。是不是黄色塑料片并没有想象中的那样比背景“更暗”?要确认这一点,请再次显示该图像的灰度版本。

步骤 8:在图像中找到“明亮”的圆
查看图像的灰度图,可发现与背景相比,黄色塑料片的强度几乎相同,甚至更亮。因此,要检测黄色塑料片,请将 ‘ObjectPolarity’ 更改为 ‘bright’。

rgb = imread('coloredChips.png');    %加载图像
subplot(1,2,1);
[centers,radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','bright', 'Sensitivity',0.92);
imshow(rgb);
h = viscircles(centers,radii);           %用相位编码方法在图像上绘制灵敏度为0.92时找到的圆
title('相位编码方法:灵敏度为0.92时找到的圆');
a1 = length(centers)       %计算相位编码方法找到绘制灵敏度为0.92时的圆的个数subplot(1,2,2);
[centers,radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','bright', 'Sensitivity',0.92,'Method','twostage');
imshow(rgb);
h = viscircles(centers,radii);           %用两阶段方法在图像上绘制灵敏度为0.92时找到的圆
title('两阶段方法:灵敏度为0.92时找到的圆');
a2 = length(centers)       %计算两阶段方法找到绘制灵敏度为0.92时的圆的个数%统计结果
a1 =3a2 =5


步骤 9:用不同颜色绘制 ‘Bright’ 圆
通过更改 viscircles 中的 ‘Color’ 参数,以不同颜色绘制明亮的圆。

h = viscircles(centers,radii,'Color','b');   %将上面程序中的代码改为此代码即可


请注意,找到了三个原先未检测到的黄色塑料片,但仍有黄色塑料片未检测到。这些黄色塑料片很难检测到,因为在这种背景下,它们没有呈现出与众不同。

步骤 10:降低 ‘EdgeThreshold’ 的值
在这里还可以使用 imfindcircles 中的另一个参数,即 ‘EdgeThreshold’。要查找圆,imfindcircles 仅使用图像中的边缘像素。这些边缘像素基本上是具有高梯度值的像素。‘EdgeThreshold’ 参数控制像素的梯度值必须有多高,才能将其视为边缘像素并包含在计算中。该参数的高值(更接近 1)只允许包含强边缘(较高梯度值),而低值(更接近 0)的宽容度更高,可在计算中包含较弱的边缘(较低梯度值)。对于检测不到黄色塑料片的情况,是因为对比度低,一些边界像素(在塑料片的圆周上)预期具有低梯度值。因此,请降低 ‘EdgeThreshold’ 参数,以确保黄色塑料片的大多数边缘像素都包含在计算中。

rgb = imread('coloredChips.png');    %加载图像
subplot(1,2,1);
[centers,radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','bright', 'Sensitivity',0.92,'EdgeThreshold',0.1);
imshow(rgb);
h = viscircles(centers,radii,'Color','b');           %用相位编码方法在图像上绘制灵敏度为0.92时找到的圆
title('相位编码方法:灵敏度为0.92时找到的圆');
a1 = length(centers)       %计算相位编码方法找到绘制灵敏度为0.92时的圆的个数subplot(1,2,2);
[centers,radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','bright', 'Sensitivity',0.92,'Method','twostage','EdgeThreshold',0.1);
imshow(rgb);
h = viscircles(centers,radii,'Color','b');           %用两阶段方法在图像上绘制灵敏度为0.92时找到的圆
title('两阶段方法:灵敏度为0.92时找到的圆');
a2 = length(centers)       %计算两阶段方法找到绘制灵敏度为0.92时的圆的个数%统计结果
a1 =5a2 =6


步骤 11:同时绘制“暗”和“亮”圆
现在 imfindcircles 找到了所有黄色圆,还找到了一个绿色圆。用蓝色绘制这些塑料片,用红色绘制之前发现的其他塑料片(‘ObjectPolarity’ 设置为 ‘dark’)。

用相位编码法找到的所有圆

**

rgb = imread('coloredChips.png');    %加载图像
%subplot(2,2,1);
[centers,radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','bright', 'Sensitivity',0.92);
imshow(rgb);
h = viscircles(centers,radii,'color','b');           %用相位编码方法在图像上绘制灵敏度为0.92时找到"亮"圆
title('相位编码方法:灵敏度为0.92时找到的圆');
[centers,radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','dark', 'Sensitivity',0.92);
h = viscircles(centers,radii);         %找到"暗"圆
a1 = length(centers)       %计算相位编码方法找到绘制灵敏度为0.92时的圆的个数%统计个数
a1 =16

用两阶段法找到的圆

rgb = imread('coloredChips.png');    %加载图像
%subplot(2,2,1);
[centers,radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','bright', 'Sensitivity',0.92,'Method','twostage');
imshow(rgb);
h = viscircles(centers,radii,'color','b');           %用两阶段方法在图像上绘制灵敏度为0.92时找到"明"圆
title('两阶段方法:灵敏度为0.92时找到的圆');
[centers,radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','dark', 'Sensitivity',0.92,'Method','twostage');
h = viscircles(centers,radii);         %找到"暗"圆
a2 = length(centers)       %计算两阶段方法找到绘制灵敏度为0.92时的圆的个数%统计结果
a2 = 22

1.2 检测和测量图像中的圆形目标相关推荐

  1. 计算机视觉与深度学习 | 检测和测量图像中的圆形目标(数钢筋)

    ================================================ 博主github:https://github.com/MichaelBeechan 博主CSDN:h ...

  2. matlab——识别图像中的圆形目标

    文章目录 说明 Figure 1 imread函数 imshow函数 Figure 2 rgb2gray函数 graythresh函数 im2bw函数 figure函数 Figure 3 bwarea ...

  3. 自动检测图像中的圆形或圆形对象

    文章目录 加载图像 确定搜索圈的半径范围 初步尝试查找圆形 提高检测灵敏度 在图像上绘制圆圈 使用第二种方法(两阶段)寻找圆圈 为什么有些圈子仍然被错过? 在图像中找到"明亮"的圆 ...

  4. 使用OpenCV测量图像中物体的大小

    本文翻译自pyimagesearch技术博客上的一篇文章,<Measuring size of objects in an image with OpenCV>,原文作者:Adrian R ...

  5. Python+opencv 机器视觉 - 基于霍夫圈变换算法检测图像中的圆形实例演示

    Python+opencv 机器视觉 - 基于霍夫圈变换算法检测图像中的圆形实例演示 第一章:霍夫变换检测圆 ① 实例演示1 ② 实例演示2 ③ 霍夫变换函数解析 第二章:Python + openc ...

  6. python图像计数_检测并计数图像中的对象

    我试图用python编写一个脚本来检测和计算图像中的对象,但我失败得很惨.在 这是我第一次对计算机视觉感兴趣并尝试一些东西.我已经尝试过使用cv2模块(opencv),遵循关于特征匹配和模板匹配的教程 ...

  7. 遥感图像中的小样本目标检测:Few-shot Object Detection on Remote SensingImages

    论文下载:https://arxiv.org/pdf/2006.07826v2.pdf Abstract 在本文中,我们处理遥感图像上的目标检测问题.以前的方法已经发展了许多基于深度卷积的遥感图像目标 ...

  8. MATLAB#183;提取图像中多个目标

    基于matlab工具箱提取图像中的多目标特征(代码如下): 代码前面部分为提取图像的边界信息,调用了后面的遍历函数Pixel_Search,函数实现方法见后~ %%ROI Testing close ...

  9. C#使用OpenCV剪切图像中的圆形和矩形

    前言 本文主要介绍如何使用OpenCV剪切图像中的圆形和矩形. 准备工作 首先创建一个Wpf项目--WpfOpenCV,这里版本使用Framework4.7.2. 然后使用Nuget搜索[Emgu.C ...

最新文章

  1. XXL-JOB v2.0.1 发布,分布式任务调度平台
  2. 基本概念之dos和cmd的区别
  3. Ubuntu14.04下Neo4j图数据库官网安装部署步骤(图文详解)(博主推荐)
  4. leetcode 792. Number of Matching Subsequences | 792. 匹配子序列的单词数(Java)
  5. vs2008安装_Visual Studio2008安装教程
  6. 阅读gulp源码小结
  7. Druid 不仅仅是一个数据库连接池
  8. CSDN 的 Markdown 编辑器语法
  9. Java ee和Java se的区别
  10. Kindle Paperwhite3入手20天感受
  11. android仿qq聊天界面版带表情、相册、照相
  12. 三分钟教会你微信炸一炸,满屏粑粑也太可爱了!
  13. MySQL 三个排序方法 row_number()、rank()、dense_rank()
  14. Python+PyCharm+PyTorch+Cuda/GPU 安装步骤
  15. 让CEF支持HEVC(H.265)视频播放
  16. 2021,前端月薪30K已是白菜价?
  17. iPhone上实现流媒体播放器
  18. OpenCV | Mat类的copyT、clone、=赋值的区别
  19. mysql 游戏背包_MySQL实战技能包
  20. 5000英镑就可买到控制美国核武库的同款IBM电脑

热门文章

  1. CAD—定义委托异步添加实体
  2. 我眼中的Linux设备树(四 中断)
  3. 基于FT5x06嵌入式Linux电容触摸屏驱动
  4. 如何办理夫妻间的房屋产权转移手续?
  5. IBM发表论文:可能已找到处理量子计算退相干的方法
  6. 第十六章--访问文件
  7. PLSQL_统计信息系列10_统计信息过旧导致程序出现性能问题
  8. Linux系统安全工具之NMAP
  9. python 批量下载文件
  10. Java操作XML文件 dom4j 篇【转】