Ask Your Question
0

how to remove specific rows from a matrix

asked 2016-04-26 08:11:56 -0600

I want to delete the rows containing all zeros from a matrix... I can do so in MATLAB but how can I do it in OpenCV? I've searched over the internet but could not understand....

edit retag flag offensive close merge delete

Comments

LBerger gravatar imageLBerger ( 2016-04-26 08:48:59 -0600 )edit

1 answer

Sort by » oldest newest most voted
2

answered 2016-04-26 12:08:50 -0600

berak gravatar image

updated 2016-04-26 12:09:57 -0600

based on the nice answer to the similar question, i'd like to propose a user-defined operation:

#include "opencv2/opencv.hpp"
using namespace cv;

#include <iostream>
using namespace std;

// function to decide, which elements should be removed.
//   rc is the row or column to check
//   returns true, if the item should get removed.
typedef bool (*remove_predicate)(const Mat &rc);

void remove_if(const Mat &mat, Mat &res, remove_predicate pred, bool removeRows=true)
{
    res.release();
    int n = removeRows ? mat.rows : mat.cols;
    for (int i=0; i<n; i++)
    {
        Mat rc = removeRows ? mat.row(i) : mat.col(i);
        if (pred(rc)) continue; // remove element
        if (res.empty()) res = rc;
        else 
        {
            if (removeRows)
                vconcat(res,rc,res);
            else
                hconcat(res,rc,res);
        }
    }
}

//
// now, we can just make a decision function,
// say, if it's all 0, remove it:
//
bool is_zero(const Mat &rc)
{
    return (sum(rc)[0]==0);
}

//
// or, build your own, very special classifier:
//
bool second_is2(const Mat &rc)
{
    return (rc.at<uchar>(1) == 2);
}

// demo code:
void main()
{
    Mat mat = (Mat_<uchar>(5, 5) << 1, 2, 3, 4, 0,
                                    0, 0, 0, 0, 0,
                                    2, 2, 4, 5, 0,
                                    0, 0, 0, 0, 0,
                                    0, 0, 0, 8, 0);
    cout << "original mat: " << endl << mat << endl;

    Mat res;
    remove_if(mat, res, is_zero, false);
    cerr << "remove zero colums: " << endl << res << endl;

    remove_if(mat, res, is_zero, true);
    cerr << "remove zero rows: " << endl << res << endl;

    remove_if(mat, res, second_is2, true);
    cerr << "remove all rows where the 2nd elem is 2: " << endl << res << endl;
}


original mat:
[  1,   2,   3,   4,   0;
   0,   0,   0,   0,   0;
   2,   2,   4,   5,   0;
   0,   0,   0,   0,   0;
   0,   0,   0,   8,   0]
remove zero colums:
[  1,   2,   3,   4;
   0,   0,   0,   0;
   2,   2,   4,   5;
   0,   0,   0,   0;
   0,   0,   0,   8]
remove zero rows:
[  1,   2,   3,   4,   0;
   2,   2,   4,   5,   0;
   0,   0,   0,   8,   0]
remove all rows where the 2nd elem is 2:
[  0,   0,   0,   0,   0;
   0,   0,   0,   0,   0;
   0,   0,   0,   8,   0]
Drücken Sie eine beliebige Taste . . .
edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2016-04-26 08:11:56 -0600

Seen: 2,467 times

Last updated: Apr 26 '16