Simple passing of Matrices ie. cv::Mat to functions in OpenCV2.4
c++, image-processing, opencv
Solution
To understand what's going on you need to take a look at C++ constructors, more specifically the copy constructor.
When you create a `cv::Mat` from another `cv::Mat`, as in:
cv::Mat a = cv::imread("huge.png", 1);
cv::Mat b = a;
the copy constructor (which is a function) of `cv::Mat` is called to perform the copy of the object. Before I talk about what happens in the copy procedure, you must realize that as `cv::Mat` is used to store images, larger images might occupy hundreds of megabytes in memory. So what the copy constructor of `cv::Mat` does in the example above is copy the entire header (height, width, depth info and others) of `a` into `b`, but instead of copying the entire data/pixels of `a` (which might be hundreds of MB), it just points (using a pointer) to the original data of `a`.
In other words, not copying the entire image data is an optimization/performance decision.
Now, consider this code that calls a function and passes `cv::Mat` as a parameter:
void do_something(cv::Mat src)
{
// changing src pixels will be the same as changing orig pixels
}
int main()
{
cv::Mat orig = cv::imread("huge.png", 1);
do_something(orig);
return 0;
}
If you have studied how to pass parameters to functions, you know that calling `do_something(a);` will pass the parameter by value. This means that it will try to copy the content of `orig` into `src`, however, this procedure activates the copy constructor of `cv::Mat` which will not make a hard copy of the data as I've just explained.
Solution to this problem? If you are writing `do_something()` and you just want to make a real copy of `orig`, just create a new `cv::Mat` and call the method `copyTo()`:
void do_something(cv::Mat src)
{
cv::Mat real_copy = src.copyTo();
// operating on the data of real_copy will not affect orig
}
But remember, if `src` is ~100MB calling `copyTo()` to make the real copy will occupy another ~100MB of memory, which means that in a single function call your program just went from 100MB to 200MB. Keep this in mind when designing your system. Good luck.
Problem
I am new to opencv and I have a doubt with one of the simplest operations in coding: Passing values to functions. Heres what I want to do, - Initialize a `cv:Mat` in the main function with say, values from 0 to 50. - Pass this matrix as an argument to a function `foo()` which in turn simply prints out the values of each element in the matrix. Thats it. Now I have read in multiple places that when these matrices are passed, it is only the header that gets passed, not the actual data. Then how am I still able to read out the values of this matrix in the called function as if the entire matrix was passed?