Could anyone verify/answer my understandings/questions?
In OpenCV, suppose
Mat A; // Suppose A has some values in it
Mat B=A;
Suppose a function "void a_function(Mat argument) {..//change argument..}".
After you call "a_function(A)", A is also affected, right?
Then, why (or in which case) do we need "void a_function(Mat &argument)" if it is already calling by reference? Can &
have a special meaning here?
If you don't want A to be affected by the function call, which one is better habit?
a_function(A.clone())
?a_function(A)
and declaring the function using const Mat &argument
and leaving the responsibility to the function?Suppose you need to calculate row-wise cross product like
L.row(i) = A.row(i).cross(B.row(i));
cross
function) will be gone/disappear(?) soon (when exiting the current local scope), right?1. Yes.
Proof:
cv::Mat A = (cv::Mat_<double>(2,2) << 1.0, 2.0, 3.0, 4.0);
std::cout << "Original A:\n" << A << std::endl;
cv::Mat B = A;
B.at<double>(0, 1) = 2.5;
std::cout << "A:\n" << A << std::endl;
std::cout << "B:\n" << B << std::endl;
2. Yes.
Proof:
void a_function(cv::Mat C)
{
C.at<double>(1, 0) = 3.5;
}
cv::Mat A = (cv::Mat_<double>(2,2) << 1.0, 2.0, 3.0, 4.0);
std::cout << "Original A:\n" << A << std::endl;
a_function(A);
std::cout << "A:\n" << A << std::endl;
3. When a
Mat
is specified as a function parameter with or without the reference&
, the class uses smart pointers internally to point to the original data instead of copying it.
Proof:
void some_function(cv::Mat C)
{
C.at<double>(1, 0) = 3.5;
}
void another_function(cv::Mat& C)
{
C.at<double>(1, 0) = 3.6;
}
cv::Mat A = (cv::Mat_<double>(2,2) << 1.0, 2.0, 3.0, 4.0);
std::cout << "Original A:\n" << A << std::endl;
a_function(A);
std::cout << "A:\n" << A << std::endl;
cv::Mat B = (cv::Mat_<double>(2,2) << 1.0, 2.0, 3.0, 4.0);
std::cout << "Original B:\n" << B << std::endl;
a_function(B);
std::cout << "B:\n" << B << std::endl;
Since the use of &
in this case doesn't make a difference, as you pointed out, I do believe using it improves readability: people that are not aware of the internal workings of a Mat
might fear that a copy is being made if the parameter is specified without &
.
4. It's a matter of taste. I prefer
const Mat& img
because I think its cleaner and more obvious to C/C++ programmers.
And to answer the last question:
5. Yes.
Proof:
cv::Mat L = (cv::Mat_<double>(1,3) << 0.0, 0.0, 0.0);
cv::Mat E = (cv::Mat_<double>(1,3) << 1.0, 2.0, 3.0);
cv::Mat F = (cv::Mat_<double>(1,3) << 4.0, 5.0, 6.0);
L = E.row(0).cross(F.row(0));
std::cout << "E:\n" << E << std::endl;
std::cout << "F:\n" << F << std::endl;
std::cout << "L:\n" << L << std::endl;