【问题标题】:OpenCV Mat in function return and using copyTo函数返回中的 OpenCV Mat 并使用 copyTo
【发布时间】:2015-07-16 00:04:01
【问题描述】:

我有这个 sn-p 来执行齐次矩阵的逆

Mat invHom(const Mat A)
{
    Mat invA = Mat::eye(4,4,CV_64FC1);
    Mat R, P;

    A(Range(0,3), Range(0,3)).copyTo(R);
    A(Range(0,3), Range(3,4)).copyTo(P);

    invA(Range(0,3), Range(0,3)) = R.t();
    invA(Range(0,3), Range(3,4)) = -R.t()*P;
    return invA;
}

此代码是否容易出错?因为 invA、R、P 是在函数范围内创建的 Mat。函数的“返回”是否执行创建和复制到新的 Mat 对象(即 Mat::copyTo()),以便 invA 的值在函数外部仍然可用?

抱歉我的英语和编程条件不好

没有错误的:

int invHom(const Mat A, Mat& invA_ou)
{
    Mat invA = Mat::eye(4,4,CV_64FC1);

    Mat R, P;
    A(Range(0,3), Range(0,3)).copyTo(R);
    A(Range(0,3), Range(3,4)).copyTo(P);

    //invA(Range(0,3), Range(0,3)) = R.t();
    //invA(Range(0,3), Range(3,4)) = -R.t()*P;

    Mat tmp1 = R.t();
    tmp1.copyTo(invA(Range(0,3), Range(0,3)));

    Mat tmp = -R.t()*P;
    tmp.copyTo(invA(Range(0,3), Range(3,4)));

    invA.copyTo(invA_ou);
    return 1;
}

【问题讨论】:

    标签: c++ c opencv


    【解决方案1】:

    代码没问题。 Mat 是一个对象,基本上由标题和实际数据组成。当您复制 Mat 时,您只是在复制标题,而不是数据(这就是它非常快的原因)。复制时,内部引用计数器会递增。当引用计数器为零时,数据将被释放。 要执行深层复制,您需要方法clone()copyTo(...)

    所以,在你的情况下,你很好。

    您可以查看 OpenCV 文档 here 了解更多详细信息。

    另一种编码风格是将输出矩阵作为参数传递,例如:

    void invHom(const Mat& A, Mat& invA)
    {
        invA = Mat::eye(4,4,CV_64FC1);
        Mat R, P;
    
        A(Range(0,3), Range(0,3)).copyTo(R);
        A(Range(0,3), Range(3,4)).copyTo(P);
    
        invA(Range(0,3), Range(0,3)) = R.t();
        invA(Range(0,3), Range(3,4)) = -R.t()*P;        
    }
    

    请注意,将引用 (&) 传递给 Mat,您甚至不需要复制标头。

    【讨论】:

    • 问题是我的复制是从函数内部创建的对象进行的,所以函数返回后,主调用者​​不会收到这个值
    • 您的 return 语句将复制 Mat(标题),这将为函数内部创建的数据增加引用计数器。当你退出函数时,引用计数器会减少,但数据不会被取消,因为它们仍然被返回的 Mat 引用
    • 如果你想确定,直接返回invA.clone(),但这是不必要的深拷贝。
    • 感谢您的解释!我想更多地了解这种增加引用计数器并在函数存在时减少它的机制。您能帮我解决一些术语,例如 c/c++ 术语吗?
    • 嗨@ray没问题:)我应该检查(可能明天),但是......掩码中的0个元素没有被复制。如果矩阵未初始化,则创建矩阵以正确大小进行零初始化(应检查),然后像以前一样。我从来没有使用带有面具的copyTo。可能 setTo 是您需要的。
    猜你喜欢
    • 2018-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多