【问题标题】:How does Matlab calculate the perimeter using regionprops of a rectangular pictureMatlab如何使用矩形图片的regionprops计算周长
【发布时间】:2018-11-09 06:00:35
【问题描述】:

我想计算一个“几乎”圆形(或椭圆形)物体的周长。我用了两种方式:

第一种方法:

stats = regionprops('table',bw,'Centroid',...
'MajorAxisLength','MinorAxisLength','Perimeter');
perimeter_matlab=stats.Perimeter; %get the perimeter using matlab regionprops

第二种方法:

stats2 = regionprops(L,'Area','Centroid');

for k = 1:length(B)
    % obtain (X,Y) boundary coordinates corresponding to label 'k'
    boundary = B{k};

    %get the perimeter by calculating the each pixel to pixel distance in boundary and add the discret distand together
    delta_sq = diff(boundary).^2;
    perimeter_pixel= sum(sqrt(sum(delta_sq,2)));
end

结果:

当我使用像 900*600 像素这样的矩形对象时,它的周长应该是 900*2+598*2=2996 但是 perimeter_matlab=2935.7 为什么会出错? perimeter_pixel = 2996 是正确的。

当我使用半径为50 像素(直径为101)且其周长应为2*pi*50=314.1593 的圆时 perimeter_matlab=313.904 接近答案,但是 perimeter_pixel = 332.0488为什么会出错?

Matlab 如何计算perimeter

【问题讨论】:

    标签: matlab image-processing


    【解决方案1】:

    我不知道 MATLAB 使用什么算法,但我可以告诉你为什么你的像素到像素的距离会高估边界长度:因为图像是在规则网格上定义的,通过将边界像素串在一起得到的多边形是不如您尝试测量的连续域圆那么平滑。锯齿状会导致多边形边界更长。对此进行补偿的算法倾向于假设圆形物体,因此将圆形的误差最小化。这种补偿会导致对正方形边界长度的低估。尽管如此,如果您以任意角度测量正方形的边界,您最终会使用此补偿得到准确的估计。与网格对齐的单个正方形恰好是最坏的情况。

    有关算法和所涉及选择的更深入解释,请参阅this blog post


    编辑:

    现在我知道 MATLAB 使用什么算法了。有一个名为'PerimeterOld' 的属性,它实现了您也尝试过的简单方法。也就是说,它对水平或垂直步长使用权重 1,对对角线步长使用权重 sqrt(2)。您正在使用的一个名为 'Perimeter' 的属性具有您发现的意外行为,它使用了我在上面给出的链接中描述的 Vossepoel 和 Smeulders 的算法:

    % (Code copy-pasted from regionprops.m
    %  Copyright 1993-2014 The MathWorks, Inc.
    %  Provided here as "fair use" for instructional purposes, don't
    %  use this code, use the equivalent code on my blog instead.)
    function perimeter = computePerimeterFromBoundary(B)
    delta = diff(B).^2;
    if(size(delta,1) > 1)
        isCorner  = any(diff([delta;delta(1,:)]),2); % Count corners.
        isEven    = any(~delta,2);
        perimeter = sum(isEven)*0.980 + sum(~isEven)*1.406 - sum(isCorner)*0.091;
    else
        perimeter = 0; % if the number of pixels is 1 or less.
    end
    

    【讨论】:

    • 感谢您的回答!现在我明白了主要原因。解决此问题的下一步是找到此类代码的算法,以了解它们如何补偿这些错误并进行查看。再次感谢!
    • @Melissa 我找到了regionprops 使用的相关代码。我已经编辑了我的答案。我希望这会有所帮助。
    • 非常感谢您的回答。现在我明白了 Vossepoel 和 Smeulders 方法对周长有其重要性。大多数人都是用这种方式计算圆形物体吗?
    • @Melissa 这是计算周长的正确方法。不幸的是,仍然有很多人不知道这种方法,他们使用1sqrt(2) 权重,或者更糟糕的是,他们只计算像素。表示赞赏的一种方式是支持我的回答。 ;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-17
    • 1970-01-01
    • 2018-03-03
    • 1970-01-01
    • 2016-01-17
    相关资源
    最近更新 更多