opencv 矩陣塊的複製問題

opencv中有函數可以實現,圖像指點塊的複製,或者複製到圖像指定塊:

void cvSetImageROI(IplImage* image,  CvRect rect)

這個函數對於控制圖像的局部塊進行處理非常方便,但是它的輸入只能是圖像指針 ,對於CvMat* 或者CvArray*這些類型的數據都稍稍麻煩了點。

1.             將他們相互轉化

  • IplImage轉Cvmat
1
2
3
Ptr<IplImage> image; //input
Ptr<CvMat> mat = cvCreateMatHeader(image->height, image->width, CV_32SC1);
cvConvert(image, mat);

或者:

1
2
CvMat matObj;
*mat = cvGetMat(image, &amp;matObj);// cvGetImage和cvGetMat都要慎用
  • Cvmat 轉IplImage
1
2
Ptr<IplImage> image = cvCreateImageHeader(cvGetSize(mat), 8,1);
cvGetImage(mat, image);//cvGetImage和cvGetMat都要慎用

2.            使用其他的函數

cvMat* cvGetSubRect(const CvArr* arr, cvMat* submat, CvRect rect);

該函數實現,將arr中rect區域數據copy到submat中。

注:沒有實現將數據copy到arr中的某rect區域,需要自己實現

實現時,一定要注意:Submat一定不能分配內存空間

如:

1
2
3
//如上的實現會出先內存泄漏
Ptr<CvMat&gt; submat = cvCreateMat(rect.width , rect.height,CV_32F);
cvGetSubRect(src, submat, rect);
1
2
3
//這樣子的實現就是ok的
Ptr<CvMat> submat = cvCreateMatHeader(rect.width , rect.height,CV_32F);
cvGetSubRect(src, submat, rect);

出現內存錯誤的原因:我們看看cvGetSubRect的源代碼。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
CV_IMPL  CvMat* cvGetSubRect( const CvArr* arr, CvMat* submat, CvRect rect )
{
     CvMat* res = 0;
     CV_FUNCNAME( "cvGetRect" );
     __BEGIN__;
     CvMat stub, *mat = (CvMat*)arr;
     if( !CV_IS_MAT( mat ))
         CV_CALL( mat = cvGetMat( mat, &stub ));
     if( !submat )
         CV_ERROR( CV_StsNullPtr, "" );
     if( (rect.x|rect.y|rect.width|rect.height) < 0 )
         CV_ERROR( CV_StsBadSize, "" );
     if( rect.x + rect.width> mat->cols || rect.y + rect.height>mat->rows )
         CV_ERROR( CV_StsBadSize, "" );
 {//從此處可以看出,如果submat已經分配有內存空間,那麼,此處將產生內存泄漏,切記傳遞submat時,一定要穿一個沒有分配內存的指針。
     submat -> data.ptr = mat->data.ptr + (size_t)rect.y*mat->step + rect.x*CV_ELEM_SIZE(mat->type);
     submat->step = mat->step & (rect.height > 1 ? -1 : 0);
     submat->type = (mat->type & (rect.width <  mat->cols ? ~CV_MAT_CONT_FLAG : -1)) |
     (submat->step == 0 ? CV_MAT_CONT_FLAG : 0);
     submat->rows = rect.height;
     submat->cols = rect.width;
     submat->refcount = 0;
     res = submat;
 }
     __END__;
     return res;
 }

總之,這個函數和opencv中的其他函數使用習慣不太一樣,使用時,一定要注意。

發佈了169 篇原創文章 · 獲贊 20 · 訪問量 42萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章