给定一组点,如何计算相似变换(平移,缩放,旋转)?

时间:2014-09-18 05:06:30

标签: opencv math affinetransform

我试图通过仿射翘曲注册一张脸,并注意到它有时会偏斜太多。我想计算一个没有剪切/偏斜分量的变换矩阵,但仍然保持注册误差的最小平方误差条件。我怎样才能做到这一点?以下是我如何进行仿射变换。

#include "opencv2/opencv.hpp"
using namespace cv;
int main(int ac, char* av[])
{ 
    vector<Point2f> src;
    vector<Point2f> dst;
    src.push_back(Point2f(100,100));
    src.push_back(Point2f(150,150));
    src.push_back(Point2f(200,200));

    dst.push_back(Point2f(50,100));
    dst.push_back(Point2f(150,150));
    dst.push_back(Point2f(210,220));

    // we want M,solve for it using the following
    // M * U = X
    // M = X * inv(U)
    Mat U=Mat::ones(3,3,CV_32FC1);
    Mat X=Mat::ones(2,3,CV_32FC1);

    U.at<float>(0,0)=dst[0].x;
    U.at<float>(0,1)=dst[1].x;
    U.at<float>(0,2)=dst[2].x;
    U.at<float>(1,0)=dst[0].y;
    U.at<float>(1,1)=dst[1].y;
    U.at<float>(1,2)=dst[2].y;

    X.at<float>(0,0)=src[0].x;
    X.at<float>(0,1)=src[1].x;
    X.at<float>(0,2)=src[2].x;
    X.at<float>(1,0)=src[0].y;
    X.at<float>(1,1)=src[1].y;
    X.at<float>(1,2)=src[2].y;

    Mat M = X *  U.inv();

    //now we have the transform matrix M, we can apply this to any x,y and get the source corrdinates
    float x=20,y=20;
    Mat DST=Mat::zeros(3,1,CV_32FC1);
    DST.at<float>(0,0)=x;
    DST.at<float>(1,0)=y;
    DST.at<float>(2,0)=1;
    Mat SRC = M*DST;
    float xf =SRC.at<float>(0,0);
    float yf =SRC.at<float>(1,0);

    //interpolation etc

    return 0;
}    

1 个答案:

答案 0 :(得分:3)

OpenCVs相似变换是cv::estimateRigidTransform,它允许您根据您选择的参数计算4自由度(相似变换)或6自由度(全仿射)变换。

请参阅链接了解更多详情:

http://docs.opencv.org/modules/video/doc/motion_analysis_and_object_tracking.html#estimaterigidtransform

但我不确定为什么它找不到某些输入的解决方案。请尝试使用点矢量而不是矩阵。我已经看到了案例(虽然它与findHomography有关),OpenCV将3x2矩阵(3个点,每个2维)误解为2个点,每个点有3个维度,反之亦然。反之亦然。