【OpenCV】选择ROI区域 (转)

问题描述:在测试目标跟踪算法时,需要选择不同区域作为目标,进行目标跟踪,测试目标跟踪的效果。

解决思路:

1.OpenCV中提供了鼠标交互控制,利用setMouseCallback()给固定的窗口设置鼠标回调函数。

2.在鼠标回调函数中,选择感兴趣区域。

代码实现如下,将感兴趣区域封装在MouseSelect类中,提供选择点和矩形框两种模式。

 1 #pragma once
 2 #ifndef __MOUSESELECT_H__
 3 #define __MOUSESELECT_H__
 4
 5 #include <opencv2/opencv.hpp>
 6 #include <iostream>
 7
 8 #define MAX_OBJECTS    10
 9 using namespace cv;
10 using namespace std;
11 typedef struct MouseSelectParams
12 {
13     vector<Point> pts;        //Points of selected
14     char        *win_name;
15     Mat            *image;
16     unsigned int mode;        //1 Point,2 Rect
17     int             n;            // selected object number
18 }MouseSelectParams;
19
20 void on_mouse(int event,int x,int y,int flags,void *param);
21 class MouseSelect
22 {
23 public:
24     MouseSelect();
25     ~MouseSelect();
26
27     void select_rect(Mat &frame);
28     void select_point(Mat &frame);
29
30     vector<Point> vPoints;
31     vector<Rect> vRects;
32     unsigned int obj_selected;
33 private:
34     int get_rects(Mat &frame);
35     int get_points(Mat &frame);
36
37 };
38 #endif

  1 #include "MouseSelect.h"
  2
  3 MouseSelectParams *g_mousep;
  4 MouseSelect::MouseSelect() {}
  5
  6 MouseSelect::~MouseSelect() {}
  7
  8 void MouseSelect::select_rect(Mat &frame)
  9 {
 10     obj_selected = 0;
 11     while(0 == obj_selected)
 12     {
 13         obj_selected = get_rects(frame);
 14         if (obj_selected == 0)
 15         {
 16             cout<<"You haven‘t selected any rectangles. "<<endl;
 17         }
 18     }
 19 }
 20
 21 void MouseSelect::select_point(Mat &frame)
 22 {
 23     obj_selected = 0;
 24     while(0 == obj_selected)
 25     {
 26         obj_selected = get_points(frame);
 27         if (obj_selected == 0)
 28         {
 29             cout<<"You haven‘t selected any points."<<endl;
 30         }
 31     }
 32 }
 33
 34 int MouseSelect::get_rects(Mat &frame)
 35 {
 36     char *win_name = "Init Frame";
 37     MouseSelectParams params;
 38     params.win_name = win_name;
 39     params.image = &frame;
 40     params.n = 0;
 41     params.mode = 2;
 42     namedWindow(win_name,WINDOW_AUTOSIZE);
 43     imshow(win_name,frame);
 44
 45     g_mousep = &params;
 46     setMouseCallback(win_name,on_mouse,0);
 47     waitKey(0);
 48     destroyWindow(win_name);
 49
 50     int x1,x2,y1,y2,w,h;
 51     Rect rt;
 52     Point pt1,pt2;
 53     cout<<"Point Num: "<<params.pts.size()<<" Object Num: "<<params.n<<" Object Type: Rect."<<endl;
 54     for(int i = 0;i < params.pts.size();i += 2)
 55     {
 56         pt1 = params.pts[i];
 57         pt2 = params.pts[i + 1];
 58         x1 = min(pt1.x,pt2.x);
 59         x2 = max(pt1.x,pt2.x);
 60         y1 = min(pt1.y,pt2.y);
 61         y2 = max(pt1.y,pt2.y);
 62         w = x2 - x1;
 63         h = y2 - y1;
 64         w = (w % 2)? w:w+1;
 65         h = (h % 2)? h:h+1;
 66         rt.x = x1;
 67         rt.y = y1;
 68         rt.width = w;
 69         rt.height = h;
 70         vRects.push_back(rt);
 71     }
 72     return params.n;
 73 }
 74
 75 int MouseSelect::get_points(Mat &frame)
 76 {
 77     char    *win_name = "Init Frame";
 78     MouseSelectParams params;
 79     params.win_name = win_name;
 80     params.image = &frame;
 81     params.n = 0;
 82     params.mode = 1;
 83
 84     namedWindow(win_name,1);
 85     imshow(win_name,frame);
 86
 87     g_mousep = &params;
 88     setMouseCallback(win_name,on_mouse,0);
 89     waitKey(0);
 90
 91     destroyWindow(win_name);
 92
 93     cout<<"Point Num: "<<params.pts.size()<<" Object Num: "<<params.n<<" Object Type: Point."<<endl;
 94     for (int i = 0;i < params.n;i++)
 95     {
 96         vPoints.push_back(params.pts[i]);
 97     }
 98     return params.n;
 99 }
100
101 void on_mouse(int event,int x,int y,int flags,void *param)
102 {
103     int        n;
104     static bool pressed = false;
105     static Point cur_pt;
106     static Point prev_pt;
107     /* on left button press, remember first corner of rectangle around object */
108     if (event == CV_EVENT_LBUTTONDOWN)
109     {
110         n = g_mousep->n;
111         if (n == MAX_OBJECTS)
112         {
113             return;
114         }
115         prev_pt.x = x;
116         prev_pt.y = y;
117         //cout<<prev_pt.x <<","<<prev_pt.y<<" "<<cur_pt.x<<","<<cur_pt.y<<endl;
118         pressed = true;
119     }
120     /* on left button up, finalise the rectangle and draw it in black */
121     else if(event == CV_EVENT_LBUTTONUP && pressed)
122     {
123         /* 1 == mode for selecting points */
124         if (1 == g_mousep->mode)
125         {
126             n = g_mousep->n;
127             if (n == MAX_OBJECTS)
128             {
129                 return;
130             }
131             cur_pt.x = x;
132             cur_pt.y = y;
133             g_mousep->pts.push_back(cur_pt);
134             int radius = 3;
135             circle(*g_mousep->image,cur_pt,radius,CV_RGB(255,0,0));
136             imshow(g_mousep->win_name,*g_mousep->image);
137             pressed = false;
138             g_mousep->n++;
139         }
140         /* 2 == mode for selecting rectangles */
141         else if (2 == g_mousep->mode)
142         {
143             n = g_mousep->n;
144             if (n == MAX_OBJECTS)
145             {
146                 return;
147             }
148             cur_pt.x = x;
149             cur_pt.y = y;
150             g_mousep->pts.push_back(prev_pt);
151             g_mousep->pts.push_back(cur_pt);
152         //    cout<<prev_pt.x <<","<<prev_pt.y<<" "<<cur_pt.x<<","<<cur_pt.y<<endl;
153             rectangle(*g_mousep->image,prev_pt,cur_pt,CV_RGB(0,0,255));
154             imshow(g_mousep->win_name,*g_mousep->image);
155             pressed = false;
156             g_mousep->n++;
157         }
158         else if (3 == g_mousep->mode)
159         {
160             n = g_mousep->n;
161
162         }
163     }
164     else if (event == CV_EVENT_MOUSEMOVE && pressed && CV_EVENT_FLAG_LBUTTON)
165     {
166         if (2 == g_mousep->mode)
167         {
168             n = g_mousep->n;
169             if (n == MAX_OBJECTS)
170             {
171                 return;
172             }
173             cur_pt.x = x;
174             cur_pt.y = y;
175             Mat tmp = (*g_mousep->image).clone();
176             //cout<<prev_pt.x <<","<<prev_pt.y<<" "<<cur_pt.x<<","<<cur_pt.y<<endl;
177             rectangle(tmp,prev_pt,cur_pt,CV_RGB(0,255,0));
178             imshow(g_mousep->win_name,tmp);
179         }
180     }
181 }

代码分析:

on_mouse()回调函数,对应于一个显示窗口。

在回调函数处理鼠标事件,要理解一个鼠标点击过程,会产生多个事件。

例如:鼠标左击,对应着CV_EVENT_LBUTTONDOWN和CV_EVENT_LBUTTONUP。

在选择矩形框区域时,CV_EVENT_LBUTTONDOWN记录一个对角点;CV_EVENT_MOUSEMOVE记录选对矩形框的中间过程,并显示出来,便于用户调整选择的区域;CV_EVENT_LBUTTONUP记录另一个对角点,CV_EVENT_LBUTTONUP响应后,完成一个矩形框的选择。

在选择点时,只需记录CV_EVENT_LBUTTONUP事件响应的坐标。

时间: 2024-08-08 05:37:36

【OpenCV】选择ROI区域 (转)的相关文章

【OpenCV入门教程之四】 ROI区域图像叠加&amp;初级图像混合 全剖析(转)

本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/20911629 作者:毛星云(浅墨)    邮箱: [email protected] 写作当前博文时配套使用的OpenCV版本: 2.4.8 在这篇文章里,我们一起学习了在OpenCV中如何定义感兴趣区域ROI,如何使用addWeighted函数进行图像混合操作,以及将ROI和addWeighted函数结合起来使用,对指定区域进行图像

【OpenCV】复制、切割出图像ROI区域

对图像设定ROI的函数是: cvSetImageROI(IplImage* src,CvRect rect); src 表示的是源图像, rect 指的是ROI区域. 如果要取消ROI区域,那么使用函数: cvResetImageROI(IplImage* src); 这个函数,就把src上的ROI区域取消掉. 举例: #include <opencv/cv.h> #include <opencv2/highgui/highgui.hpp> using namespace cv;

OpenCv_Image与光流法中设置ROI区域

无论是在图片显示中或者是在光流法寻找角点的过程中,我们都会遇到ROI这个东西.它的作用就是让我们能够专注于图像或者当前视频帧中的某一块区域(我们称之为感兴趣区域) 进行处理,而不是对整个图像或者是整个视频帧进行处理,这不仅能够排除掉一些不必要的误差干扰,还能减少运算量.接下来分别说明来图像和光流法视频中如何设置ROI. 图像设置ROI 代码如下: /* * Description : setting ROI in image * Author : Liulongpo * Date : 2015年

ROI区域图像叠加&amp;初级图像混合 综合实例

将addWeighted函数与ROI函数封装到ROI_LinearBlending中 //---------------------------------[ROI_LinearBlending()]------------------------------------- // 函数名:ROI_LinearBlending() // 描述:线性混合实现函数,指定区域线性图像混合.利用cv::addWeighted()函数结合定义 // 感兴趣区域ROI,实现自定义区域的线性混合 //-----

ROI区域图像叠加

//----------------------------------[ROI_AddImage( )函数]---------------------------------- // 函数名:ROI_AddImage() // 描述:利用感兴趣区域ROI实现图像叠加 //---------------------------------------------------------------------------------------------- bool ROI_AddImage(

opencv 感兴趣区域建立

在对某IplImage图像用cvSetImageROI函数设置了ROI后,对图像的处理都将仅限于ROI区域,相当于该图像变为了ROI中的图像,测试代码值仅用cvCopy(复制图像的函数),进行了测试,实际上对于任何处理图像IplImage类型的函数,处理设置了ROI区域的图像类对象,都是处理它的ROI区域. #include "stdafx.h" #include<cv.h> #include<cxcore.h> #include<highgui.h>

检测车道线——2.选择兴趣区域 Region Masking

通过简单的颜色选择,我们设法消除了图像中除了车道线以外的几乎所有内容.但是,在这一点上,自动提取确切的线条仍然非常棘手,因为我们仍然在周边检测到了一些不是线条线的其他物体. 在这种情况下,我将假定拍摄图像的前置摄像头安装在汽车的固定位置,这样车道线总是会出现在图像的同一区域. 所以在提取行车线的时候,只关注这个梯形区域内的图像,可以避免其他区域的信息造成干扰.这个梯形区域如果选取地太大,则会引入更多无关信息(比如护栏,树木等),如果梯形区域选取太小,则可能看不见行车线,所以这里需要权衡.接下来,

机器学习进阶-图片基本处理-ROI区域 1.img[0:200, 0:200]截取图片 2.cv2.split(对图片的颜色通道进行拆分) 3. cv2.merge(将颜色通道进行合并) 4 cur_img[:, :, 0] = 0 使得b通道的颜色数值为0

1. 截取图片的部分区域img[0:200, 0:200], 读入的图片是ndarray格式 2. b, g, r = cv2.split(img)  # 对图片的颜色通道进行拆分 3.img = cv2.merge((b, g, r))  #对图片的颜色通道进行合并 4. 对其他通道置零,只显示单个通道 cur_img[:, :, 0] = 0, cur_img[:, :, 1] = 0 代码: 只显示部分区域 import cv2 # 定义显示函数 def cv_show(name, img

OpenCV计算连通区域数目与最大连通区域并标示出

#include <stdio.h> #include <cv.h> #include <highgui.h> #pragma comment(lib, "cv.lib") #pragma comment(lib, "cxcore.lib") #pragma comment(lib, "highgui.lib") int main( int argc, char** argv ) { IplImage* src