ROI(region of interest)——感兴趣区域。
1.用途
这个区域是图像分析所关注的重点。圈定这个区域,以便进行进一步的处理。而且,使用ROI指定
想读入的目标,可以减少处理时间,增加精度,给图像处理带来不小的便利。
2.定义ROI方法
- 使用表示矩阵区域的Rect。
它指定矩阵的左上角坐标(构造函数的前两个参数)和矩阵的长宽(构造函数的后两个参数)以定义一个矩阵区域。
// 定义一个Mat类型并给定其设定的区域 Mat imageROI; // 方法一 imageROI = image(Rect(500, 250, logo.cols, logo.rows));
- 指定感兴趣行或列的范围(Range)。
Range是指从起索引到终止索引(不包括终止索引)的一连串连续序列。cRange可以用来定义Range。如果使用Range来定义ROI,那么前例中定义ROI的代码可以重写为:
// 方法二 imageROI = image( Range(250, 250+logoImage.rows),
Range(200, 200+logoImage.cols));
3.切割具体步骤
- 将要切割下的图像区域局部设置为ROI
void cvSetImageROI(IplImage* image,CvRect rect);- 创建一个与切割图像大小相同的新图像
IplImage* cvCreateImage( CvSize size, int depth, int channels );
| IPL_DEPTH_8U | 无符号8位整型 |
| IPL_DEPTH_8S | 有符号8位整型 |
| IPL_DEPTH_16U | 无符号16位整型 |
| IPL_DEPTH_16S | 有符号16位整型 |
| IPL_DEPTH_32F | 单精度浮点数 |
| IPL_DEPTH_64F | 双精度浮点数 |
- 将原图像复制到新图像中
void cvCopy( const CvArr* src, CvArr* dst, const CvArr* mask=NULL );
操作掩码是8比特单通道的数组,它指定了输出数组中被改变的元素。函数cvCopy从输入数组中复制选定的成分到输出数组:
如果mask(I)!=0,则dst(I)=src(I)。
如果输入输出数组中的一个是IplImage类型的话,其ROI和COI将被使用。输入输出数组必须是同样的类型、维数和大小。函数也可以用来复制散列数组(这种情况下不支持mask)。
- 释放ROI区域
cvResetIamgeROI(src);
4.实例
如何利用ROI将一幅图加到另一幅图的指定位置。
通过一个图像掩码,直接将插入处的像素设置为插入图像的像素值,这样效果会很逼真。
#include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <iostream>using namespace cv; using namespace std;bool ROI_AddImage(); bool LinearBlending(); bool ROI_LinearBlending(); void ShowHelpText();int main( ) {system("color 6F");if(ROI_AddImage( )&& LinearBlending( )&&ROI_LinearBlending( )){cout<<endl<<"\n运行成功,得出了需要的图像";}waitKey(0);return 0; }//----------------------------------【ROI_AddImage( )函数】---------------------------------- // 函数名:ROI_AddImage() // 描述:利用感兴趣区域ROI实现图像叠加 //---------------------------------------------------------------------------------------------- bool ROI_AddImage() {// 【1】读入图像Mat srcImage1= imread("dota_pa.jpg");Mat logoImage= imread("dota_logo.jpg");if( !srcImage1.data ) { printf("读取srcImage1错误~! \n"); return false; }if( !logoImage.data ) { printf("读取logoImage错误~! \n"); return false; }// 【2】定义一个Mat类型并给其设定ROI区域Mat imageROI= srcImage1(Rect(200,250,logoImage.cols,logoImage.rows));// 【3】加载掩模(必须是灰度图)Mat mask= imread("dota_logo.jpg",0);//【4】将掩膜拷贝到ROI logoImage.copyTo(imageROI,mask);// 【5】显示结果namedWindow("<1>利用ROI实现图像叠加示例窗口");imshow("<1>利用ROI实现图像叠加示例窗口",srcImage1);return true; }//---------------------------------【LinearBlending()函数】------------------------------------- // 函数名:LinearBlending() // 描述:利用cv::addWeighted()函数实现图像线性混合 //-------------------------------------------------------------------------------------------- bool LinearBlending() {//【0】定义一些局部变量double alphaValue = 0.5; double betaValue;Mat srcImage2, srcImage3, dstImage;// 【1】读取图像 ( 两幅图片需为同样的类型和尺寸 )srcImage2 = imread("mogu.jpg");srcImage3 = imread("rain.jpg");if( !srcImage2.data ) { printf("读取srcImage2错误! \n"); return false; }if( !srcImage3.data ) { printf("读取srcImage3错误! \n"); return false; }// 【2】进行图像混合加权操作betaValue = ( 1.0 - alphaValue );addWeighted( srcImage2, alphaValue, srcImage3, betaValue, 0.0, dstImage);// 【3】显示原图窗口imshow( "<2>线性混合示例窗口【原图】", srcImage2 );imshow( "<3>线性混合示例窗口【效果图】", dstImage );return true;}//---------------------------------【ROI_LinearBlending()】------------------------------------- // 函数名:ROI_LinearBlending() // 描述:线性混合实现函数,指定区域线性图像混合.利用cv::addWeighted()函数结合定义 // 感兴趣区域ROI,实现自定义区域的线性混合 //-------------------------------------------------------------------------------------------- bool ROI_LinearBlending() {//【1】读取图像Mat srcImage4= imread("dota_pa.jpg",1);Mat logoImage= imread("dota_logo.jpg");if( !srcImage4.data ) { printf("读取srcImage4错误~! \n"); return false; }if( !logoImage.data ) { printf("读取logoImage错误~! \n"); return false; }//【2】定义一个Mat类型并给其设定ROI区域 Mat imageROI;//方法一imageROI= srcImage4(Rect(200,250,logoImage.cols,logoImage.rows));//方法二//imageROI= srcImage4(Range(250,250+logoImage.rows),Range(200,200+logoImage.cols));//【3】将logo加到原图上addWeighted(imageROI,0.5,logoImage,0.3,0.,imageROI);//【4】显示结果imshow("<4>区域线性图像混合示例窗口",srcImage4);return true; }
参考:《OpenCV3编程入门》 毛星云 著







