python - 无法理解此代码中的质心和距离公式
问题描述
我正在努力理解 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 )$
解决方案
好的,让我们通过这个
centroid = mean(x, 2);
沿行取平均值,x
3 行 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]
推荐阅读
- neo4j - Neo4j - 根据多种类型的关系进行过滤
- java - 我们如何在android中将贴纸添加到默认键盘
- html - 如何从子类中删除 CSS 过滤器?
- flutter - 突变不起作用 - Flutter 和 GraphQL
- django - 从 url 捕获任意数量的值
- ionic-framework - 无法设置离子离子范围的默认最小值和最大值
- javascript - 使用 DirectLine ASE 保留与 Bot Framework 的聊天记录
- firebase - 错误:NoSuchMethodError:类“_AssertionError”没有实例获取器“代码”
- javascript - 如何通过javascript中的键值类型更改嵌套对象数组
- python - 如何通过Python检测照片中的相似物体