0
votes

I would like to use some STL algorithms for my openCV app. Right now, I would like to mirror the img. I want to reverse the order of rows, columns and both rows an columns. When I type:

    // Horizontal and vertical mirror
    MatIterator_<cv::Vec3b> it  = img.begin<cv::Vec3b>();
    MatIterator_<cv::Vec3b> end = img.end<cv::Vec3b>();

    std::reverse(it, end);

It works like a charm.

But when I try to iterate through single column or row

    MatIterator_<cv::Vec3b> it  = img.col(0).begin<cv::Vec3b>();
    MatIterator_<cv::Vec3b> end = img.col(0).end<cv::Vec3b>();

    std::reverse(it, end);

I get an exception from invoking the std::reverse:

OpenCV(4.1.1) Error: Assertion failed (i >= 0) in cv::MatSize::operator [], file C:\build\master_winpack-build-win64-vc14\opencv\modules\core\include\opencv2/core/mat.inl.hpp, line 1465
OpenCV(4.1.1) C:\build\master_winpack-build-win64-vc14\opencv\modules\core\include\opencv2/core/mat.inl.hpp:1465: error: (-215:Assertion failed) i >= 0 in function 'cv::MatSize::operator []'

Mat::col(int number) returns the Mat obj. with the dimensions of [img height x 1], so why get I such an error? The same happens with Mat::row...

1

1 Answers

0
votes

I think you are dealing with a dangling reference problem, from the documentation of row() which is referenced by col()

Creates a matrix header for the specified matrix row.

The method makes a new header for the specified matrix row and returns it.

The docs stress the fact that that col() or row() share the data with the original matrix, so there's no copy of the buffer, but you still need your Matobject object to know other information, for example the dimensions. Stepping through the problem with the debugger I can see that it crashes because the dimensions of the matrix it points to are 0. The matrix it points to is the one returned by col() that has stopped existing after your first line. You can fix your code making sure that the column matrix survives until it is needed no more:

auto col = img.col(0);
cv::MatIterator_<cv::Vec3b> it = col.begin<cv::Vec3b>();
cv::MatIterator_<cv::Vec3b> end = col.end<cv::Vec3b>();
std::reverse(it, end);