您的位置:首页 > 运维架构

cvCopy与cvCloneImage的区别

2013-07-31 18:48 399 查看
/* Copies source array to destination array */

CVAPI(void)  cvCopy( const CvArr* src, CvArr* dst,

                     const CvArr* mask CV_DEFAULT(NULL) );

/* Creates a copy of IPL image (widthStep may differ) */

CVAPI(IplImage*) cvCloneImage( const IplImage* image );

如果设定了ROI等参数的时候,cvCopy只是复制被设定的区域,复制到一个和所设定参数相吻合的新的IplImage中

而cvCloneImage则是将整个IplImage结构复制到新的IplImage中,其中的ROI等参数也会一同复制。新的IplImage将会和原来的一模一样。

 

cvCopy的原型是:

void cvCopy( const CvArr* src, CvArr* dst, const CvArr* mask=NULL );
在使用这个函数之前,你必须用cvCreateImage()一类的函数先开一段内存,然后传递给dst。cvCopy会把src中的数据复制到dst的内存中。

cvCloneImage的原型是:

IplImage* cvCloneImage( const IplImage* image );

在使用函数之前,不用开辟内存。该函数会自己开一段内存,然后复制好image里面的数据,然后把这段内存中的数据返回给你。
clone是把所有的都复制过来,也就是说不论你是否设置Roi,Coi等影响copy的参数,clone都会原封不动的克隆过来。

copy就不一样,只会复制ROI区域等。用clone复制之后,源图像在内存中消失后,复制的图像也变了,而用copy复制,源图像消失后,复制的图像不变
________________________________________________________________
Opencv中的ROI介绍

ROI(Region of Interest)是指图像中的一个矩形区域,可能你后续的程序需要单独处理这一个小区域,如图所示

如上图所示,就是ROI的一个例子,如果你对图像设置了ROI,那么,Opencv的大多数函数只在该ROI区域内运算(只处理该ROI区域),如果没设ROI的话,就会出来整幅图像。
ROI非常有用,例如我们想把图像中的人脸扣出来,进行人脸识别。需要注意的时候,ROI一定在图像内部,而不能超出图像的范围。

对图像设定ROI的函数是:

cvSetImageROI(IplImage* src,CvRect rect);
src表示的是源图像,rect只的是ROI区域。

如果要取消ROI区域,那么使用函数:

cvResetImageROI(IplImage* src);
这个函数,就把src上的ROI区域取消掉。

下面举几个例子:

例子1:
从一幅大图像中,取出一小块图像并保存这一个小块图像。
代码如下:
/* 读取大图像 */
IplImage *img1 = cvLoadImage("elvita.jpg", 1);

/* 设置图像的ROI区域
   注意ROI区域不要越界,必须在大图像的内部 */
cvSetImageROI(img1, cvRect(10, 15, 150, 250));

/* 为小图像分配内存空间
   cvGetSize(img1)返回的是一个CvSize结构体,意思就是返回了图像img1的宽度和高度,由于
img已经设置了ROI,所以cvGetSize函数对ROI区域有效,所以,返回的是ROI区域的宽度和高度 */
IplImage *img2 = cvCreateImage(cvGetSize(img1),
                               img1->depth,
                               img1->nChannels);

/* 把img1的ROI区域拷贝到img2*/
cvCopy(img1, img2, NULL);

/* 取消img1上的ROI区域 */
cvResetImageROI(img1);

例子2:
两幅不同大小的图像相加
/* 加载图像
   注意,这两幅图像有不同的宽度和高度 */
IplImage *img1 = cvLoadImage("elvita.jpg", 1);  /* 大图像  */
IplImage *img2 = cvLoadImage("fifi.jpg", 1);    /* 较小的图像*/

/* 定义ROI区域的坐标*/
CvRect rect = cvRect(25, 25, img2->width, img2->height);

/* 对图像img1设置ROI1区域 */
cvSetImageROI(img1, rect);

/* 两幅图像相加
   注意,通过对img1设置ROI区域后,两幅图像,其实有相同的宽度和高度了。 */
cvAdd(img1, img2, img1, NULL);

/* 取消感兴趣区域,即ROI区域*/
cvResetImageROI(img1);

例子3:在一个特定区域进行模板匹配 (关于模板匹配的完整代码下载)
IplImage *src = cvLoadImage("myphoto.jpg", 1);
IplImage *template = cvLoadImage("eye.jpg", 1);

CvRect rect = cvRect(25, 25, 120, 120);

//设置ROI区域
cvSetImageROI(src, rect);

IplImage *result = cvCreateImage(cvSize(rect.width  - tpl->width  + 1,
                                     rect.height - tpl->height + 1),
                              IPL_DEPTH_32F, 1);

/* 进行模板匹配 */
cvMatchTemplate(src, template, result, CV_TM_SQDIFF);

/* 查找最匹配的坐标 */
CvPoint    minlocation, maxlocation;
double    minvalue, maxvalue;
cvMinMaxLoc(result, &minvalue, &maxvalue, &minlocation, &maxlocation, 0);

/* 在源图像上画出矩形*/
cvRectangle(src,
            cvPoint(minlocation.x, minlocationc.y),
            cvPoint(minlocation.x + template->width, minlocationc.y + template->height),
            CV_RGB(255, 0, 0), 1, 0, 0 );

cvResetImageROI(src);

在上面的例子中,先定义ROI区域,再进行模板匹配,这样会加快匹配的速度,因为,只在ROI区域进行模板匹配运算。

例子4:ROI区域像素值的访问
可以想把ROI区域拷贝到一幅新的图像中,然后再访问其像素值

/* 假设已经有了一幅 8-bit 3通道图像*/

/* ROI的坐标*/
CvRect rect = cvRect(10, 20, 50, 60);

/* ROI区域的子图像 */
IplImage* subimg;

/* 设置ROI区域 */
cvSetImageROI(img, rect);

//ROI区域拷贝
cvCopy(img, subimg, NULL);

//释放ROI区域
cvResetImageROI(img);

/* 然后,就可以对subimg进行访问,其实就是访问ROI区域 */

或者可以通过ROI的左边信息进行访问

/* ROI区域的坐标 */
CvRect rect = cvRect(10, 20, 50, 60);

//设置ROI区域
cvSetImageROI(img, rect);

/* 假设,把整个ROI区域赋值为0 */
for (i = rect.y; i < (rect.y + rect.height); i++) {
    for (j = rect.x; j < (rect.x + rect.width); j++) {
        ((uchar*)(img->imageData + i * img->widthStep))[j*3] = 0;
        ((uchar*)(img->imageData + i * img->widthStep))[j*3+1] = 0;
        ((uchar*)(img->imageData + i * img->widthStep))[j*3+2] = 0;
    }
}

cvResetImageROI(img);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: