2014-09-25 219 views
1

任何人都可以验证/回答我的理解/问题吗?opencv:矩阵分配混淆

在OpenCV中,假设

Mat A; // Suppose A has some values in it 
Mat B=A; 
  1. 如果我更新B,A也受影响。对?它似乎基本上通过引用分配。

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

  1. 当您调用“a_function(A)”后,A也会受到影响,对吧?那么,为什么(或在这种情况下)我们是否需要“void a_function(Mat & argument)”(如果它已经通过引用调用)? &可以在这里有特殊的含义吗?

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

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

假设你需要计算的行方向的横产品如

L.row(i) = A.row(i).cross(B.row(i)); 
  • 在这种情况下,我可以放心地使用这种分配没有理由'clone()'是中间结果矩阵(从cross函数)很快就会消失(?)(当退出当前的本地作用域时),对吧?
  • 回答

    4

    是。

    证明:

    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.是。

    证明:

    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.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; 
    

    因为在这种情况下使用&不有所作为,正如你指出的那样,我相信使用就可以增强可读性:人是不知道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;