opencv:矩阵分配混乱

YW *_*won 3 c++ opencv matrix assignment-operator

任何人都可以验证/回答我的理解/问题吗?

在OpenCV中,假设

Mat A; // Suppose A has some values in it
Mat B=A;
Run Code Online (Sandbox Code Playgroud)
  1. 如果我更新B,A也会受到影响.对?它似乎基本上通过引用分配.

假设一个函数"void a_function(Mat argument){..//change argument ..}".

  1. 在你打电话给"a_function(A)"之后,A也会受到影响,对吧?

  2. 那么,为什么(或者在哪种情况下)我们需要"void a_function(Mat&argument)",如果它已经通过引用调用了?&这里可以有特殊意义吗?

  3. 如果你不希望A受到函数调用的影响,哪一个更好习惯?

    • 打电话给a_function(A.clone())
    • 通过调用a_function(A)并声明函数使用const Mat &argument并将责任留给函数?

假设您需要计算像行一样的跨行产品

L.row(i) = A.row(i).cross(B.row(i));
Run Code Online (Sandbox Code Playgroud)
  1. 在这种情况下,我可以安全地使用没有'clone()'的赋值的原因是中间结果矩阵(来自cross函数)将很快消失(?)(当退出当前本地范围时),对吧?

kar*_*lip 8

1.是的.

证明:

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;
Run Code Online (Sandbox Code Playgroud)

2.是的.

证明:

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;
Run Code Online (Sandbox Code Playgroud)

3.当a Mat指定为带或不带引用的函数参数&,该类在内部使用智能指针指向原始数据而不是复制它.

证明:

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;
Run Code Online (Sandbox Code Playgroud)

由于&在这种情况下的使用没有任何区别,正如您所指出的,我相信使用它可以提高可读性:不了解内部工作的人Mat可能担心如果参数是正在制作副本指定没有&.

4.它是品味问题.我更喜欢const Mat& img因为我认为它对C/C++程序员来说更清晰,更明显.

并回答最后一个问题:

5.是的.

证明:

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;
Run Code Online (Sandbox Code Playgroud)