【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的掩码运算后 ...
随机推荐
- linux上apache并发数与服务器内存关系计算!
Linunx(本次为ubuntu) apache! 连接数理论上当然是支持越大越好,但要在服务器的能力范围内,这跟服务器的CPU.内存.带宽等都有关系. 查看当前的连接数可以用: ps aux | g ...
- 2018-2019-2 网络对抗week1 Kali安装 20165333陈国超
Kali安装 安装过程是按照网上的教程装的,链接点击[https://blog.csdn.net/KNIGH_YUN/article/details/79949512] 安装成功的截图 主要说一下安装 ...
- 移除powerdesigner中Recent Files中无效链接的文件
最近总算折腾清楚了,如何删除PowerDesigner中Recent Files或者recent models中不想显示的PDM文件链接: 解决方案: 将原文件的名称改变下,点击原先的文件链接,提示已 ...
- python第三方包安装方法(两种方法)
具体有以下两种方法: 第一种方法(不使用pip或者easy_install): Step1:在网上找到的需要的包,下载下来.eg. rsa-3.1.4.tar.gz Step2:解压缩该文件. Ste ...
- JDK的get请求方式
package com.example.wang.testapp3; import android.app.ProgressDialog; import android.os.Bundle; impo ...
- 【AtCoder】AGC017
在此处输入标题 标签(空格分隔): 未分类 A - Biscuits dp[i][0/1]表示当前和是偶数还是奇数,直接转移即可 #include <bits/stdc++.h> #def ...
- 002 在大数据中基础的llinux基本命令
一:基本命令 1.显示当前的目录 2.长格式显示目录自身的信息 3.创建文件 4.创建目录 创建多层目录,使用-p. 5.删除目录或者文件 -f:不提示,强制删除 -i:删除前,提示 -r:删除目录以 ...
- eric6中ui文件编译失败,提示找不到puicc5
1解决办法 在setting中——preference 找到qt设置——pyQT工具文件选择更改为: 我的pyuicc5.exe文件在这个目录下 然后右击编译窗口,就成功了. 如果找不到ui文件,在窗 ...
- Linux —— 文件处理指令
- php特别值
if(!isset($lichi)){ echo'未定义'; if(empty($lichi)){ echo '未定义的显示为空的';//最终会走到这来 } } 手册类型比较表 empty为真$x = ...