well I’m a little confused about passing Mat to function and retrieving it so what is the difference between let's say
void GetFrame(Mat& frame)
void GetFrame(Mat frame)
in which version the changes to frame inside the function body will result in change in the original frame passed to function
Best How To :
With a bit of care, you can get all 3 versions to work and do the same thing, but I will try to explain the details.
Mat object is really just a small header which contains metadata about the real data, (eg, number of rows and columns), and a pointer to the actual data. In most cases, the pointer is actually a smart pointer, with reference counting, and can be shared by multiple
Mat objects, and automatically deleted when the last remaining
Mat object stops pointing to it. (
Mat objects can also point to data it doesn't own, ie if you have some data you got from a different library/API, and want to reuse the same memory rather than copy it.)
1. Pass by reference version
Version 1 of your function is perhaps the simplest. The caller's
Mat object is copied by reference, which obviously means that any modifications to the
Mat object's metadata (including the (smart) pointer) will be visible to the caller upon return. The underlying data will obviously reflect any modification made by the function.
2. Pass by value version
In version 2 of your function (passing in a
Mat object by value), the small header represented by
Mat is copied and passed to the function. The copy is shallow: metadata and the (smart) pointer is copied, but the underlying data is shared by the caller's
Mat object and the callee's
Mat object. The part that you have to be careful is that if the function modifies the metadata of the copied
frame object, these changes will not be visible to the caller.
So for example, if you pass an empty
Mat, you may be surprised with the result: First, the meta-data of the empty
Mat is copied. When the function calls something like
frame.create(newRows, newCols, newType);, the
create function will allocate a new chunk of memory since
frame.rows != newRows,
frame.cols != newCols, and
frame.type() != newType, and the (callee's copy alone of)
frame metadata is updated reflect the newly allocated data. When the function returns, its
frame object will hold the only reference to the smart pointer, so the data will be automatically discarded. The caller will still have just an empty header.
If, however, the
Mat object that is passed in to the function already has the correct dimensions and type,
frame.create() will do nothing, which means that any modification made by the callee to the underlying data will be visible to the caller.
3. Return by value version
The 3rd version is similar to the second, except that rather than making a copy of the meta-data when the function is called, the function instead allocates a
Mat however it sees fit, and the meta-data (including pointer to the underlying data) is copied back to the caller upon return. The underlying data survives and is accessible to the caller.
If you don't know the size and type of the data ahead of time, you cannot use pass-by-value. If you do know the size/type, you can use pass-by-value, and the pre-allocated memory will be used.
Pass-by-reference will use the pre-allocated memory if possible, or allocate new memory, and in either case the caller will always see the new header/data.
Return-by-value also will always work properly, but it does have to re-allocate new memory every call, which may be undesirable.