Что внутри (как разложить) аффинную матрицу деформации

Мой вопрос связан с другим вопросом, который я задал . но здесь я пытаюсь точнее понять состав warp_matrix, полученный с помощью cv2.getAffineTransform. Я нашел в это, как разложить матрицу аффинного преобразования и особенно как получить угол поворота

Но при использовании примера из документа OpenCV Получаю два разных угла поворота.

код :

import cv2
import numpy as np

pts1 = np.float32([[50,50],[200,50],[50,200]])
pts2 = np.float32([[10,100],[200,50],[100,250]])

M = cv2.getAffineTransform(pts1,pts2)

theta0=np.degrees(np.arctan(-M[0,1]/M[0,0]))
theta1=np.degrees(np.arctan(M[1,0]/M[1,1]))

print(theta0)
print(theta1)

производить :

-25.3461759419
-18.4349488229

person Antoine Soulier    schedule 01.02.2019    source источник


Ответы (1)


Преобразования подобия (которые представлены комбинацией масштабирования, поворота и перемещения) являются подмножеством аффинных преобразований. Аффинные преобразования представляют собой произвольные матрицы 2x3 и поэтому не должны разлагаться на отдельные матрицы масштабирования, поворота и преобразования.

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

Если вы используете OpenCV 3.2.0+ (включая 4.0+), вы можете использовать cv2.estimateAffinePartial2D() (документы). Если вы используете предыдущую версию, вы можете использовать cv2.estimateRigidTransform() (docs)< /а>.

Из документов на estimateAffinePartial2D() предполагаемая матрица преобразования

cos(θ) * s   -sin(θ) * s    t_x
sin(θ) * s    cos(θ) * s    t_y

Где θ — угол поворота, s — коэффициент масштабирования, а t_x, t_y — перемещения по осям x, y соответственно.

Результат здесь может быть разложен в соответствии с ответом, который вы связали.

>>> M, inliers = cv2.estimateAffinePartial2D(pts1, pts2)
>>> M
array([[  1.26666667,   0.33333333, -70.        ],
       [ -0.33333333,   1.26666667,  53.33333333]])

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

>>> theta0 = np.degrees(np.arctan2(-M[0,1], M[0,0]))
>>> theta1 = np.degrees(np.arctan2(M[1,0], M[1,1]))
>>> print(theta0)
-14.7435628365
>>> print(theta1)
-14.7435628365

Обратите внимание, что ответ на ваш вопрос ссылается на другой ответ на другой вопрос. Есть небольшое отличие от матрицы, которую мы получили здесь, и матрицы, обсуждаемой там: в версии выше есть только один масштабный коэффициент s, но в связанной версии есть два масштабных коэффициента, s_x и s_y. Это эффективно оставляет пять степеней свободы, а именно переменные

s_x, s_y, θ, t_x, t_y

Преобразование подобия имеет четыре степени свободы, а полное аффинное преобразование — шесть. На самом деле я не знаю, широко ли используется тип с пятью степенями свободы; Я не видел, чтобы это обсуждалось в литературе по сшиванию изображений / фотограмметрии, которую я читал (хотя математически это, конечно, все еще допустимое подмножество аффинных преобразований). Я просто указываю на это, поскольку это несоответствие между моим ответом и тем, на который вы ссылаетесь, но на практике я не думаю, что вы увидите, что используется такой тип преобразования.

person alkasm    schedule 02.02.2019