【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 = ¶ms;
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 = ¶ms;
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事件响应的坐标。
【OpenCV】选择ROI区域 (转)的更多相关文章
- 【OpenCV】选择ROI区域
问题描述:在测试目标跟踪算法时,需要选择不同区域作为目标,进行目标跟踪,测试目标跟踪的效果. 解决思路: 1.OpenCV中提供了鼠标交互控制,利用setMouseCallback()给固定的窗口设置 ...
- opencv——设置ROI区域
#include "stdafx.h" #include<opencv2\opencv.hpp> #include<opencv\cv.h> #includ ...
- 【opencv学习笔记六】图像的ROI区域选择与复制
图像的数据量还是比较大的,对整张图片进行处理会影响我们的处理效率,因此常常只对图像中我们需要的部分进行处理,也就是感兴趣区域ROI.今天我们来看一下如何设置图像的感兴趣区域ROI.以及对ROI区域图像 ...
- 图像的ROI区域选择与复制
[opencv学习笔记六]图像的ROI区域选择与复制 孜然 7 人赞同了该文章 图像的数据量还是比较大的,对整张图片进行处理会影响我们的处理效率,因此常常只对图像中我们需要的部分进行处理,也就是感 ...
- Python 图像处理 OpenCV (3):图像属性、图像感兴趣 ROI 区域及通道处理
前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 图像属性 图像 ...
- OpenCV计算机视觉学习(1)——图像基本操作(图像视频读取,ROI区域截取,常用cv函数解释)
1,计算机眼中的图像 我们打开经典的 Lena图片,看看计算机是如何看待图片的: 我们点击图中的一个小格子,发现计算机会将其分为R,G,B三种通道.每个通道分别由一堆0~256之间的数字组成,那Ope ...
- 【opencv学习笔记】SetImageROI函数设置ROI区域的作用及用法
虽然先前知道ROI区域是感兴趣区域,但是真正看到调用了OpenCV的cvSetImageROI函数时,并不知道它的作用,所以还是单独写了一段代码对这个函数进行探究. OpenCVchm文档中对cv ...
- opencv 3 core组件进阶(2 ROI区域图像叠加&图像混合;分离颜色通道、多通道图像混合;图像对比度,亮度值调整)
ROI区域图像叠加&图像混合 #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp&g ...
- opencv——感兴趣区域(ROI)的分析和选取[详细总结]
引言 在利用OpenCV对图像进行处理时,通常会遇到一个情况,就是只需要对部分感兴趣区域进行处理.因此,如何选取感兴趣区域呢?(其实就是"抠图"). 在学习opencv的掩码运算后 ...
随机推荐
- Renderscript图像处理
作者:慧能 最近正在学习renderscript,后期会整理一篇完整的文档,先记着.... https://blog.csdn.net/codemydream/article/details/5346 ...
- python+selenium四:iframe查看、定位、切换
iframe是HTML里面嵌套HTML的一种框架 1.查看iframe 1.Top Window:可直接定位 2.iframe#i:说明此元素在iframe上 3.iframe显示为空:(id或nam ...
- python接口自动化测试二十一:类和方法
# 类和方法 class Count(): def __init__(self, aaa, bbb): # 初始化 # 可以放公共的参数 print('实例化的时候,会执行init的内容') self ...
- #14 [BZOJ2090/2089] [Poi2010]Monotonicity 2/Monotonicity
题解: 首先想到了标算..然后证明了一发是错的(事实证明很智障) 先说正确性比较显然的O(n^2)算法 令f[i][j]表示前i个物品,匹配到第j个括号,最大值是多少 g[i][j]表示前i个物品,匹 ...
- PKUWC2019游记&&WC2019游记
今天好颓,不想写代码了,写写游记 PKUWC2019游记&&WC2019游记 PKUWC2019游记 提前两天就来了中山纪中,考了两天模拟,第一天比较正常,但是可做题只有T3,第二天非 ...
- Docker 记一次容器内部修改宿主机挂载目录用户权限后宿主机目录变化
一.需求: 因公司需求,需制作mysql5.7.22 docker基础镜像,每个项目以此镜像启动一个数据库容器,并且每个项目挂载一个宿主机目录到镜像中数据存储下面用于数据持久化保存以便后期迁移至阿里云 ...
- go语言中goroute使用:=遇到的坑
先看下源代码,预想从1至N总取出所有能被a或b整除的正整数之和,为了利用go语言的并行优势,特使用goroute特性来实现,同时使用普通顺序计算进行效率比较分析 package chango impo ...
- 基于C++11实现线程池的工作原理
目录 基于C++11实现线程池的工作原理. 简介 线程池的组成 1.线程池管理器 2.工作线程 3.任务接口, 4.任务队列 线程池工作的四种情况. 1.主程序当前没有任务要执行,线程池中的任务队列为 ...
- 破解百度云盘MAC下载限速问题
由于电脑更新问题,所以把电脑上的所有东西清除了.突然发现自己以前的东西还都在百度云盘上,但由于MAC 下载百度云盘上的东西只有几K或者几十K,这个网速对于小文件还能忍受,但如果是大文件就无法容忍了. ...
- SQLserver 新用户的创建以及权限的给与
我们有时在装sql server 2008或者2012的时候,发现在装的时候,忘记设置sa用户的密码了,其实sa用户是sql server自带的用户,所以我们在装数据库的时候只需要设置一个密码就可以了 ...