OpenCV warpAffine с вращением относительно произвольной точки

Я использую OpenCV в C ++. У меня есть два изображения лиц, и я пытаюсь выровнять лица друг к другу. У меня есть особенности, обозначающие глаза, нос и другие точки интереса на лицах. Я использую метод Аруна, чтобы извлечь вращение, перевод и масштабирование, которое переводит центроид наборов функций в одном изображении в другое. Затем он вращается и масштабируется. И я пытаюсь использовать это преобразование, чтобы деформировать одно изображение так, чтобы лицо на изображении совпало с лицом на другом изображении. По крайней мере, это идея, но у меня проблемы. Кажется, что вращение и перевод выполняются в другом порядке, чем я ожидал в warpAffine. Также кажется, что есть проблема с порядком строк / столбцов в зависимости от координат x / y. Кроме того, как следует из названия, я думаю, что warpAffine выполняет операции с 0,0 на изображении, тогда как я ожидаю, что они будут выполняться вокруг центроида точек лица. Что я должен делать, чтобы правильно выровнять эти два набора точек? Вот мой код:

// R is the rotation as computed by Arun's method
// centered_moving is the moving points with the centroid subtracted from them
// same with centered_base
for (int i = 0; i < base.cols; i++)
{
a = centered_base.col(i);
b = centered_moving.col(i).t();
H += a*b;
}
SVD sv;
Mat W, U, Vt;
sv.compute(H, W, U, Vt);
Mat R = (Vt.t())*(U.t());
// centroid_moving and centroid_base are the centroids of the two point clouds, moving is the cloud that will be translated
Mat trans = -centroid_moving + centroid_base;
Mat Afmat = Mat::zeros(2, 3, ddepth);
Mat tmpmat = Afmat(Rect(0, 0, 2, 2));
R = Mat::eye(2, 2, ddepth);
R.copyTo(tmpmat);
Afmat.at<double>(1, 2) = trans.at<double>(0);
Afmat.at<double>(0, 2) = trans.at<double>(1);
warpAffine(image_moving, affine_result, Afmat, image_moving.size());

0

Решение

Проблема заключалась в том, что я использовал точки в ряду, порядке столбцов, тогда как warpAffine хочет получить матрицу, полученную из точек в порядке x, y (столбец, строка). Перелистывание точек и использование getAffineTransform решило проблему.

0

Другие решения