Object that is passed to function is changed, although no pointer is passed

Hey there,

I am posting this simplified piece of code that is a bit confusing for me. There are two functions that I call. One shows the expected results but the result of the other one rather puzzles me.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
//#define defineVecTyp Vec3f
#define defineVecTyp float


template <typename vecTyp>
vecTyp buildLaplacianPyramid(cv::Mat inputmat) {
    vecTyp lapPyr;

    GaussianBlur(inputmat,inputmat,Size(GaussSize,GaussSize),0.0,0.0);
	code ...

    return lapPyr;
}


int sum1(int int1, int int2)
{
    int1=int1*2;
    int2=int2*2;

    int sum=int1+int2;
    return sum;
}


int main()
{

    int val1=1;
    int val2=10;
    int sumOfVals;

    cout << "val1= " << val1 << " ## val2= " << val2 << endl;

    sumOfVals=sum1(val1,val2);
    cout << "val1= " << val1 << " ## val2= " << val2 << endl;
    cout << "sumOfVals= " << sumOfVals << endl;


    cv::Mat M1;
    M1=imread("../image1.jpeg");
    imshow("M1",M1);


    vector<Mat_<defineVecTyp> > LaplacianPyramid;
    LaplacianPyramid = buildLaplacianPyramid< vector<Mat_<defineVecTyp> > >(M1);
    imshow("M1, after buildLaplacianPyramid",M1);


    return 0;
}




Calling the function sum1 does not change the values stored in the variables val1 and val2. The output of the program is as follows:
val1= 1 ## val2= 10 // before the call of function sum1
val1= 1 ## val2= 10 // after the call of function sum1
sumOfVals= 22

This is quite obvious and as expected and I just pasted this piece of code as an example for better clarification.


However, if I call the function buildLaplacianPyramid and apply a function for Gaussian Blurring, this also effects the cv::Mat passed to the function. The line
imshow("M1, after buildLaplacianPyramid",M1);
therefore shows an image that is blurred. Since I am not passing a pointer to the cv::Mat I do not understand why this should be happening.
I was assuming that there would be a copy of the cv::Mat M1 to be used within the function. Therefore I was expecting the cv::Mat M1 to retain its original value. I was expecting that all changes applied to cv::Mat inputmat within the function would not have any influence on the cv::Mat M1. Just like in my other example with the sum.

Does anybody have an idea how to explain this behaviour?!
I am grateful for any hints.
Thanks


> Since I am not passing a pointer to the cv::Mat I do not understand why this should be happening.

The copy constructor of cv::Mat does not do a deep copy.

To get value semantics, clone the object.

buildLaplacianPyramid< ... >( M1.clone() ) ;
JLBorges wrote:
The copy constructor of cv::Mat does not do a deep copy
I.e., cv::Mat behaves a similar to std::shared_ptr. The matrix data isn't copied by assignment, instead, it gives a pointer to the existing data and increments a reference counter. This is done to protect against extreme memory usage which, without this type of feature, would be really easy to overlook in programs using OpenCV.
Thanks for the quick response!
Now that you mention it, it really makes a lot of sense to NOT copy the complete data.
Basically it would not have been a big problem to work around it, but I was not sure if the problem was due to some kind of mistake of mine. Now I know...
Topic archived. No new replies allowed.