TSL_
TSL_

Reputation: 2079

OpenCV Mat in function return and using copyTo

I have this snippet to perform inverse of a homogeneous matrix

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;
}

is this code tend to error? since invA, R, P are Mat created in function scope. Does the "return" of the function perform creation & copying to a new Mat object (i.e. Mat::copyTo()) so that value of invA is still available outside the function?

Sorry for my bad English and terms of programming

one with no error:

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;
}

Upvotes: 0

Views: 5920

Answers (1)

Miki
Miki

Reputation: 41765

The code is ok. Mat is an object basically composed by an header and the actual data. When you copy a Mat you're copying the header only, not the data (that's why it's very fast). When you copy, an internal reference counter is incremented. When the reference counter is zero, data will be released. To perform a deep copy, you need the method clone() or copyTo(...).

So, in your case you're fine.

You can look at OpenCV doc here for further details.

An alternative coding style would be to pass the output matrix as argument, like:

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;        
}

Note that passing references (&) to Mat, you don't even copy the header.

Upvotes: 3

Related Questions