Filter the rows/columns of a Mat

asked 2013-01-17 07:38:20 -0500

Simone gravatar image

Hello,

I want to filter out the rows of a Mat according to a mask, a task that may be quite frequent in computer vision. I was wondering what's the most efficient way to do it. Suppose you have a matrix Mat A of size NxP and a mask vector<uchar> M of N elements, whose values are 0 or 255 whether the corresponding row of A is to delete or not, respectively. In Matlab would be easy to do something like

A = A(find(M),:)

to get the desired filtered matrix. In OpenCV the simplest way, i guess, to do something like that is to build another matrix copying row by row, so something like this:

Mat result = Mat( countNonZero(M), A.cols, A.type );
for(int i=0, k=0; i<M.size(); ++i )
{
    if( M[i] )
    {
        A.row( i ).copyTo( result.row( k++ ) );
    }
 }

This works just fine, but I was wondering if there is a more efficient method (computationally and/or from memory use point of view), such as for example casting somehow (i'm just fumbling here..) A to a vector of some sort and use the built-in delete of vector.

Also, another variant of the same problem is when you have as mask a vector<uchar> M of size K with K<=N storing the index of the rows of A to be keep in the new version of the matrix. Again a simple way to do it is:

Mat result = Mat( M.size(), A.cols, A.type );
for(int i=0; i<M.size(); ++i )
{
    CvAssert( M[i] < A.rows );
    A.row( M[i] ).copyTo( result.row( i ) );
}

Any comments? :-)

Thanks!

S.

edit retag flag offensive close merge delete