0

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

// 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

Не можете использовать [getAffineTransform] (http://docs.opencv.org/modules/imgproc/doc/geometric_transformations.html?#getaffinetransform) с двумя векторами точек? Или [findHomography] (http://docs.opencv.org/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html?#findhomography)? – Miki

+0

Я пробовал findHomography, но по какой-то причине это приводит к очень искаженным регистрациям. getAffineTransform может получать информацию только от 3 очков, а мои совпадения несовершенны, поэтому 3 балла недостаточно. У меня около 30 баллов. –

+0

Вы уверены, что порядок точек одинаковый для двух векторов, которые вы передаете findHomography? CV_RANSAC должен дать вам надежные результаты. – Miki

ответ

0

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