matlab - MATLAB 的 `regionprops` 函数如何计算周长?
问题描述
我发现该函数使用链码来编码形状的边界,然后使用以下公式以这种方式计算周长:
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
. 如果我们顺时针计算它,它会在c
, e
, f
...a
宽线等)。
解决方案
获取链码有两个步骤:追踪边界和将坐标编码为链码。这后一步是微不足道的,我不会详细说明。我认为这个问题是关于追踪边界的。
通常,所跟踪的是形成边界的对象像素(即具有至少一个背景邻居)。重要的是按顺序进行,仅列出这些像素是不够的。但请注意,对边界的这种描述是有偏差的:真实对象大于通过在对象边界处连接像素中心形成的多边形。周长计算需要考虑到这一点(如您链接的博客文章中所述)。
这段代码稍微改编自这篇博文。img
是一个逻辑数组:
% 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 像素厚部分将被访问两次,以完成边界跟踪。
推荐阅读
- apache-kafka - debezium 无法使用带有默认插件 pgoutput 的 postgres 11 访问文件“decoderbufs”
- android - 当 MainAcitivty 调用 onDestroy() 时如何调用所有活动 onDestroy()?
- javascript - JS/JSON 每小时为数据创建一个新行
- node.js - 无法完成 React 在 Github 页面上使用的“npm run deploy”命令
- ios - 停止 UICollectionView 滚动并使其显示所有单元格
- java - OAuth2RestOperations:java.lang.IllegalArgumentException:URI 不是绝对的
- graph - 图建模(社交网络)
- sql-server - updateOrCreate laravel 不适用于 SQL Server
- python - Python 初学者(需要帮助)- 仅输出已保存列表的一个元素的程序 (3.8.1)
- android - 使用 Room 检索单个记录以填充编辑对话框(活动或片段)