Я пытаюсь реализовать метод 3D Shape-Retrival в Python. Основой являются «физические моменты», как указано в следующей статье .
Объекты представлены в виде облаков точек. Моя первая цель - центрировать эти точки в (0,0,0), повернуть их в их каноническую c позу и изменить масштаб, как описано в статье выше. Все, кроме перемасштабирования, работает просто отлично.
Вот мой код:
Создание пирамиды:
P1 = [3,3,3]
P2 = [6,3,3]
P3 = [6,5,3]
P4 = [3,5,3]
P5 = [4.5,4,7]
points = [P1,P2,P3,P4,P5]
points = np.reshape(points, [5,3])
Итак, это вершины моего примера объекта, который затем выглядит как:
Для вычисления моментов я включил следующий метод:
def getMoment(M,points):
M_step1 = np.power(points,M)
M_step2 = np.prod(M_step1, axis=1)
M_hat = sum(M_step2)/len(points)
return M_hat
Это прекрасно работает для вычисления первых моментов и перемещения геометрии в (0,0,0) путем вычитания этих моментов из исходных точек.
Mhat_100 = getMoment([1,0,0],points)
Mhat_010 = getMoment([0,1,0],points)
Mhat_001 = getMoment([0,0,1],points)
COM = [Mhat_100,Mhat_010,Mhat_001]
points_centered = np.subtract(points,COM)
Вычисление матрицы S:
S = np.asarray([getMoment([2,0,0],points_centered),getMoment([1,1,0],points_centered), getMoment([1,0,1],points_centered),\
getMoment([1,1,0],points_centered),getMoment([0,2,0],points_centered),getMoment([0,1,1],points_centered),\
getMoment([1,0,1],points_centered), getMoment([0,1,1],points_centered), getMoment([0,0,2],points_centered)])
S = np.reshape(S,[3,3])
Выполнение SVD-операции над этой матрицей:
U, S1, VH = np.linalg.svd(S, full_matrices=True)
Деление унитарной матрицы U по наибольшей шкале:
U_Scale = U/S1[0]
Применение масштабирования и поворота к центрированным точкам:
points_scale_rot = []
for i in points_centered:
points_scale_rot.append(np.dot(U_Scale,i))
points_scale_rot = np.reshape(points_scale_rot,[len(points_scale_rot),3])
points_scale_rot
Согласно документу, Наибольший элемент диагональной матрицы S должен быть равен 1, в противном случае я получаю следующее:
getMoment([2,0,0],points_scale_rot) #Result: 0.1220703125
getMoment([0,2,0],points_scale_rot) #Result: 0.390625
getMoment([0,0,2],points_scale_rot) #Result: 0.274658203125
Пирамида после этих операций:
Есть идеи, где моя ошибка / ошибка может быть?
Спасибо заранее!