【问题标题】:Detect a circular shape inside image in MATLAB在 MATLAB 中检测图像内部的圆形
【发布时间】:2013-12-22 10:41:00
【问题描述】:

检测图像中这些圆形的最快方法是什么?

半径始终在(80-100mm)之间。背景总是白色的。并且圆圈将始终位于中心。

我已经尝试过Hough Transform,但我无法真正让它发挥作用。我对此很陌生,我觉得 Hough 变换 对此有点过头了。请建议我正确的方法来做到这一点。


更新

这是我应用霍夫变换后得到的结果。

我使用了here提到的算法。

以下是大算法的相关代码

% applying Hough Below
[accum, circen, cirrad] = ...
    CircularHough_Grd(gR, [89 93],...
    17.4, 13, 1);   % this executes in 0.72 sec

% Lets see what we got
imshow(gR);
hold on;
plot(circen(:,1), circen(:,2), 'r+');
for ii = 1 : size(circen, 1)
    rectangle('Position',[circen(ii,1) - cirrad(ii), circen(ii,2) - cirrad(ii), 2*cirrad(ii), 2*cirrad(ii)],...
        'Curvature', [1,1], 'edgecolor', 'b', 'linewidth', 1.5);
end
hold off;

有意义的圆圈是中间那个。

【问题讨论】:

  • 你能先展示你自己的尝试吗?

标签: matlab image-processing shape


【解决方案1】:

这是我的建议:
1. 转为灰度图,增强“白差”

gimg = min( img, [], 3 );


2.去除白色区域的阈值

BW = im2bw( gimg, .4 ); 


3. 获取图像区域的面积和质心属性

st = regionprops( ~BW, 'Area', 'Centroid', 'PixelIdxList' );

4。只选择足够大的区域

sel = [st.Area] > numel(BW)*0.025; % at least 2.5% of image size
st = st(sel);

5。计算区域到图像中心的距离

cntr = .5 * [size(BW,2) size(BW,1)]; % X-Y coordinates and NOT Row/Col
d = sqrt( sum( bsxfun(@minus,vertcat( st.Centroid ), cntr ).^2, 2 ) );

6。选择离中心最近的区域

[mn idx] = min(d);

7。创建蒙版

res = false(size(BW)); 
res( st(idx).PixelIdxList ) = true;

您还可以考虑使用其他区域属性(例如,'Eccentricity')来更好地拒绝非圆形区域。

【讨论】:

  • 为了更加确定你得到的是一个圆,你可以检查它的面积与它的最大半径的比率是否很高。
  • @Shai 这是$niper 射击。圈子不知道是什么打击了他们。它只需要 0.04 秒(与我正在做的霍夫变换相比太少了)!作为下一步,我将把白色不完美的圆圈包围在一个正方形内,并获得它的中心并近似一个更好的圆圈,然后使用该圆圈作为蒙版,然后尝试获得圆圈的颜色。这种方法对吗?还是有现成的方法可以做到这一点?
  • @wy - 看看regionprops 以及它可以为您提供什么。在我的代码中,您已经在'Centroid' 结构数组的'Centroid' 字段中找到了圆心。根据您需要的精度,您必须找到一种方法来估计圆的半径。如果它是您想要的颜色 - 那么您不需要估计一个圆 - 掩码 res 就是您所需要的:t = reshape( img, [], 3); c = mean( t(res,:), 1 ) 将为您提供掩码像素的平均颜色。
  • @Shai reshape( img, [], 3) 抛出 已知维度的乘积,3,不能整除元素总数,450800。 错误。我想我需要截断或填充 img 数组以使其大小可被 3 整除。
  • @wy 如果您的 color 图像的元素数量不能被 3 整除,那么这很奇怪:您应该有对应于 R、G 和 B 的第三维尺寸 3每个像素的分量。
【解决方案2】:

如果您的matlab版本是R2012a或更高版本,图像处理工具箱中包含函数imfindcircles,用于检测图像中的圆圈。

filen='http://i.stack.imgur.com/pmBp1.jpg';  % your original image
I=imread(filen);

I=im2bw(I(:,:,3));  % convert to gray scale
Rmin=50;Rmax=100;  % circle radius range
[centersDark, radiiDark] = imfindcircles(I, [Rmin Rmax], ...
                                        'ObjectPolarity','dark','sensitivity',0.93)
imagesc(I),hold on
viscircles(centersDark, radiiDark,'LineStyle','--');hold off

结果:

其实这个函数也应用了霍夫变换,我觉得和你的差不多。您可能需要注意的一件事是,Hough 中与灵敏度对应的阈值对检测结果有很大影响。过高的灵敏度会导致检测到更多的圆圈,包括较弱或部分被遮挡的圆圈,有较高的误检率风险,而这正是您所获得的。

【讨论】:

  • 这有点矫枉过正。请参阅 wy 的 comment 运行时间。
  • @lennon310 我有 R2010a。我可以获得imfindcircles 来发布我的版本吗?这个脚本需要多长时间才能得到圈子?
  • 它应该包含在图像处理工具箱中。我需要 ~0.7s 来实现 imfindcircles,而 ~0.05s 来实现 regionprops。所以如果你有大量的图片要处理,速度可能会慢很多。
猜你喜欢
  • 1970-01-01
  • 2015-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-24
  • 1970-01-01
相关资源
最近更新 更多