首页 > 解决方案 > 无法理解此代码中的质心和距离公式

问题描述

我正在努力理解 8 点算法的规范化过程。我在 MATLAB 中引用这段代码,因为我没有 matlab,所以我无法运行。

function Nmatrix = getNormMat2d(x)

Nmatrix - the normalization matrix
%       x - input data, dim: 3xN

% Get the centroid
centroid = mean(x, 2);
% Compute the distance to the centroid
dist = sqrt(sum((x - repmat(centroid, 1, size(x, 2))) .^ 2, 1));
% Get the mean distance
mean_dist = mean(dist);
% Craft normalization matrix
Nmatrix = [sqrt(2) / mean_dist, 0, -sqrt(2) / mean_dist * centroid(1);...
           0, sqrt(2) / mean_dist, -sqrt(2) / mean_dist * centroid(2);...
           0, 0, 1];

end

我正在尝试用 Python 编写代码。但我不明白一些事情:

质心不应该是这样的:

#dummy points 
x1 = np.array([20, 30, 40, 50, 60, 30, 20, 40])
y1 =  np.array([12, 34, 56, 78, 89, 45, 90, 29])
# did the following to give it the shape the matlab function expects
first=np.stack((x1,y1),axis = 1) 
ones=np.ones((8,1))
first = np.concatenate((first,ones),axis = 1)
p1 = np.ndarray.transpose(first)
#centroid
centroid_x = np.mean(p1[0,:])
centroid_y = np.mean(p1[1,:])

我不明白他们为什么使用centroid = mean(x, 2);. 除此之外,这条线dist = sqrt(sum((x - repmat(centroid, 1, size(x, 2))) .^ 2, 1));在我的脑海中并不是很好。

请帮助我理解这一点

关于算法:

我们需要得到一个变换矩阵(平移和缩放),使得新坐标系的原点位于质心,并且在平移之后坐标被统一缩放,使得从原点到点的平均距离等于 $sqrt(2 )$

标签: pythonmatlab

解决方案


好的,让我们通过这个

centroid = mean(x, 2);

沿行取平均值,x3 行 N 列也是如此。这意味着这centroid是一个 3x1 向量[xC ; yC ; zC]

dist = sqrt(sum((x - repmat(centroid, 1, size(x, 2))) .^ 2, 1));

让我们从外到内

repmat(centroid, 1, size(x, 2))

制作一个包含 N 个 副本的矩阵centroid。然后-取点和质心之间的差,给出一个 3xN 矩阵。.^2只是将 3xN 矩阵的每个元素平方。沿行sum( ... , 1 )相加(即,将 x、y 和 z 分量加在一起)。然后sqrt取平方根。

所以通过 Matlab 代码运行你的 python 示例

x1 = [20, 30, 40, 50, 60, 30, 20, 40];
y1 = [12, 34, 56, 78, 89, 45, 90, 29];
x = [ x1 ; y1 ];
centroid = mean(x, 2);
dist = sqrt(sum((x - repmat(centroid, 1, size(x, 2))) .^ 2, 1));
dist'

ans =

      45.1506159980127
      21.0731612483747
      4.19262745781211
      27.5513724703507
      42.1939346944558
      11.0602045641118
      39.3837291911266
      25.4033093316599

和等效的python

x1 = np.array([20, 30, 40, 50, 60, 30, 20, 40])
y1 =  np.array([12, 34, 56, 78, 89, 45, 90, 29])
x = np.column_stack((x1,y1))
centroid = np.mean( np.transpose( x ) )
dist = [ np.sqrt( np.sum( np.square( v - centroid ) ) ) for v in x ]
dist
[45.1506159980127, 21.073161248374674, 4.192627457812105, 27.551372470350728, 42.19393469445579, 11.060204564111823, 39.38372919112663, 25.40330933165992]

推荐阅读