OpenCV changes the matrix inside the function (layout area)

I pass Mat to another function and change it inside the called function. I expected that, being a more complex type, it is automatically passed by reference so that the matrix changes in the calling function, but that is not the case. Can someone point me to an explanation of how to correctly return a modified Mat from a function?

Here's the code snippet:

void callingFunction(Mat img) { Mat tst(100,500,CV_8UC3, Scalar(0,255,0)); saveImg(tst, "Original image", true); testImg(tst); saveImg(tst, "Want it to be same as inside testImg but is same as Original", true); } void testImg(Mat img) { int rs = 50; // rows int cs = 100; // columns img = Mat(rs, cs, CV_8UC3, Scalar(255,0,0)); Mat roi(img, Rect(0, 0, cs, rs/2)); roi = Scalar(0,0,255); // change a subsection to a different color saveImg(img, "inside testImg", true); } 

Thanks!

+7
source share
3 answers

You must define Mat as a reference parameter (&). Here's the edited code:

 void callingFunction(Mat& img) { Mat tst(100,500,CV_8UC3, Scalar(0,255,0)); saveImg(tst, "Original image", true); testImg(tst); saveImg(tst, "Want it to be same as inside testImg but is same as Original", true); } void testImg(Mat& img) { int rs = 50; // rows int cs = 100; // columns img = Mat(rs, cs, CV_8UC3, Scalar(255,0,0)); Mat roi(img, Rect(0, 0, cs, rs/2)); roi = Scalar(0,0,255); // change a subsection to a different color saveImg(img, "inside testImg", true); } 
+8
source

I was wondering about the same question, so I would like to clarify again the answer given by @ArtemStorozhuk (which is true).

The OpenCV documentation is misleading because it seems like you are passing the matrix by value, but in fact the cv :: OutputArray constructor is defined as follows:

 _OutputArray::_OutputArray(Mat& m) 

so he gets the matrix by reference!

Since operations such as cv :: Mat :: create create a new matrix, the operation releases the link and sets the bit to 1. Thus, to save the result in the calling function, you must pass the Help matrix.

+2
source

If it’s true that you must explicitly pass by reference, then how do all the functions of OpenCV work? None of them pass values ​​by reference, but somehow they seem to write the passed in Mat very well. For example, here is the declaration of the Sobel function in imgproc.hpp:

 //! applies generalized Sobel operator to the image CV_EXPORTS_W void Sobel( InputArray src, OutputArray dst, int ddepth, int dx, int dy, int ksize=3, double scale=1, double delta=0, int borderType=BORDER_DEFAULT ); 

as you can see, it goes into src and dst without &. And yet I know that after I call Sobel with an empty dst, it will be filled. No '&' involved.

-2
source

All Articles