реализация физических моментов для трехмерного восстановления формы в python - PullRequest
0 голосов
/ 10 февраля 2020

Я пытаюсь реализовать метод 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])

Итак, это вершины моего примера объекта, который затем выглядит как: Original pyramid

Для вычисления моментов я включил следующий метод:

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

Пирамида после этих операций: Pyramid centered+rotated+scaled

Есть идеи, где моя ошибка / ошибка может быть?

Спасибо заранее!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...