OpenCV图像区域复制粘贴

OpenCV把一个图像的一小块区域拷贝到另一个图像的指定区域,灰度图直接设定区域,复制粘贴即可:

// vv.cpp : 定义控制台应用程序的入口点。
//opencv把一个图像的一小块区域拷贝到另一个图像的指定区域

#include "stdafx.h"
#include "cv.h"
#include "highgui.h"

int main()
{ 
	IplImage* img = cvLoadImage("c:\\lh.jpg",0);	
	CvRect roi =cvRect(6, 6, 48, 48); 
	cvNamedWindow("img");
	cvShowImage("img", img);

	IplImage* img1 = cvLoadImage("c:\\leehom.jpg",0);	
	CvRect roi1 = cvRect(6, 6, 48, 48); 
	cvNamedWindow("img1");
	cvShowImage("img1", img1);

	cvSetImageROI(img, roi);
	cvSetImageROI(img1, roi1);
	cvCopy(img1, img);
	cvResetImageROI(img);
	cvResetImageROI(img1);

	cvNamedWindow("result");

	cvShowImage("result", img);
	
	

	cvWaitKey(-1);
	cvReleaseImage(&img);
	cvReleaseImage(&img1);
	cvDestroyAllWindows();
	return 0;
}

结果图:

OpenCV图像区域复制粘贴_第1张图片


要注意

对于三通道图像:【拷贝的两幅图像的depth 和 nchanels 应该是一样的才可以哦】

额 其实代码一样的呃。 只是第一次随意指定的Rect区域,三通道图像不行,还看了下 cvSetImageROI的源码。

后来发现,额,三通道耶,rect区域的指定肯定是 3 的倍数撒!

特意设定相同的rect区域试了下,发现拷贝过去的图片是一样的耶。

好菜额···

不太懂,灰度图中是从第六个像素点开始的, 3通道图应该也是从第六个像素开始的啊,因为拷贝过去的图像是一样的啊。

如果3通道图中 的 6 也是指第六个像素的话,那,roi1 为嘛非要是3的倍数呢?

如果这个6指的是第3个像素的第一个通道位置的话,那么 为嘛拷贝过去的图像一样呢????

快哭了 额。。。暂时还没想通。。。。

// vv.cpp : 定义控制台应用程序的入口点。
//opencv把一个图像的一小块区域拷贝到另一个图像的指定区域

#include "stdafx.h"
#include "cv.h"
#include "highgui.h"

int main()
{ 
	IplImage* img = cvLoadImage("c:\\lh.jpg",1);	
	CvRect roi =cvRect(6, 6, 48, 48); 
	cvNamedWindow("img");
	cvShowImage("img", img);

	IplImage* img1 = cvLoadImage("c:\\leehom.jpg",1);	
	CvRect roi1 = cvRect(6, 6, 48, 48); 
	cvNamedWindow("img1");
	cvShowImage("img1", img1);

	cvSetImageROI(img, roi);
	cvSetImageROI(img1, roi1);
	cvCopy(img1, img);
	cvResetImageROI(img);
	cvResetImageROI(img1);

	cvNamedWindow("result");
	cvShowImage("result", img);
	
	

	cvWaitKey(-1);
	cvReleaseImage(&img);
	cvReleaseImage(&img1);
	cvDestroyAllWindows();
	return 0;
}


OpenCV图像区域复制粘贴_第2张图片


opencv中cvSetImageROI在 cvcore.h中,具体在 cxarray.cpp 中:

CV_IMPL void
cvSetImageROI( IplImage* image, CvRect rect )
{
    if( !image )
        CV_Error( CV_HeaderIsNull, "" );

    // allow zero ROI width or height
    CV_Assert( rect.width >= 0 && rect.height >= 0 &&
               rect.x < image->width && rect.y < image->height &&
               rect.x + rect.width >= (int)(rect.width > 0) &&
               rect.y + rect.height >= (int)(rect.height > 0) );
    
    rect.width += rect.x;
    rect.height += rect.y;
    
    rect.x = std::max(rect.x, 0);
    rect.y = std::max(rect.y, 0);
    rect.width = std::min(rect.width, image->width);
    rect.height = std::min(rect.height, image->height);
    
    rect.width -= rect.x;
    rect.height -= rect.y;

    if( image->roi )
    {
        image->roi->xOffset = rect.x;
        image->roi->yOffset = rect.y;
        image->roi->width = rect.width;
        image->roi->height = rect.height;
    }
    else
        image->roi = icvCreateROI( 0, rect.x, rect.y, rect.width, rect.height );
}

后面我使用的时候,发现一个很奇怪的现象,不知道是不是我使用的 opencv2.3.1 版本的问题

ex:

//人脸区域
CvRect roi = cvRect(r_ret->x * scale, r_ret->y * scale, r_ret->width * scale, r_ret->height * scale );
cvRectangle(img, cvPoint(roi.x , roi.y ), cvPoint( roi.x + roi.width , roi.y + roi.height), CV_RGB(0, 255, 0), 3, 8, 0); 
cvSetImageROI(img, roi);
//裁剪出人脸图像,灰度图
IplImage* face = cvCreateImage( cvSize(roi.width, roi.height), 8, 1);
cvCopy(img, face);
cvResetImageROI(img);

这样是没问题的、但是下面这样,就有问题了:

//人脸区域
CvRect roi = cvRect(r_ret->x * scale, r_ret->y * scale, r_ret->width * scale, r_ret->height * scale );
cvRectangle(img, cvPoint(roi.x , roi.y ), cvPoint( roi.x + roi.width , roi.y + roi.height), CV_RGB(0, 255, 0), 3, 8, 0); 
//裁剪出人脸图像,灰度图
IplImage* face = cvCreateImage( cvSize(roi.width, roi.height), 8, 1);

cvSetImageROI(img, roi);
cvCopy(img, face);
cvResetImageROI(img);

真是奇了怪了, roi区域 又不会改变。。。。。。。。。。

你可能感兴趣的:(OpenCV图像区域复制粘贴)