Как найти матрицу аффинного преобразования между двумя наборами трехмерных точек? - PullRequest
0 голосов
/ 16 мая 2019

Мне нужно зарегистрировать некоторые 3D-ориентиры для лица, указанные для каждого кадра видео. Для этой задачи я пытаюсь найти матрицу преобразования между несколькими ориентирами, заданными для последовательных кадров. Например, трехмерные координаты 3 ориентиров в кадре 1 и кадре 2 задаются как:

frame1 = [2 4 15; 4 15 14; 20 11 7]
frame2 = [16 5 12; 5 7 9; 11 6 19]

Я попытался использовать функцию imregtform, предоставляемую инструментами matlab и ABSOR для matlab.

tform = imregtform(frame1, frame2, 'affine','OnePlusOneEvolutionary','MeanSquares');

tform = absor(frame1, frame2)

При использовании imregtform возникает следующая ошибка:

Error using imregtform>parseInputs (line 261)
The value of 'MovingImage' is invalid. All dimensions of the moving image should be greater than 4.

Error in imregtform (line 124)
parsedInputs = parseInputs(varargin{:});

Примечание: ABSOR не находит аффинное преобразование, оно находит преобразование подобия.

1 Ответ

1 голос
/ 21 мая 2019

Прежде всего, 3 балла - это слишком мало, чтобы восстановить аффинное преобразование - вам нужно 4 балла. Для N-мерного пространства есть простое правило: чтобы однозначно восстановить аффинное преобразование, вы должны знать изображения из N + 1 точек, которые образуют симплекс --- треугольник для 2D, пирамиду для 3D и т. Д. С 3 точками вы можете получить только 2D аффинное преобразование. Хорошее объяснение того, почему это так, вы можете найти в " Руководстве для начинающих по аффинному отображению симплексов ".

Относительно некоторого алгоритма поиска. Боюсь, я не знаю, чтобы Matlab предоставил вам соответствующий код, но я немного поработал с Python, возможно, этот код может помочь (извините за плохой стиль кода - я математик, а не программист)

import numpy as np
# input data
ins = [[1, 1, 2], [2, 3, 0], [3, 2, -2], [-2, 2, 3]]  # <- points
out = [[0, 2, 1], [1, 2, 2], [-2, -1, 6], [4, 1, -3]] # <- mapped to
# calculations
l = len(ins)
B = np.vstack([np.transpose(ins), np.ones(l)])
D = 1.0 / np.linalg.det(B)
entry = lambda r,d: np.linalg.det(np.delete(np.vstack([r, B]), (d+1), axis=0))
M = [[(-1)**i * D * entry(R, i) for i in range(l)] for R in np.transpose(out)]
A, t = np.hsplit(np.array(M), [l-1])
t = np.transpose(t)[0]
# output
print("Affine transformation matrix:\n", A)
print("Affine transformation translation vector:\n", t)
# unittests
print("TESTING:")
for p, P in zip(np.array(ins), np.array(out)):
  image_p = np.dot(A, p) + t
  result = "[OK]" if np.allclose(image_p, P) else "[ERROR]"
  print(p, " mapped to: ", image_p, " ; expected: ", P, result)

Этот код демонстрирует, как восстановить аффинное преобразование в виде матрицы и вектора, и проверяет, что начальные точки отображаются в том месте, где они должны. Он основан на уравнении, представленном в « Руководстве для начинающих по аффинному отображению симплексов », восстановление матрицы описано в разделе «Восстановление канонической записи». Те же авторы опубликовали « Рабочая тетрадь по аффинно по отображению симплексов», в которой содержится много практических примеров такого рода.

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