Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opencv 如果在EstimaterialGidTransform或getAffineTransform中提供更多输入,会发生什么?_Opencv - Fatal编程技术网

Opencv 如果在EstimaterialGidTransform或getAffineTransform中提供更多输入,会发生什么?

Opencv 如果在EstimaterialGidTransform或getAffineTransform中提供更多输入,会发生什么?,opencv,Opencv,我使用的是大约两个100点的向量的变换,效果很好。 但无论如何,getAffineTransform不起作用 我知道findHomography使用RANSAC找到最佳矩阵,getPerspectiveTransform只需要4个点 我的问题是,如果我在EstimaterialGidTransform或getAffineTransform中提供更多输入,会发生什么 它是否只需要输入矩阵中的4个点?或者做一些RANSAC?您提到的功能可以分为3种不同类型: 类型1:getAffineTransfo

我使用的是大约两个100点的向量的变换,效果很好。 但无论如何,getAffineTransform不起作用

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

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


它是否只需要输入矩阵中的4个点?或者做一些RANSAC?

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

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

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

类型3:findHomography。这个更先进。它不仅可以处理点位置的错误,而且还可以处理异常值的存在。如果点之间存在一些错误的匹配,那么使用它们进行最小二乘误差估计将导致非常差的精度。它可以使用RANSAC或LMeDs测试可能的匹配,并消除这些异常值。它的工作原理类似于变换的多次迭代:为不同的点子集找到最小二乘匹配。如果您知道不存在异常值,则可以将“method”参数设置为0,它的工作方式与EstimaterialGidTransform类似—通过尝试最小化所有点匹配产生的最小二乘误差

编辑。感谢米卡的评论。

我想我的记忆力在捉弄我。我记得这个转换是通过OpenCV中的方程组实现的,但现在我检查了一下,发现米卡是对的。它确实使用了一些硬编码的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;
}
//查找两个点集之间的仿射变换(使用最小二乘匹配)
静态布尔计算函数(常量向量和srcPoints、常量向量和dstPoints、Mat和transf)
{
//健康检查
如果((srcPoints.size()<3)| |(srcPoints.size()!=dstPoints.size())
返回false;
//输出容器
转换创建(2,3,CV_64F);
//填写矩阵
常量int n=(int)srcPoints.size(),m=3;
材料A(n,m,CV_64F)、xc(n,1,CV_64F)、yc(n,1,CV_64F);

对于(int i=0;Iafar有人计算出,如果提供了3个以上的点,EstimaterialGidTransform会在内部使用某种RANSAC,但此RANSAC具有硬编码参数。此外,您可以使用参数
bool fullAffine
计算6自由度仿射变换
EstimaterialGidTransform
@Mika,您是对的。它使用RANSAC。至于“fullAffine”参数,默认情况下它设置为“true”,即它从3对或更多点计算仿射变换。对于线性方程优化解决方案,我想我有时可能需要它!作为您的新编辑,我们可以认为当由于使用了
RANSAC
,该点超过了3点。但是,当给定的点有一些错误的点时,我们通常会得到更糟糕的结果。为什么使用
DECOMP\u CHOLESKY