事情是這樣的,我想把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