2015-11-05 86 views
-1

我在我的代碼中的幾個地方執行以下操作;轉換爲Mat後需要釋放IplImage嗎?

cv::Mat cv_proc_image = ... 
IplImage ipl_img = cv_proc_image; 
cvSmooth(&ipl_img, &ipl_img, smooth_type, smooth_param1); 
cv_proc_image = cv::cvarrToMat(&ipl_img); 

而且我觀察到這個操作發生變化後的內存膨脹。你認爲我應該在上次作業後釋放IplImages分配的內存嗎?

+0

什麼是cv_proc_image? –

+0

它是cv :: Mat取自函數參數 – erogol

+3

如果您顯示「smooth_type」和「smooth_param1」是什麼,那麼您不應該在第一個位置使用舊的C語法 – Miki

回答

6

您不應該首先使用舊的C語法。你應該使用C++語法。另請注意,cvSmooth

該功能現已過時。使用GaussianBlur(),blur(),medianBlur()或bilateralFilter()。


UPDATE

當你做IplImage ipl_img = mat_img;你只是創建一個新的標題,沒有數據的副本。所以這不是耗盡你的記憶。讓我用一個小例子顯示它:

#include <opencv2/opencv.hpp> 
using namespace cv; 

int main() 
{ 
    // Your (green) mat 
    Mat mat_img(10, 10, CV_8UC3, Scalar(0,255,0)); 

    // To IplImage 
    IplImage ipl_img = mat_img; 

兩個mat_imgipl_img是平等的。沒有涉及的副本。

enter image description here

// It's created only a new header, on the same data 

    // In fact, changing ipl_img changes also mat_img 
    cvSet2D(&ipl_img, 1, 2, Scalar(255,0,0)); 

兩個圖像改成這樣:

enter image description here

// Same here, changing ipl_img changes also mat_img 
    cvSmooth(&ipl_img, &ipl_img); 

    return 0; 
} 

即使平滑後,他們是平等的:

enter image description here

結論

因此,要回答你原來的問題:NO,你並不需要釋放IplImage,因爲無份參與。你只是創建新的標題,但指向相同的數據。你的內存泄漏在別的地方。

您甚至不需要使用cvarrToMat,因爲對IplImage的更改與Mat中的更改相同。

+1

這不是這次討論的最佳位置,但值得注意的是,該操作沒有提到他使用的OpenCV版本,或者這是否是遺留代碼。作爲一個社區,我們需要留意,舊系統的開發人員仍然可能會提出問題。現在不管這是不是仍然是我不知道的正確答案,但實際上並沒有回答這個問題。 – GPPK

+1

我部分同意你的看法。顯然,OP不在C環境中,否則他不能使用'Mat'。所以它是C++。出於同樣的原因,該版本是相當新的。無論如何,我留下了對這個問題的評論,如果他**必須**使用C,那麼我期待他的迴應。另外,在發佈的代碼中,他只是使用舊的語法來調用一個函數,然後回到新的語法。這表明使用新的語法也可以解決問題(我的其他評論是關於給出一個完整的例子)。所以我認爲這**能夠回答這個問題,至少現在是這樣說的_now_GPPK – Miki

+0

這告訴我!我傾向於同意。 – GPPK

0

從opencv的文檔:

>  When copyData=false , the conversion is done really fast (in O(1) time) and the newly created matrix header will have refcount=0 , which 
> means that no reference counting is done for the matrix data. In this 
> case, you have to preserve the data until the new header is 
> destructed. Otherwise, when copyData=true , the new buffer is 
> allocated and managed as if you created a new matrix from scratch and 
> copied the data there. That is, cvarrToMat(arr, true) is equivalent to 
> cvarrToMat(arr, false).clone() (assuming that COI is not set). The 
> function provides a uniform way of supporting CvArr paradigm in the 
> code that is migrated to use new-style data structures internally. The 
> reverse transformation, from Mat to CvMat or IplImage can be done by a 
> simple assignment: 

在你的情況,你沒有設置 '了CopyData' 所以它默認爲false:

Mat cvarrToMat(const CvArr* arr, bool copyData=false, bool allowND=true, int coiMode=0) 

所以,你必須自己來釋放它。

編輯: 我不熟悉舊的OpenCV風格..當超出範圍時,lplimage自由地自由嗎?如果確實如此,則不會發生泄漏

+0

IplImage在超出範圍時不會自由。問題是,IplImage ipl_img = cv_proc_image;是否分配新的內存,或者是否在IplImage的內部使用了'cv_proc_image'的數據指針。如果有新的內存分配,那麼他必須手動釋放它。 – Micka