opencv中圖像複製的坑

事情是這樣的,我想把IplImage轉換到Mat,然後使用Mat做相關的處理,我是這麼幹的:

IplImage *tmpCutImg=cvCreateImage(cutSize,srcImage->depth,srcImage->nChannels);
GetImageRect(srcImage,iRect,tmpCutImg);
Mat cutMat(tmpCutImg);
cvReleaseImage(&tmpCutImg);//釋放IplImage的內存
//顯示Mat圖像
imshow("cutMat",cutMat);
waitKey(1);

然後就發現跪掉了,顯示的圖像根本是一張亂碼圖片,後來發現是因爲使用

Mat cutMat(tmpCutImg);

將IplImage轉換爲Mat時,Mat和IplImage共用數據區,在顯示Mat之前就將tmpCutImg釋放掉,Mat中的數據就變成隨機的了,顯示就成亂碼了。所以正確的做法應該是在使用完畢Mat後再釋放tmpCutImg。

同樣的,使用Mat的構造函數進行Mat的構造也會是這種情況,產生的新的Mat會與原來的Mat公用相同的數據區。如下所示:

Mat A=imread("test.jpg");
Mat A(B);

上面的操作構造出來的B會和A共用數據區,如果對B的數據區進行了操作,A的內容也會變化,因此如果想要複製全新的獨立的Mat,要使用如下方式:

Mat B=A.clone();

還有一個函數是

void Mat::copyTo(OutputArray m, InputArray mask) const

這個函數的用法跟clone()的關係看了下面的代碼就明白了:

inline Mat Mat::clone() const
{
  Mat m;
  copyTo(m);
  return m;
}

所以如果不提供mask,那麼clone()與copyTo()的功能是一樣的,而不同的是copyTo()拷貝Mat時只拷貝mask不爲零的位置,且mask的類型必須爲CV_8U

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章