2014-09-25 262 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;