如果我在estimateRigidTransform或getAffineTransform中提供更多输入会发生什么?

nel*_*227 5 opencv

我正在使用estimateRigidTransform和大约两个100点的向量,并且工作正常.但不知何故getAffineTransform不起作用.

我知道findHomography使用RANSAC找到最好的矩阵,getPerspectiveTransform只需要4个点.

我的问题是如果我在estimateRigidTransform或getAffineTransform中提供更多输入会发生什么?

输入矩阵只需要4个点吗?或者做某种RANSAC?

Mic*_*nov 18

您提到的功能可以分为3种不同的类型:

类型1:getAffineTransform和getPerspectiveTransform.给定一个平面上的3个点和另一个平面上的3个匹配点,您可以计算这些平面之间的仿射变换.给出4分,你可以找到透视变换.这就是getAffineTransform和getPerspectiveTransform可以做的事情:它们需要3对和4对点,不多也不少,并计算相关变换.唯一的.

类型2:estimateRigidTransform.如果你无法获得绝对精确的点(通常是从图像中获取它们的情况),那么你需要超过3对点来减少误差.越多越好(即更好的准确性).有多种方法可以定义要减少的错误,以及用于查找最小错误的方法.estimateRigidTransform正在最小化最小平方误差(我认为最流行的错误定义).它通过求解方程组来实现.如果你提供3点,那么结果当然与getAffineTransform的结果相同.如果estimateRigidTransform可以完成其工作,您可以问我们为什么需要在OpenCV中使用getAffineTransform.唉,这不是OpenCV中唯一的冗余.

类型3:findHomography.这个更先进.它不仅可以处理点位置的错误,而且还可以处理异常值的存在.如果点之间存在一些错误的匹配,那么使用它们进行最小平方误差估计将导致非常差的精度.它可以使用RANSAC或LMeD来测试可能的匹配并消除这些异常值.它的工作方式类似于estimateRigidTransform的多次迭代:找到不同子点集的最小二乘匹配.如果您知道不存在异常值,那么您可以将'method'参数设置为0,它将像estimateRigidTransform一样工作 - 尝试最小化从所有点的匹配创建的最小平方误差.

编辑.感谢Micka的评论.

我想我的记忆在欺骗我.我记得estimateRigidTransform是通过OpenCV中的方程系统实现的,但现在我检查了它,看到Micka是对的.它确实使用了一些硬编码的RANSAC ...抱歉误导你.

对于那些仍然对封闭式解决方案而不是RANSAC感兴趣的人来说,这里是:

// find affine transformation between two pointsets (use least square matching)
static bool computeAffine(const vector<Point2d> &srcPoints, const vector<Point2d> &dstPoints, Mat &transf)
{
    // sanity check
    if ((srcPoints.size() < 3) || (srcPoints.size() != dstPoints.size()))
        return false;

    // container for output
    transf.create(2, 3, CV_64F);

    // fill the matrices
    const int n = (int)srcPoints.size(), m = 3;
    Mat A(n,m,CV_64F), xc(n,1,CV_64F), yc(n,1,CV_64F);
    for(int i=0; i<n; i++)
    {
        double x = srcPoints[i].x, y = srcPoints[i].y;
        double rowI[m] = {x, y, 1};
        Mat(1,m,CV_64F,rowI).copyTo(A.row(i));
        xc.at<double>(i,0) = dstPoints[i].x;
        yc.at<double>(i,0) = dstPoints[i].y;
    }

    // solve linear equations (for x and for y)
    Mat aTa, resX, resY;
    mulTransposed(A, aTa, true);
    solve(aTa, A.t()*xc, resX, DECOMP_CHOLESKY);
    solve(aTa, A.t()*yc, resY, DECOMP_CHOLESKY);

    // store result
    memcpy(transf.ptr<double>(0), resX.data, m*sizeof(double));
    memcpy(transf.ptr<double>(1), resY.data, m*sizeof(double));

    return true;
}
Run Code Online (Sandbox Code Playgroud)