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

解决思路:

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

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

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

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

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

    Linunx(本次为ubuntu) apache! 连接数理论上当然是支持越大越好,但要在服务器的能力范围内,这跟服务器的CPU.内存.带宽等都有关系. 查看当前的连接数可以用: ps aux | g ...

  2. 2018-2019-2 网络对抗week1 Kali安装 20165333陈国超

    Kali安装 安装过程是按照网上的教程装的,链接点击[https://blog.csdn.net/KNIGH_YUN/article/details/79949512] 安装成功的截图 主要说一下安装 ...

  3. 移除powerdesigner中Recent Files中无效链接的文件

    最近总算折腾清楚了,如何删除PowerDesigner中Recent Files或者recent models中不想显示的PDM文件链接: 解决方案: 将原文件的名称改变下,点击原先的文件链接,提示已 ...

  4. python第三方包安装方法(两种方法)

    具体有以下两种方法: 第一种方法(不使用pip或者easy_install): Step1:在网上找到的需要的包,下载下来.eg. rsa-3.1.4.tar.gz Step2:解压缩该文件. Ste ...

  5. JDK的get请求方式

    package com.example.wang.testapp3; import android.app.ProgressDialog; import android.os.Bundle; impo ...

  6. 【AtCoder】AGC017

    在此处输入标题 标签(空格分隔): 未分类 A - Biscuits dp[i][0/1]表示当前和是偶数还是奇数,直接转移即可 #include <bits/stdc++.h> #def ...

  7. 002 在大数据中基础的llinux基本命令

    一:基本命令 1.显示当前的目录 2.长格式显示目录自身的信息 3.创建文件 4.创建目录 创建多层目录,使用-p. 5.删除目录或者文件 -f:不提示,强制删除 -i:删除前,提示 -r:删除目录以 ...

  8. eric6中ui文件编译失败,提示找不到puicc5

    1解决办法 在setting中——preference 找到qt设置——pyQT工具文件选择更改为: 我的pyuicc5.exe文件在这个目录下 然后右击编译窗口,就成功了. 如果找不到ui文件,在窗 ...

  9. Linux —— 文件处理指令

  10. php特别值

    if(!isset($lichi)){ echo'未定义'; if(empty($lichi)){ echo '未定义的显示为空的';//最终会走到这来 } } 手册类型比较表 empty为真$x = ...