Ask Your Question
0

Removing the zero rows.

asked 2015-10-27 05:45:47 -0600

Pranav gravatar image

Is there any way by which we can remove the zero rows in any matrix in opencv 3.0.0?

edit retag flag offensive close merge delete

Comments

I do not think so; it is not an function that is needed, but you can do it by a roi: cv::Mat no0rowsImg = initImage(no0rowRect);

thdrksdfthmn gravatar imagethdrksdfthmn ( 2015-10-27 06:04:27 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
1

answered 2015-10-27 09:13:08 -0600

theodore gravatar image

you just need to know which rows you want to remove and then you can just use the removeRow() function below:

void removeRow(InputOutputArray _matIn, int row, int method = METHOD::CV_RECT)
{
    CV_Assert( row >= 0 && row < _matIn.getMat().rows );

    Mat matIn = _matIn.getMat();
    cv::Size size = matIn.size();
    Mat matOut( matIn.rows - 1, matIn.cols, matIn.type());

    if ( row > 0 )
    {
        cv::Rect rect( 0, 0, size.width, row );
        matIn( rect ).copyTo( matOut( rect ) );
    }

    if ( row < size.height - 1 )
    {
        cv::Rect rect1( 0, row + 1, size.width, size.height - row - 1 );
        cv::Rect rect2( 0, row, size.width, size.height - row - 1 );
        matIn( rect1 ).copyTo( matOut( rect2 ) );
    }
    matOut.copyTo(_matIn);
}


int main()
{
    // Example case
    Mat mat = (Mat_<uchar>(5, 5) << 1, 2, 3, 4, 0,
                                  0, 0, 0, 0, 0,
                                  12, 13, 14, 15, 16,
                                  0, 0, 0, 0, 0,
                                  0, 0, 0, 8, 0);

    cout << "mat: " << endl << mat << endl;

    // Find all non zero rows and set in a vector as indexes
    Mat nonZeroCoordinates;
    findNonZero(mat, nonZeroCoordinates);

    vector<int> nonZeroRows;

    for(size_t i = 0; i < nonZeroCoordinates.rows; ++i)
    {
        int row = nonZeroCoordinates.at<Point>(i).y;
        if(!(std::find(nonZeroRows.begin(), nonZeroRows.end(), row) != nonZeroRows.end()))
        {
            //elem does not exists in the vector
            nonZeroRows.push_back(row);
        }
    }

    // Create a zeros rows indexer, according to the non zero indexes
    vector<int> zeroRows(mat.cols);
    std::iota(zeroRows.begin(), zeroRows.end(), 0);

    std::sort(nonZeroRows.begin(), nonZeroRows.end());

    for(int i = nonZeroRows.size() - 1; i >= 0; i--)
        zeroRows.erase( std::next( zeroRows.begin(), nonZeroRows[i] ) );

    // remove rows
    for(int i = 0; i < zeroRows.size(); ++i)
    {
        removeRow(mat, zeroRows[i]);
        // decrease index values since the form of the mat changes
        transform(zeroRows.begin(), zeroRows.end(), zeroRows.begin(), bind2nd(std::minus<int>(), 1));
    }

    cout << endl << "removedRowsMat: " << endl << mat << endl;

return 0;
}

image description

edit flag offensive delete link more

Comments

You remove inner rows? Is it correct?

thdrksdfthmn gravatar imagethdrksdfthmn ( 2015-10-27 11:00:01 -0600 )edit

Isn't it faster to erase or push_back than to copy?

thdrksdfthmn gravatar imagethdrksdfthmn ( 2015-10-27 11:03:16 -0600 )edit

@thdrksdfthmn I do not understand what you want to say, can you explain it a bit more. Also maybe provide an example :-).

theodore gravatar imagetheodore ( 2015-10-27 11:18:20 -0600 )edit

if you want to remove row x, then do a newImg.push_back(oldimg(roi_0_to_Xminus1)); newImg.push_back(oldimg(roi_Xminus1_to_rowsNumber)); is it more clear now? :)

thdrksdfthmn gravatar imagethdrksdfthmn ( 2015-10-28 03:29:47 -0600 )edit
1

thanks @thdrksdfthmn yes it is clear now. But one question is pushing back makes a copy of the data or it just points to the data of the original Mat?

theodore gravatar imagetheodore ( 2015-10-28 05:32:08 -0600 )edit

Good questin! Logically, it should insert data in the Mat, so it should not be linked to the other one... Have you tested it, I am not 100%sure, not docs about it, except "They emulate the corresponding method of the STL vector class"?

thdrksdfthmn gravatar imagethdrksdfthmn ( 2015-10-28 07:37:39 -0600 )edit
1

I see, no I haven't tested it but I will do it as soon as I find some time. Thanks again though ;-).

theodore gravatar imagetheodore ( 2015-10-28 07:50:24 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2015-10-27 05:45:47 -0600

Seen: 1,786 times

Last updated: Oct 27 '15