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

解决思路:

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 = ;
  11. while( == obj_selected)
  12. {
  13. obj_selected = get_rects(frame);
  14. if (obj_selected == )
  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 = ;
  24. while( == obj_selected)
  25. {
  26. obj_selected = get_points(frame);
  27. if (obj_selected == )
  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 = ;
  41. params.mode = ;
  42. namedWindow(win_name,WINDOW_AUTOSIZE);
  43. imshow(win_name,frame);
  44.  
  45. g_mousep = &params;
  46. setMouseCallback(win_name,on_mouse,);
  47. waitKey();
  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 = ;i < params.pts.size();i += )
  55. {
  56. pt1 = params.pts[i];
  57. pt2 = params.pts[i + ];
  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 % )? w:w+;
  65. h = (h % )? h:h+;
  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 = ;
  82. params.mode = ;
  83.  
  84. namedWindow(win_name,);
  85. imshow(win_name,frame);
  86.  
  87. g_mousep = &params;
  88. setMouseCallback(win_name,on_mouse,);
  89. waitKey();
  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 = ;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 ( == 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 = ;
  135. circle(*g_mousep->image,cur_pt,radius,CV_RGB(,,));
  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 ( == 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(,,));
  154. imshow(g_mousep->win_name,*g_mousep->image);
  155. pressed = false;
  156. g_mousep->n++;
  157. }
  158. else if ( == 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 ( == 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(,,));
  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区域的更多相关文章

  1. 【OpenCV】选择ROI区域 (转)

    问题描述:在测试目标跟踪算法时,需要选择不同区域作为目标,进行目标跟踪,测试目标跟踪的效果. 解决思路: 1.OpenCV中提供了鼠标交互控制,利用setMouseCallback()给固定的窗口设置 ...

  2. opencv——设置ROI区域

    #include "stdafx.h" #include<opencv2\opencv.hpp> #include<opencv\cv.h> #includ ...

  3. 【opencv学习笔记六】图像的ROI区域选择与复制

    图像的数据量还是比较大的,对整张图片进行处理会影响我们的处理效率,因此常常只对图像中我们需要的部分进行处理,也就是感兴趣区域ROI.今天我们来看一下如何设置图像的感兴趣区域ROI.以及对ROI区域图像 ...

  4. 图像的ROI区域选择与复制

    [opencv学习笔记六]图像的ROI区域选择与复制 孜然   7 人赞同了该文章 图像的数据量还是比较大的,对整张图片进行处理会影响我们的处理效率,因此常常只对图像中我们需要的部分进行处理,也就是感 ...

  5. Python 图像处理 OpenCV (3):图像属性、图像感兴趣 ROI 区域及通道处理

    前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 图像属性 图像 ...

  6. OpenCV计算机视觉学习(1)——图像基本操作(图像视频读取,ROI区域截取,常用cv函数解释)

    1,计算机眼中的图像 我们打开经典的 Lena图片,看看计算机是如何看待图片的: 我们点击图中的一个小格子,发现计算机会将其分为R,G,B三种通道.每个通道分别由一堆0~256之间的数字组成,那Ope ...

  7. 【opencv学习笔记】SetImageROI函数设置ROI区域的作用及用法

    虽然先前知道ROI区域是感兴趣区域,但是真正看到调用了OpenCV的cvSetImageROI函数时,并不知道它的作用,所以还是单独写了一段代码对这个函数进行探究.   OpenCVchm文档中对cv ...

  8. opencv 3 core组件进阶(2 ROI区域图像叠加&图像混合;分离颜色通道、多通道图像混合;图像对比度,亮度值调整)

    ROI区域图像叠加&图像混合 #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp&g ...

  9. opencv——感兴趣区域(ROI)的分析和选取[详细总结]

    引言 在利用OpenCV对图像进行处理时,通常会遇到一个情况,就是只需要对部分感兴趣区域进行处理.因此,如何选取感兴趣区域呢?(其实就是"抠图"). 在学习opencv的掩码运算后 ...

随机推荐

  1. SAP ECC MM 配置文档

    SAP ECC 6.0 Configuration Document Materials Management (MM) Table of Content TOC \o \h \z 1. Genera ...

  2. saiku、mondrian前奏之——立方体、维度、Schema的基本概念

    以前介绍了几个基本工具:saiku 和 Schema Workbench,算是入门级别的了解多维报表,如果要继续深入,需要深入了解如下几个概念: 1.OLAP 联机分析处理,和他对应的是OLTP(联机 ...

  3. git pull 指定版本

    git init git remote add origin git@bitbucket.org:huashiyiqike/lstm-hf.git git pull origin master

  4. 【Android】Handler、Looper源码分析

    一.前言 源码分析使用的版本是 4.4.2_r1. Handler和Looper的入门知识以及讲解可以参考我的另外一篇博客:Android Handler机制 简单而言:Handler和Looper是 ...

  5. MFC ADO连接Oracle12c数据库 类库文件

    Stdafx.h Stdafx.h libado.h libado.h libado.cpp libado.cpp 参考网址如下:http://www.cnblogs.com/livewithnore ...

  6. codeforces Restore Cube(暴力枚举)

    /* 题意:给出立方体的每个顶点的坐标(是由源坐标三个数某几个数被交换之后得到的!), 问是否可以还原出一个立方体的坐标,注意这一句话: The numbers in the i-th output ...

  7. HTML5探索一(那些新增的标签和属性)

    tml5相比html4,添加了部分语义化的标签和属性,现在我们就从这些标签和属性开始,学习html5吧. 首先,认识下HTML5新的文档类型: <!DOCTYPE html> 那些新标签 ...

  8. Asp.net Mvc4 基于Authorize实现的模块权限验证方式

    在MVC中,我们可以通过在action或者controller上设置Authorize[Role="xxx"] 的方式来设置用户对action的访问权限.显然,这样并不能满足我们的 ...

  9. [Node.js] 使用File API 异步上传文件

    原文地址:http://www.moye.me/2014/11/05/html5-filereader/ 最近在做一个网盘的项目,不出意外的涉及到大文件的上传,那么问题来了:如何实时的显示文件上传的进 ...

  10. cmd 窗口配置mysql数据库

    1.运行-cmd 进入command 窗口 首先cd 到mysql目录下的bin的 路运行-cmd 进入command 窗口 首先cd 到mysql目录下的bin的路径.注意cd D盘时直接输入D:就 ...