Removing the zero rows.
Is there any way by which we can remove the zero rows in any matrix in opencv 3.0.0?
Is there any way by which we can remove the zero rows in any matrix in opencv 3.0.0?
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;
}
@thdrksdfthmn I do not understand what you want to say, can you explain it a bit more. Also maybe provide an example :-).
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? :)
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
?
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"?
Asked: 2015-10-27 05:45:47 -0600
Seen: 1,785 times
Last updated: Oct 27 '15
GpuMat misses operators, and functions that compared with Mat
Bug with GpuMat::GpuMat(const GpuMat& m, Rect roi)
installing two versions of opencv
Building current 3.0 dev branch Ubuntu 14.04
No EM in the official GIT repository [closed]
opencv3.0 illuminationChange Issue and bug fix [closed]
OpenCV Alpha 3.0 - What is the license for the subset of IPP that is linked to this version?
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);