具体参考官网:https://ww2.mathworks.cn/help/images/detect-and-measure-circular-objects-in-animage.html#DetectCirclesExample-6
笔记:在下面图像中的圆,有相对于图像背景色来说更暗的圆,也有相对于图像背景色来说更亮的圆,所以通过两次画轮廓的方式,先画出图像上相对于背景色更亮的圆的轮廓,再画出图像上相对于背景色更暗的圆的轮廓,并通过整'Sensitivity',
'EdgeThreshold'这两个参数,直到画出所有圆的轮廓。
1.imdistline:是一个交互式工具,用于确定图形上圆的半径范围,
creates a Distance tool with endpoints at the positions specified by h
= imdistline(___,x
,y
)x
and y
.,x,y,用于指定距离工具在图上的位置信息。例:h = imdistline(gca,[10 100],[10 100]);
2.delete(d)用于删除图像上的距离工具,但图像本身仍保留
3.寻找图像上圆的函数:imfindcircles,该函数返回在图像上找到的圆的中心和半径[centers,radii]
imfindcircles的参数:第一个是导入的图像,
第二个是指定圆的半径范围,
第三个是设置找到图像内相对于背景色更亮或者更暗的圆 ,分别表示为'ObjectPolarity','bright' 或者 'ObjectPolarity','dark'
第四个‘Method’,可设定为‘Method’,'TwoStage'或者‘Method’,'PhaseCode' 这个我没有弄懂是什么意思
第五个参数'Sensitivity'
— 敏感因子,默认设置为0.85,其范围在[0,1]之间,随着灵敏度系数的增加,imfindcircles会检测到更多的圆形对象,包括弱圆形和部分遮盖的圆形。 较高的灵敏度值也会增加错误检测的风险。
第六个参数'EdgeThreshold',范围在[0,1]之间,边缘梯度阈值设置用于确定图像中边缘像素的梯度阈值,指定为由'EdgeThreshold'和[0,1]范围内的数字组成的逗号分隔对。 指定0将阈值设置为零梯度幅度。 指定1以将阈值设置为最大梯度幅度。 将阈值设置为较低值时,imfindcircles会检测到更多的圆形对象(弱边缘和强边缘)。 当您增加阈值时,它会检测到边缘较弱的圆圈。 默认情况下,imfindcircles使用函数Graythresh自动选择边缘渐变阈值。
4.画图像上圆的轮廓:viscircles函数,需要输入通过上步得到的两个参数centers,radii,另外可以设置轮廓的颜色和线条样式,例如:'Color','b','LineStyle','--'
5.total_number即为图像上找到的圆的数量
代码如下:
rgb = imread(fullfile('D://','yuanpian.jpg'));
imshow(rgb)
d = imdistline;
delete(d)
[centers,radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','dark', ...
'Sensitivity',0.95);
viscircles(centers,radii);
[centersBright,radiiBright,metricBright] = imfindcircles(rgb,[20 25], ...
'ObjectPolarity','bright','Sensitivity',0.92,'EdgeThreshold',0.1);
hBright = viscircles(centersBright, radiiBright,'Color','b');
a=length(radii)
b=length(radiiBright)
total_number=a+b
结果图如下:
下面时自己检测一个图像中苹果数量的例子
rgb = imread(fullfile('D://','fuji.jpg'));
imshow(rgb)
d = imdistline(gca);
delete(d)
##用于显示图像的灰度图,查看苹果的颜色相对于背景色来说是更暗还是更亮
gray_image = rgb2gray(rgb);
imshow(gray_image)
[centersBright,radiiBright,metricBright] = imfindcircles(rgb,[55 90],'ObjectPolarity','dark','Method','TwoStage','Sensitivity',0.94,'EdgeThreshold',0.1);
hBright = viscircles(centersBright, radiiBright,'Color','b');
b=length(radiiBright)
total_number=b
效果如下