opencv中對圖像的處理是最基本的操作,一般的圖像類型爲IplImage類型,但是當我們對圖像進行處理的時候,多數都是對像素矩陣進行處理,所以這三個類型之間的轉換會對我們的工作帶來便利Mat類型較CvMat和IplImage有更強的矩陣運算能力,支持常見的矩陣運算(參照Matlab中的各種矩陣運算),所以將IplImage類型和CvMat類型轉換爲Mat類型更易於數據處理。Mat類型可用於直接存儲圖像信息,通過函數imread、imwrite、imshow等實現(與Matlab中的函數相似),似乎在某種程度上可以取代IplImage類型。
2 ).Mat
3). CvMat
1、四者關係:
1).CvMat(CvMat is now obsolete, consider using Mat instead)不建議用;
2). 派生關係:CvArr -> CvMat -> IplImage
3). Mat是C++接口,和IplImage有所不同。
2. 相互轉換
1). Mat與IplImage相互轉換
IplImage* src;
某文章說,轉換應該是Mat m(src); 而這不會複製內容,真正能複製內容的是:
Mat -> IplImage:
- Mat m;
- IplImage* transIplimage = cvCloneImage(&(IplImage) m);
IplImage -> Mat
- IplImage* transIplImage;
- Mat m = cvarrToMat(transIplImage,true);
2). CvMat與IplImage相互轉換
- IplImage* transIplImage;
- CvMat* cvmat;
- cvGetMat(transIplImage,cvmat);
- cvGetImage(cvmat,transIplImage);
3. (多通道)Mat, IplImage, CvMat的元素獲取
單通道的網上很多,這裏只寫多通道:
1). IplImage
- //i is the index of rows
- //j is the index of cols
- //c is the index of channel
- ((uchar*)pImg->imageData+i*pImg->widthStep)[j*3+c]
- CV_IMAGE_ELEM(pImg,uchar,i,3*j+c)
2 ).Mat
- Mat m;
- int h = m.rows; int w = m.cols;
- int nc = m.channels();
- for (int i = 0;i<h;i++)
- {
- for(int j = 0;j<w;j++)
- {
- Vec3b& elem = m.at<Vec3b>(i,j);
- for (int c = 0; c<nc; c++)
- {
- uchar uc = elem[c] ;//Mat(i,j) of channel c
- }
- }
- }
3). CvMat
CV_MAT_ELEM(cvmat,uchar,i,3*j+c)
4. 驗證獲取元素代碼(Mat轉IplImage)
此代碼只用於驗證多通道元素獲取沒有錯誤,具體用的時候最好還是用opencv直接給的吧(見第3小節)
- IplImage* cvcvt_mat2IplImage(Mat m)
- {
- int h = m.rows; int w = m.cols;
- int nc = m.channels();
- IplImage* pImg = cvCreateImage(cvSize(w,h),8,nc);
- for (int i = 0;i<h;i++)
- {
- for(int j = 0;j<w;j++)
- {
- Vec3b& elem = m.at<Vec3b>(i,j);
- for (int c = 0; c<nc; c++)
- {
- //以下兩種都可以
- //((uchar*)pImg->imageData+i*pImg->widthStep)[j*3+c] = elem[c];
- CV_IMAGE_ELEM(pImg,uchar,i,3*j+c) = elem[c];
- }
- }
- }
- return pImg;
- }