First time here? Check out the FAQ!

Ask Your Question
0

Removing the zero rows.

asked Oct 27 '15

Pranav gravatar image

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

Preview: (hide)

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 (Oct 27 '15)edit

1 answer

Sort by » oldest newest most voted
1

answered Oct 27 '15

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

Preview: (hide)

Comments

You remove inner rows? Is it correct?

thdrksdfthmn gravatar imagethdrksdfthmn (Oct 27 '15)edit

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

thdrksdfthmn gravatar imagethdrksdfthmn (Oct 27 '15)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 (Oct 27 '15)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 (Oct 28 '15)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 (Oct 28 '15)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 (Oct 28 '15)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 (Oct 28 '15)edit

Question Tools

1 follower

Stats

Asked: Oct 27 '15

Seen: 1,800 times

Last updated: Oct 27 '15