此示例显示如何在图像中自动检测圆圈或圆形对象并可视化检测到的圆圈。
阅读并显示各种颜色的圆形塑料芯片的图像。除了有足够的圈子来检测,来自圆形检测点的此图像中有一些有趣的事情发生:
有不同颜色的芯片,这对背景具有不同的对比。在一端,蓝色和红色的在这个背景上具有强烈的对比。另一端,一些黄色芯片与背景上没有鲜明。
请注意一些筹码如何彼此顶部,其他一些靠近在一起,几乎互相触摸的其他芯片。重叠的对象边界和对象遮挡通常是对象检测的具有挑战性的场景。
rgb = imread('Comingchips.png');imshow(RGB)
使用圆圈找到适当的半径范围draw
功能。在芯片的近似直径上绘制一条线。
d =窗口;
线路ROI的长度是芯片的直径。典型的芯片在40到50像素的范围内具有直径。
pos = d.Position;diffpos = diff(pos);直径=射频(差异(1),差别(2))
直径= 45.3448
这imfindcircles.
功能搜索带有一系列半径的圆圈。在20至25个像素的范围内搜索带半径的圆圈。在此之前,询问这些物体是否比背景更亮或较暗。要回答这个问题,请查看此图像的灰度版本。
gray_image = rgb2gray(RGB);imshow(gray_image)
背景非常明亮,大部分芯片比背景更暗。但是,默认情况下,imfindcircles.
找到比背景更亮的圆形物体。所以,将参数“objorpolarity”设置为“黑暗”imfindcircles.
寻找黑眼圈。
[中心,半径] = Imfindcircles(RGB,[2025],'objectpolarity'那'黑暗的')
中心= [] radii = []
请注意输出中心
和radii.
是空的,这意味着没有找到圈子。这经常发生,因为imfindcircles.
是一个圆圈探测器,和类似于大多数探测器,imfindcircles.
有一个内部检测阈值这决定了它的敏感性。简单来说,它意味着检测器对某个(圆圈)检测的置信度必须大于某个级别之前被认为是一个有效的检测。imfindcircles.
具有参数的“灵敏度”,可用于控制该内部阈值,从而使用算法的灵敏度。更高的“灵敏度”值设置检测阈值下降并导致检测更多圆圈。这类似于家庭安全系统中使用的运动检测器上的灵敏度控制。
回到芯片图像,可以在默认的灵敏度级别,所有圆的均值低于内部阈值,这就是为什么没有检测到圆圈的原因。默认情况下,“灵敏度”为0到1之间的数字,设置为0.85。将“敏感性”提高到0.9。
[中心,半径] = Imfindcircles(RGB,[2025],'objectpolarity'那'黑暗的'那......'灵敏度',0.9)
中心=8×2146.1895 198.5824 328.8132 135.5883 130.3134 43.8039 175.2698 297.0583 312.2831 192.3709 327.1316 297.0077 297.0077 243.97/323.9893 166.4538 271166。4538 297166/2538 297197731229939709929920990
radii =8×123.1604 22.5710 22.9576 23.7356 22.9551 22.9995 22.9055 23.0298
这次imfindcircles.
发现一些圆圈 - 八个精确。中心
包含圆形中心的位置和radii.
包含这些圆圈的估计半径。
功能viscircles.
可用于在图像上绘制圆圈。输出变量中心
和radii.
从imfindcircles.
可以直接传递给viscircles.
。
imshow(RGB)H = Viscircles(中心,半径);
圆形中心似乎正确定位,它们的相应的半径似乎与实际芯片相匹配。但仍有很多筹码被遗漏了。尝试将“敏感性”提高到0.92。
[中心,半径] = Imfindcircles(RGB,[2025],'objectpolarity'那'黑暗的'那......'灵敏度',0.92);长度(中心)
ans = 16.
所以增加“敏感性”让我们更加圆圈。再次在图像上绘制这些圆圈。
删除(h)%删除先前绘制的圆圈H = Viscircles(中心,半径);
这个结果看起来更好。imfindcircles.
有两种不同的寻找圆圈的方法。到目前为止默认方法,称为阶段编码方法,用于检测圆圈。有另一种方法,普遍称为两阶段方法,可用的方法imfindcircles.
。使用两阶段方法并显示结果。
[中心,半径] = Imfindcircles(RGB,[2025],'objectpolarity'那'黑暗的'那......'灵敏度',0.92,'方法'那'扭曲');删除(h)h = Viscircles(中心,半径);
两级方法在0.92的灵敏度下检测更多圆圈。通常,这两种方法是互补的,它们具有不同的优点。相位编码方法通常比两级方法更快,更易于稳健。但它也可能需要更高的“敏感性”水平来获得与两级方法相同的检测。例如,相位编码方法如果“灵敏度”级别提高,则发现相同的芯片,如0.95。
[中心,半径] = Imfindcircles(RGB,[2025],'objectpolarity'那'黑暗的'那......'灵敏度',0.95);删除(H)Viscircles(中心,半径);
请注意,两种方法都在imfindcircles.
精确地找到部分可见(闭塞)芯片的中心和半径。
看着最后的结果,很好奇imfindcircles.
找不到图像中的黄色芯片。黄色芯片与背景没有强烈对比。事实上,他们似乎具有非常相似的强度作为背景。如假设的背景,黄色芯片是否有可能比背景“更深”吗?要确认,请再次显示此图像的灰度版本。
imshow(gray_image)
与背景相比,黄色芯片几乎是相同的强度,甚至可以更亮。因此,要检测黄色芯片,将“象根性”变为“光明”。
[Centsbright,Radiibright] = IMFindcircles(RGB,[20 25],......'objectpolarity'那'明亮的'那'灵敏度',0.92);
画出明亮的通过改变“颜色”参数,以不同颜色的圆圈viscircles.
。
imshow(rgb)hbright = Viscircles(Centsbright,Radiibright,'颜色'那'B');
请注意,发现了三个缺少的黄色芯片,但仍缺少一个黄色芯片。这些黄色芯片很难找到,因为他们没有站出来以及这个背景上的其他人。
还有另一个参数imfindcircles.
这里可能有用,即'Edgethreshold'。找到圈子,imfindcircles.
仅使用图像中的边缘像素。这些边缘像素基本上是具有高梯度值的像素。'edgethreshold'参数控制如何高的在其被认为是边缘像素并包括在计算之前,必须在图中的梯度值。该参数的高值(更接近1)将仅允许包括强边(较高梯度值),而低值(更靠近0)是更允许的,并且甚至包括较弱的边缘(较低梯度值)计算。在缺少黄色芯片的情况下,由于对比度低,因此预期一些边界像素(在芯片的圆周上)具有低梯度值。因此,降低“EDGETHRESHOLD”参数以确保黄色芯片的大多数边缘像素包括在计算中。
[Centsbright,Radiibright,Metricbright] = IMFindcircles(RGB,[20 25],......'objectpolarity'那'明亮的'那'灵敏度',0.92,'edgethreshold',0.1);删除(HBRIGHT)HBRIGHT = VISCIRCLES(CENTERSBRIGHT,RADIIBRIGHT,'颜色'那'B');
现在imfindcircles.
找到所有的黄色,也是一个绿色的。用早期发现的其他芯片绘制蓝色的这些芯片(用'objectpolarity'设置为'黑暗'),红色。
H = Viscircles(中心,半径);
所有圆圈都被检测到。最后一个词 - 应该注意的是,在检测中改变参数更具侵略性可能会找到更多圆圈,但它也增加了检测假圆的可能性。在可以找到(检测率)的真圆数之间存在权衡,以及与它们一起发现的虚假圆数(误报率)。
幸福的圈狩猎!