1、定义ROI区域的两种方法:①指定矩形坐标,并规定好长宽;Mat img = imread("1.jpg");Mat roi = img(Rect(500, 200, 100, 300));//Rect四个形参分别是:x坐标,y坐标,长,高;注(x,y)指矩形的左上角点;②指定感兴趣行或列的范围(Range),Range是指从起始索引到终止索引的一段联系序列:Mat img = imread("1.jpg");Mat roi = img(Range(250, 250 +xleng), Range(200, 200 + yleng));//Range两个形参分别是:起始行或列,起始行或列+偏移量示例:#include<opencv2\opencv.hpp>#include<opencv2\highgui\highgui.hpp>using namespace std;using namespace cv;int main(){ Mat srcImage = imread("test.jpg"); if (!srcImage.data) { cout << "读取原始图失败!" << endl; return -1; } rectangle(srcImage, Rect(0, 0, 600, 200), Scalar(0, 255, 0),2); //将感兴趣区域框出来 imshow("ROI", srcImage); waitKey(); return 0;}
2、有时,不仅要把ROI标记出来,还要把ROI提取出来,成为一幅单独图片;示例如下:int main(){ Mat img1 = imread("0.jpg", 1); Mat img2(img1.rows, img1.cols, CV_8UC3); //设置感兴趣区域,拷贝 img1(Rect(200, 100, 150, 100)).copyTo(img2); //或 //Mat roi = img1(Rect(200, 100, 150, 100)); //imshow("roi",roi); imshow("img1", img1); imshow("img2", img2); waitKey(0);}
3、图像上添加logo:两种方法:①:首先定义ROI区域,然后进行线性叠加,使用addWeighted();线性胼秀阔绡混合操作是一种典型的二元像素操作,理论公式如下:g(x)=(1-a)f1(x)+af2(x);a:0~1;改变两幅图像混合效果;int main(){ Mat srcImage = imread("0.jpg"); if (!srcImage.data) { cout << "读取原始图失败!" << endl; return -1; } namedWindow("srcImage", WINDOW_NORMAL);//WINDOW_NORMAL允许用户自由伸缩窗口 imshow("srcImage", srcImage); Mat logo = imread("1.jpg"); if (!logo.data) { cout << "读取原始logo图失败!" << endl; return -1; } Mat imageROI = srcImage(Rect(120, 50, logo.cols, logo.rows)); //从原图中抠出矩形区域,Rect第一二参数表示矩形左上角定点的坐标,用于定位,后两个参数表示举行的宽和高 imshow("ROI", imageROI); addWeighted(imageROI, 0.65, logo, 0.35, 0., imageROI);//dst = src1[I]*alpha+ src2[I]*beta + gamma;第5参数就是偏执因子gamma。 namedWindow("原图加logo", WINDOW_NORMAL); imshow("原图加logo", srcImage); waitKey(); return 0;}
4、②方法二:定义ROI区域,使用copyTo实现直接拷贝覆盖int main(){ Mat srcImage = imread("0.jpg"); if (!srcImage.data) { cout << "读取原始图失败!" << endl; return -1; } namedWindow("srcImage", WINDOW_NORMAL); imshow("srcImage", srcImage); Mat logo = imread("3.jpg"); Mat mask = imread("3.jpg",0); // 加载掩模(必须是灰度图) if (!logo.data) { cout << "读取原始logo图失败!" << endl; return -1; } Mat imageROI = srcImage(Rect(205, 10, logo.cols, logo.rows)); //从原图中抠出矩形区域,Rect第一二参数表示矩形左上角定点的坐标,用于定位,后两个参数表示举行的宽和高 imshow("ROI", imageROI); logo.copyTo(imageROI,mask);//注意两个参数,一个是ROI,一个是掩模 namedWindow("原图加logo", WINDOW_NORMAL); imshow("原图加logo", srcImage); waitKey(); return 0;}
5、利用鼠标交互提取ROI;主函数中调用鼠标的回调函数,将鼠标操作与程序的窗口绑定,产生鼠标操作时回调函数调用鼠标响应函数执行;回调函数setMouseCallback():形式:void setMouseCallback(const string& winname, MouseCallback onMouse, void* userdata=0 )参数:第一个参数,windows视窗名称,对名为winname的视窗进行鼠标监控;第二个参数,鼠标响应处理函数,监听鼠标的点击,移动,松开,判断鼠标的操作类型,并进行响应的函数处理;第三个参数,鼠标响应处理函数的ID,与鼠标相应处理函数相匹配就行,暂时只用到默认为0的情况。鼠标响应处理函数onMouse():OpenCV中,鼠标相应处理函数一般默认形参和返回参数。格式:void onMouse(int event,int x,int y,int flags,void *ustc)第一个参数,鼠标操作时间的整数代号,在opencv中,event鼠标事件总共有10中,从0-9依次代表如下:EVENT_MOUSEMOVE =0, //滑动EVENT_LBUTTONDOWN =1, //左键点击EVENT_RBUTTONDOWN =2, //右键点击EVENT_MBUTTONDOWN =3, //中间点击EVENT_LBUTTONUP =4, //左键释放EVENT_RBUTTONUP =5, //右键释放EVENT_MBUTTONUP =6, //中间释放EVENT_LBUTTONDBLCLK =7, //左键双击EVENT_RBUTTONDBLCLK =8, //右键双击EVENT_MBUTTONDBLCLK =9 //中间释放第二个参数,代表鼠标位于窗口的(x,y)坐标位置,窗口左上角默认为原点,向右为x轴,向下为y轴;第三个参数,代表鼠标的拖拽事件,以及键盘鼠标联合事件,总共有32种事件,这里不再赘述。第四个参数,函数参数的编号。
6、图像感兴趣区域剪切:①将需要剪切的图像图像不部分设置为ROIcvSetImageROI(src , cvRect(x,y,width,height));②新建一个爵奏笆棚与需要剪切的图像部分同样大小的新图像cvCreateImage(cvSize(width,height),IPL_DEPTH,nchannels);③将源图像复制到新建的图像中cvCopy(src,dst,0);④释放ROI区域cvResetIamgeROI(src);示例:#include "stdafx.h"#include <opencv2\opencv.hpp>#include <opencv2\highgui\highgui.hpp>#include <opencv2\features2d\features2d.hpp>#include <opencv2\core\core.hpp>using namespace std;using namespace cv;IplImage* src;IplImage* dst;int main(int argc , char** argv ){ src = cvLoadImage("0.jpg",1); cvNamedWindow("源图像",1); cvShowImage("源图像",src); cvSetImageROI(src,cvRect(0,0,0.5*src->width,0.5*src->height)); dst = cvCreateImage(cvSize(0.5*src->width,0.5*src->height), IPL_DEPTH_8U,src->nChannels); cvCopy(src,dst,0); cvResetImageROI(src); cvNamedWindow("操作后的图像",1); cvShowImage("操作后的图像",dst); cvWaitKey(0); cvDestroyWindow("操作后的图像"); cvDestroyWindow("源图像"); cvReleaseImage(&src); cvReleaseImage(&dst); return 0;}