视觉图像:OpenCV感兴趣区域ROI

2025-10-21 00:55:49

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;

}

视觉图像:OpenCV感兴趣区域ROI

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);

}

视觉图像:OpenCV感兴趣区域ROI

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;

}

视觉图像:OpenCV感兴趣区域ROI

视觉图像:OpenCV感兴趣区域ROI

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;

}

视觉图像:OpenCV感兴趣区域ROI

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种事件,这里不再赘述。

第四个参数,函数参数的编号。

视觉图像:OpenCV感兴趣区域ROI

6、图像感兴趣区域剪切:

①将需要剪切的图像图像不部分设置为ROI

cvSetImageROI(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; 

}  

视觉图像:OpenCV感兴趣区域ROI

声明:本网站引用、摘录或转载内容仅供网站访问者交流或参考,不代表本站立场,如存在版权或非法内容,请联系站长删除,联系邮箱:site.kefu@qq.com。
猜你喜欢