我试图找到物体的质心。我已经实现了连接组件标签,我已经为质心开发了以下代码,它确实给出了结果,但没有给出正确的结果: 我有以下输出矩阵,即matrix_img:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0
2 2 2 2 0 0 0 0 0 1 1 1 1 1 1 0
2 2 2 2 0 0 0 0 1 1 1 1 1 1 1 1
2 2 2 2 0 0 0 0 1 1 1 1 1 1 1 1
2 2 2 2 0 0 0 0 1 1 1 1 1 1 1 1
2 2 2 2 0 0 0 0 0 1 1 1 1 1 1 0
2 2 2 2 0 0 0 0 0 0 1 1 1 1 0 0
2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0
2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0
2 2 2 2 0 0 5 5 5 0 0 0 0 0 0 0
2 2 2 2 0 0 5 5 5 0 0 0 0 0 0 0
2 2 2 2 0 0 5 5 5 0 0 0 0 0 0 0
2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0
以下是代码
n= max(max(matrix_img));
for k=1:n
a(k)=length(find(matrix_img==k));
sx(k)=0;
sy(k)=0;
cx=0;
cy=0;
for i=1:1:r
for j=1:1:c
if(matrix_img(i,j)==k)
sx(k)=sx(k)+i;
sy(k)=sy(k)+j;
cx=sx(k)/a(k);
cy=sy(k)/a(k);
end
end
end
fprintf('Centroid of Object %d is %d and %d \n', k, cx, cy);
end
它给出的结果如下:
Centroid of Object 1 is 7 and 1.250000e+001
Centroid of Object 2 is 1.050000e+001 and 2.500000e+000
Centroid of Object 3 is 0 and 0
Centroid of Object 4 is 0 and 0
Centroid of Object 5 is 14 and 8
对象5结果正确,对象2完全错误,对象1部分错误。我该怎么办?
答案 0 :(得分:6)
您获得的值是这些对象的精确质心。所以你可能想要定义你期望得到的结果。
为了使这一点更清晰,我已经在矩阵中对对象进行着色。通过笛卡尔网格上的对称性,质心的左右两侧应该有相同数量的点,质心上方/下方应该相同。我绘制了一个彩色物体的图形,以及表示水平和垂直中心线的线条。这些是线条,我们在它们的左/右(或上/下)有相同数量的点,它们是某个对象的一部分。
它们的交点是质心,所以你可以看到物体5(蓝色)的质心位于(8, 14)
。对于其他两个对象,这些中心线不位于您拥有的整数网格上:红色对象(1)的质心位于(12.5, 7)
,这也是代码的结果,绿色对象(2)是以(2.5, 10.5)
为中心。
您要么必须通过舍入质心(例如round(cx)
)而引入不准确,要么必须使用质心的非整数坐标。
除此之外,我还建议您像oli所示那样对代码进行矢量化:这使您可以更快地运行代码,并且当您熟悉MATLAB而不是for
循环时更容易理解。
关于你的字符串表示可能有一点注意事项:不要将%d
用于非整数,因为你会看到这将导致实数以科学记数法显示。如果您使用%0.2f
之类的内容作为格式字符串,我认为更清楚。
答案 1 :(得分:3)
当你使用matlab时,避免使用循环,这会使你的代码变得非常慢,并且它会更长。
你可以这样做:
[y x]=ndgrid(1:size(matrix_img,1),1:size(matrix_img,2));
n=max(matrix_img(:));
for k=1:n
cy=mean(y(matrix_img==k));
cx=mean(x(matrix_img==k));
fprintf('Centroid of Object %d is %2.2g and %2.2g \n', k, cx, cy);
end
(也许你想在那段代码中交换x和y)