Python - 3D аффинное преобразование

Я работаю с двумя похожими, но еще не идентичными объемами с сеткой объема внутри. Я хочу, чтобы мой первый том (зеленый) соответствовал второму (красному). Оба имеют ConvexHull ( http://scipy.github.io/devdocs/generated/scipy.spatial.ConvexHull.html) с внутренними вершинами. Я создал несколько маркеров (см. Рисунок 1) для обоих томов для расчета матрицы преобразования ( https://community.esri.com/thread/183601-numpy-linalglstsq-coordinate-translations).

Структура данных таблицы объема моего исходного тома:

array([[ 0.025, -0.055, -0.03 ],
       [-0.01 , -0.05 , -0.03 ],
       [-0.005, -0.05 , -0.03 ],
       ..., 
       [-0.01 , -0.03 ,  0.1  ],
       [-0.01 , -0.025,  0.1  ],
       [-0.015, -0.02 ,  0.1  ]])

 ,     with the shape of `(12163, 3)`

Структура данных таблицы объема моего исходного тома:

array([[ 0.   , -0.055, -0.065],
       [ 0.005, -0.055, -0.065],
       [-0.005, -0.05 , -0.065],
       ..., 
       [-0.005, -0.02 ,  0.08 ],
       [ 0.   , -0.02 ,  0.08 ],
       [ 0.005, -0.02 ,  0.08 ]])

 ,     with the shape of `(14629, 3)`

Рисунок 1 - Маркер для обоих томов ConvexHull

Координаты исходных маркеров, которые должны быть преобразованы:

array([[-0.00307161, -0.01828496,  0.03521746],
       [-0.065     , -0.01828496,  0.03521746],
       [ 0.06      , -0.01828496,  0.03521746],
       [-0.00307161, -0.01828496,  0.1       ],
       [-0.00307161,  0.075     ,  0.03521746],
       [-0.00307161, -0.01828496, -0.03      ]])

Маркер шаблона:

array([[ 0.00038417, -0.02389603,  0.00802208],
       [-0.07      , -0.02389603,  0.00802208],
       [ 0.07      , -0.02389603,  0.00802208],
       [ 0.00038417, -0.02389603,  0.08      ],
       [ 0.00038417,  0.07      ,  0.00802208],
       [ 0.00038417, -0.02389603, -0.065     ]])

Я беру координаты своих маркеров, чтобы вычислить матрицу преобразования, например:

print 'Calculating the transformation matrix..\n'

n = orig_marker.shape[0]
pad = lambda x: np.hstack([x, np.ones((x.shape[0], 1))])
unpad = lambda x: x[:,:-1]
trans_mat, res, rank, s = np.linalg.lstsq(pad(orig_marker), pad(temp_marker))


transform = lambda x: unpad(np.dot(pad(x), trans_mat))
trans_mat[np.abs(trans_mat) < 1e-10] = 0  # set really small values to zero
print 'trans matrix is:\n', trans_mat
trans_mat_inv = np.linalg.inv(trans_mat)

Out [1]:  trans matrix is [[  3.29770822e-02   1.06840729e-02   1.71325156e-03   0.00000000e+00]
     [ -7.56419706e-03   9.51696607e-03   3.51349962e-02   0.00000000e+00]
     [  5.32353680e-03   2.91946064e-01   8.44071139e-01   0.00000000e+00]
     [  1.96037928e-04  -3.51253282e-02  -3.05335725e-02   1.00000000e+00]]

После этого я применяю свою матрицу преобразования к точкам сетки объема:

# apply rotation and scale
transformed_points = np.dot(orig_points, trans_mat[:3, :3].T)
# apply translation
transformed_points += trans_mat[:3, 3]
x_t, y_t, z_t = transformed_points.T

, где orig_points а также temp_points объемные сетки моих объемов x_t, y_t, z_t координаты моих преобразованных сеток объема.

Так как я применяю вращение, масштабирование и трансляцию, мои сетки объема должны совпадать. к сожалению, моя сетка объема по-прежнему выглядит как на рисунке 2:

Я почти уверен, что мой подход правильный. Я думаю, что ошибка может быть в расчете матрицы преобразования.

Кто-нибудь может увидеть, что пошло не так или где я ошибся?

С моим собственным переводом результат выглядел следующим образом:

Поскольку результат не точный, я бы предпочел правильный расчет моей матрицы преобразования.

0 ответов

Другие вопросы по тегам