2012-06-13 47 views
13

我是opencv的新手,我對編碼中最簡單的操作之一有疑問:將值傳遞給函數。簡單傳遞矩陣即。 cv :: Mat在OpenCV2.4中的功能

繼承人是我想做的事,

  1. 與發言權的主要功能初始化cv:Mat,從0到50
  2. 值通過這個矩陣作爲參數傳遞給函數foo()這又簡單打印矩陣中每個元素的值。而已。

現在我已經閱讀了多個地方,當這些矩陣被傳遞時,它只是被傳遞的頭,而不是實際的數據。那麼我怎麼仍然能夠讀出被調用函數中這個矩陣的值,就像整個矩陣被傳遞一樣?

+0

這些地方在哪裏?你可以分享他們的參考嗎? – karlphillip

+0

http://opencv.willowgarage.com/documentation/cpp/memory_management.html –

回答

31

要了解發生了什麼事情,你需要看一看C++ constructors,更具體copy constructor

當你從另一個cv::Mat創建cv::Mat,如:

cv::Mat a = cv::imread("huge.png", 1); 
cv::Mat b = a; 

拷貝構造函數(這是一個函數)cv::Mat被調用來執行對象的副本。在我談論複製過程中會發生什麼情況之前,您必須認識到,由於cv::Mat用於存儲圖像,較大的圖像可能會在內存中佔用數百兆字節。那麼在上面的例子中,的的整個標題(高度,寬度,深度信息和其他)被拷貝到b中,但是拷貝a的全部數據/像素(其可能是數百個的MB),它只是指向(使用指針)原始數據a

換句話說,不復制整個圖像數據的是優化/性能決定

現在,考慮下面的代碼調用一個函數,並傳遞cv::Mat作爲參數:

void do_something(cv::Mat src) 
{ 
    // changing src pixels will be the same as changing orig pixels 
} 

int main() 
{ 
    cv::Mat orig = cv::imread("huge.png", 1); 
    do_something(orig); 
    return 0; 
} 

如果你已經研究如何將參數傳遞給函數,你知道,調用do_something(a);pass the parameter by value。這意味着它會嘗試將orig的內容複製到src中,但是,此過程將激活cv::Mat的複製構造函數,這不會像我剛剛解釋的那樣製作數據的硬拷貝。

解決此問題的方法?如果你正在寫do_something()只想和你做的orig一個真正的副本,只需要創建一個新的cv::Mat並調用該方法copyTo()

void do_something(cv::Mat src) 
{ 
    cv::Mat real_copy = src.copyTo(); 
    // operating on the data of real_copy will not affect orig 
} 

但要記住,如果src是〜100MB叫copyTo(),使真正的副本將佔用另一個〜100MB的內存,這意味着在一個函數調用中你的程序從100MB變爲200MB。設計系統時請記住這一點。祝你好運。

+4

優秀。它就像你讀我的思想,回答我的確切問題。先生非常感謝您。非常感激。 –

+1

很酷,只需點擊附近的複選框將其選爲官方答案即可。 – karlphillip