opencv 矩阵块的复制问题

本文介绍了如何在OpenCV中处理图像局部区域,包括图像指针与矩阵之间的转换方法及使用cvGetSubRect函数来复制图像指定块的具体步骤与注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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中的其他函数使用习惯不太一样,使用时,一定要注意。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值