OpenCV学习之子图像操作

我们有时候希望对图像的某个小部分进行操作,而不是对整个图像进行运算。有两种方法,ROI和widthStep。

1. ROI

设置一个ROI区域使用cvSetImageROI,取消一个ROI使用cvResetImageROI。函数原型分别如下:

void cvSetImageROI( IplImage* image, CvRect rect );

void cvResetImageROI( IplImage* image );

rect就是我们要操作的图像的某个区域。实例如下:


#include <cv.h>
#include <highgui.h>


int main(int argc, char* argv[])
{

IplImage* src;

CvRect rect = cvRect(70, 70, 50, 50); 

if (argc == 2 && ((src = cvLoadImage(argv[1], 1)) != NULL)) {

cvSetImageROI(src, rect);

cvAddS(src, cvScalar(50), src);

cvResetImageROI(src);

cvNamedWindow("roi_add", CV_WINDOW_AUTOSIZE);

cvShowImage("roi_add", src);

cvWaitKey();

cvReleaseImage(&src);

cvDestroyWindow("roi_add");

}

return 0;

}

这里我们将ROI区域的灰度值增加50。


2. widthStep

有了ROI,为什么还需要使用widthStep。ROI只能串行的处理,需要不断设置和重置,而使用widthStep可以连续的操作多个子区域。实例如下:

#include <cv.h>
#include <highgui.h>


int main(int argc, char* argv[])
{

IplImage* src;

CvRect rect = cvRect(100, 20, 50, 50);

if (argc == 2 && ((src = cvLoadImage(argv[1], 1)) != NULL)) {

IplImage* sub_img = cvCreateImageHeader(cvSize(rect.width, rect.height),

src->depth, src->nChannels);

sub_img->origin = src->origin;

sub_img->widthStep = src->widthStep;


sub_img->imageData = src->imageData +

rect.y * src->widthStep +

rect.x * src->nChannels;


cvAddS(sub_img, cvScalar(50), sub_img);

cvNamedWindow("sub_add", CV_WINDOW_AUTOSIZE);

cvShowImage("sub_add", src);

cvWaitKey();

   

cvReleaseImageHeader(&sub_img);

cvDestroyWindow("sub_add");

cvReleaseImage(&src);


}

return 0;
}

注意:

在这里我们只创建了一个子图像的头,它的数据域在原图像中。我们通过widthStep来操作原图像的数据,从而达到修改原图像子区域的操作。

子图像的widhtStep等于原图像的widthStep,因为操作了一行后,欲操作下一行,必须将数据域指针加上widthStep。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值