MATLAB的“regionprops”函数如何计算周长?

时间:2018-06-13 15:12:17

标签: matlab image-processing

我发现该函数使用chain codes对形状的边界进行编码,然后使用以下公式计算周长this way

perimeter = sum(isEven)*0.980 + sum(~isEven)*1.406 - sum(isCorner)*0.091;

然而,我不知道在某些特殊情况下如何计算这个链代码。

考虑以下示例(MATLAB的周长为10.0150):

 1     1     1     1     1
 1     1     0     0     1

MATLAB如何定义/计算连接到左侧2x2方格的一条像素宽线周围的周边?

更确切地说:

如果我使用字母表示非零边框像素(在此示例中,所有1都是边框):

 a     d     e     f     g
 b     c                 h

链码可以从a开始。如果我们顺时针计算它,它会继续cef ...这意味着它无法返回a,否则就必须去在同一个字母上两次(如果有1px宽线连接到其他1px宽线等,则甚至超过两次)。

1 个答案:

答案 0 :(得分:2)

获取链码有两个步骤:跟踪边界并将坐标编码为链码。后一步是微不足道的,我不会详细介绍。追踪边界是我认为这个问题的关键。

通常跟踪的是形成边界的对象像素(即,具有至少一个背景邻居)。重要的是,这种情况按顺序发生,仅列出这些像素是不够的。但请注意,边界的这种描述是有偏见的:真实对象大于通过连接对象边界处像素中心形成的多边形。外围计算需要考虑到这一点(正如您链接的博客文章中所讨论的那样)。

此代码略微改编自this blog postimg是一个逻辑数组:

% Data for chain code encoding:
directions = [ 1, 0
               1,-1
               0,-1
              -1,-1
              -1, 0
              -1, 1
               0, 1
               1, 1];
% Get a start point, any pixel on the boundary is OK:
indx = find(img,1)-1;           % 0-based indexing is easier
% Image sizes
sz = [size(img,2),size(img,1)]; % x,y sizes, rather than y,x sizes
% Coordinates for start point
start = [floor(indx/sz(2)),0];
start(2) = indx-(start(1)*sz(2));
% Initialize algorithm
cc = [];                        % The chain code
coord = start;                  % Coordinates of the current pixel
dir = 1;                        % The starting direction
% Loop till full boundary is traced
while 1
   newcoord = coord + directions(dir+1,:);
   if all(newcoord>=0) && all(newcoord<sz) ...
         && img(newcoord(2)+1,newcoord(1)+1)
      cc = [cc,dir];
      coord = newcoord;
      dir = mod(dir+2,8);
   else
      dir = mod(dir-1,8);
   end
   if all(coord==start) && dir==1 % back to starting situation
      break;
   end
end

正如你在这里看到的那样,算法从一个随机像素开始,并选择一个方向来绕过。然后它通过在给定方向上找到下一个邻居来跟随边界。链接的博客文章详细说明了如何找到该邻居。简而言之,您在当前方向上查看具有背景邻居的第一个相邻对象像素。鉴于我们来自的当前位置和方向,可以证明特定方向上的邻居将是背景像素。沿着当前点顺时针(或逆时针,选择一个)方向,从该背景像素开始,第一个对象像素将保证是边界像素。我们将其添加到列表中并继续。

当我们到达开始位置和方向时,算法终止。因此,对象的1像素厚部分将被访问两次,以完成边界轨迹。