1 | initial version |
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=false)
{
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 . . .
2 | No.2 Revision |
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=false)
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 . . .