对于某些形状,特别是具有少量像素的形状,常用的计算圆度的方法通常会导致一个偏差较大的值,并且可能大于1。在R2023a之前的版本中,函数
regionprops
使用这种常用方法。在R2023a中,对计算方法进行了修改,以纠正偏差。
要了解完整的故事,请继续阅读!
什么是循环?
我们对圆度的定义是:
$c = \frac{4\pi a}{p^2}$
在哪里
一个
形状的面积是和吗
p
是它的周长。它是一个在值域内的无单位量
[0, 1]美元
.真圆的圆度是1。以下是一些简单形状的估计圆度测量值。
url = “https://blogs.mathworks.com/steve/files/simple-shapes.png” ;
P = regionprops( “表” ,, “循环”的“重心” ])
p =
3×2表
重心
循环
1
104.0036
107.9564
0.9999
2
327.0258
141.0007
0.6223
3.
619.9921
107.9377
0.1514
文本(p.Centroid (k, 1), p.Centroid (k, 2),字符串(p.Circularity (k)), ...
写成BackgroundColor = “蓝色” , ...
HorizontalAlignment = “中心” , ...
VerticalAlignment = “中间” , ...
圆度> 1??
一些用户
可以理解的是,在之前的版本中,
regionprops
有时会返回大于1的循环值。例如:
url = “https://blogs.mathworks.com/steve/files/small-circle.png” ;
写成BackgroundColor = “蓝色” , ...
HorizontalAlignment = “中心” , ...
VerticalAlignment = “中间” , ...
测量周长
在继续之前,我想暂停一下,尽管圆度是一个有用的测量方法,但它也可能相当棘手。当试图精确测量周长时,人们可能会迷失在分形的世界里;请看Bernard Mandelbrot的著名论文《英国海岸有多长?》统计自相似性和分数维,”维基百科上这样描述
在这里
.然后,由于我们处理的是数字图像,我们有时把它的像素看作是离散网格上的点,有时又把它看作是单位面积的正方形,这就增加了一些困难。比如,MATLAB回答MVP John D'Errico的问题
评论
关于这个话题。
实际上,测量周长是常见的圆度计算方法遇到麻烦的原因。测量数字图像中物体的周长通常是通过从一个像素中心跟踪到下一个像素中心,然后将由连续片段之间的角度确定的权重相加来完成的。
情节(b {1} (: 1), b{1}(:, 2),颜色= (0.850 0.325 0.098), ...
为了使周长测量中的系统偏差最小化,已经使用了几种不同的方案来分配权重。所使用的权重
regionprops
是Vossepeol和Smeulders在“有限长度直线表示中的矢量码概率和度量误差”中给出的,
计算机图形学与图像处理“,
,第20卷,第347-364页,1982。参见Luego,“测量边界长度”,Cris的图像分析博客:理论,方法,算法,应用,
https://www.crisluengo.net/archives/310/,
最后访问时间为2023年3月20日。
圆度计算偏差的原因可以从上图中看到。周长是根据连接像素中心的路径计算的。不过,有些像素部分位于红色曲线之外。因此,周长是沿着一条不完全包含所有正方形像素的曲线计算的;曲线有点太小了。相对于面积计算,周长计算被低估了。由于周长在圆度公式的分母中,因此得到的值过高。
我们能通过不同的周长轨迹来解决这个问题吗?让我们试着用一个45度角的数字化正方形。
0 0 0 0 0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 1 1 0 0 0 0 0 0
0 0 1 1 1 1 1 1 1 1 1 1 1 0 0
0 1 1 1 1 1 1 1 1 1 1 1 1 10 0
0 0 1 1 1 1 1 1 1 1 1 1 1 0 0
0 0 0 0 0 1 1 0 0 0 0 0 0
0 0 0 0 0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0];
这是由
regionprops
用来计算周长。
plot(x,y,Color = [0.850 0.325 0.098])
红色方块的周长是
$4 \cdot 5 \sqrt{2} \约28.3美元
.的面积
$(5 \√{2})^ 2美元
.然而,白色方块的数量是61个。估计的周长和面积不一致,这将导致有偏差的圆度测量。
我们能不能像这样沿着像素点的外围追踪周长来修复它?
X = [1.5 6.5 7.5 12.5 12.5 7.5 6.5 1.5 1.5];
Y = [6.5 1.5 1.5 6.5 7.5 12.5 12.5 7.5 6.5];
plot(x,y,Color = [0.850 0.325 0.098])
现在计算出来的周长太高了因为它对应的面积比白色像素的数量61要大得多。
= sum(√(sum(diff([x(:) y(:)]).^2,2)))))
对于一个正方形,周长对应于这个面积:
这一次,估计的周长相对于估计的面积过高,因此计算的圆度将偏低。
如果我们通过沿像素边缘跟踪来计算周长呢?
X =[1.5 2.5 2.5 3.5 3.5 4.5 4.5 5.5 5.5 6.5 6.5。 ...
7.5 7.5 8.5 8.5 9.5 9.5 10.5 10.5 11.5 11.5 12.5 12.5 12.5 ...
11.5 11.5 10.5 10.5 9.5 9.5 8.5 8.5 7.5 7.5 6.5 6.5 ...
5.5 5.5 4.5 4.5 3.5 3.5 2.5 2.5 1.5 1.5];
Y = [7.5 7.5 8.5 8.5 9.5 9.5 10.5 10.5 11.5 11.5 11.5 . ...
12.5 12.5 11.5 11.5 10.5 10.5 9.5 9.5 8.5 8.5 ...
7.5 7.5 6.5 6.5 5.5 5.5 4.5 4.5 3.5 3.5 2.5 2.5 1.5 1.5 ...
2.5 2.5 3.5 3.5 4.5 4.5 5.5 5.5 6.5 6.5 7.5];
plot(x,y,Color = [0.850 0.325 0.098], LineWidth = 5)
但是现在计算的周长是
道路
相对于面积太高,所以计算出来的圆度会很低。
= sum(√(sum(diff([x(:) y(:)]).^2,2)))))
偏差校正模型
在这之后,我们决定不使用周长追踪方法。相反,我们提出了一个简单的圆度偏差近似模型,然后用该模型推导出校正因子。
考虑一个有半径的圆
r
.我们可以通过计算圆度来模拟偏差
r
周长是由
$r - 1/2$
.结果,
c '美元
,为偏置圆度模型。
$ c ' = \压裂{1}{1 - \压裂{1}{r} + \压裂{0.25}{r ^ 2}} = \压裂{1}{\离开(1 - \压裂{0.5}{r} \右)^ 2}$
有多好
c '美元
匹配什么旧的
regionprops
计算又回来了?这是一个在一定半径范围内的数字化圆上进行的比较。
但是对于一般的形状我们应该怎么做呢?毕竟,如果我们已经知道它是一个圆,那么就不需要计算圆度度规了,对吧?
策略是这样的:给定计算面积,
一个
,确定
等效半径
,
美元$ r_{\文本{eq}}
,即相同面积的圆的半径。然后,用
美元$ r_{\文本{eq}}
要得到偏差修正系数:
美元c_{\文本{纠正}}= c \离开(1 - \压裂{0.5}{r_{\文本{eq}}} \右)^ 2 = c \离开(1 - \压裂{0.5}{\ sqrt{/ \π}}\右)^ 2美元
有用吗?
我们只是做了一个很大的假设,计算
美元$ r_{\文本{eq}}
就好像我们的形状是一个圆。我们真的能做到吗?我们做了一系列实验,用各种各样的形状,在很大的范围内缩放,并以不同的角度旋转。下面是一个实验的结果,用一个等边三角形,它的底与水平轴旋转了20度。蓝色曲线是在以前版本中计算的圆度;红色曲线为R2023a中计算的校正圆度,橙色横线为理论值。
我们发现很多形状都有相似的曲线。对于一些理论圆度值低于0.2左右的形状,修正并没有改善结果。然而,总的来说,我们认为纠正方法是值得的
regionprops
应该改变,以纳入它。
方法的版本历史记录部分,如果需要在代码中获取先前计算的值
区域道具参考页面
的指令。
Helper函数
xline(k, Color = [.]7 .7 .7]);
yline(k, Color = [.]7 .7 .7]);
下载实时脚本
评论
如欲留言,请点击在这里登录您的MathWorks帐户或创建一个新帐户。