与旋转相对于任意点的OpenCV warpa仿射

OpenCV warpAffine with rotation with respect to arbitrary point

本文关键字:OpenCV warpa 仿射 任意点 旋转 相对于      更新时间:2023-10-16

我在c++中使用OpenCV。我有两张脸的图像,我试着让这两张脸对齐。我用五官来表示眼睛、鼻子和脸部的其他兴趣点。我使用Arun的方法提取旋转、平移和缩放,将一张图像中的特征集的质心转换到另一张图像。然后,它旋转并缩放它。我试着用这个变换来扭曲一个图像,这样图像中的脸就和另一个图像中的脸对齐了。至少是这么想的,但我遇到了问题。在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());

问题是我正在使用行,列顺序的点,而warpAffine想要从x,y顺序(又名列,行)的点派生的矩阵。翻转点并使用getAffineTransform解决了这个问题。