OpenCV warpAffine 相对于任意点旋转
OpenCV warpAffine with rotation with respect to arbitrary point
我在 C++ 中使用 OpenCV。我有两张人脸图像,我正在尝试将这些人脸对齐。我有表示眼睛、鼻子和其他面部兴趣点的特征。我使用 Arun 的方法来提取旋转、平移和缩放,将一幅图像中的特征集的质心平移到另一幅图像中。然后,它旋转并缩放它。我正在尝试使用此转换来扭曲一张图像,以便图像中的脸部与另一张图像中的脸部对齐。至少这是个主意,但我遇到了问题。似乎旋转和平移的执行顺序与我在 warpAffine 中预期的顺序不同。 row/column 排序与 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 解决了这个问题。
我在 C++ 中使用 OpenCV。我有两张人脸图像,我正在尝试将这些人脸对齐。我有表示眼睛、鼻子和其他面部兴趣点的特征。我使用 Arun 的方法来提取旋转、平移和缩放,将一幅图像中的特征集的质心平移到另一幅图像中。然后,它旋转并缩放它。我正在尝试使用此转换来扭曲一张图像,以便图像中的脸部与另一张图像中的脸部对齐。至少这是个主意,但我遇到了问题。似乎旋转和平移的执行顺序与我在 warpAffine 中预期的顺序不同。 row/column 排序与 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 解决了这个问题。