用户通过鼠标对图像视窗最常见的操作有:

1. 左键单击按下

2. 左键单击抬起

3. 左键按下拖动

4. 鼠标指针位置移动

单次单击操作响应事件及顺序

Opencv中setMouseCallback()创建了一个鼠标回调函数,每次在图像上单击鼠标左键再抬起的过程,都会分3次调用鼠标响应函数,并且响应顺序是:

1.左键单击按下;

2.左键单击抬起;

3.鼠标指针位置移动(即使原地单击,鼠标位置并没有移动);

可以编码验证一下回调函数的这个调用机制:

#include "core/core.hpp"
#include "highgui/highgui.hpp"
#include "imgproc/imgproc.hpp"
#include<iostream> using namespace cv;
using namespace std; void OnMouseAction(int event,int x,int y,int flags,void *ustc); //鼠标回调事件函数
int static times; //记录调用次数 int main(int argc,char*argv[])
{
Mat image=imread(argv[1]);
imshow("image",image);
setMouseCallback("image",OnMouseAction);
waitKey();
system("pause");
} //*******************************************************************//
//鼠标回调函数 void OnMouseAction(int event,int x,int y,int flags,void *ustc)
{
times++;
cout<<"第 "<<times<<" 次回调鼠标事件"<<endl;
if(event==CV_EVENT_MOUSEMOVE)
{
cout<<"触发鼠标移动事件"<<endl;
}
if(event==CV_EVENT_LBUTTONDOWN)
{
cout<<"触发左键按下事件"<<endl;
}
if(event==CV_EVENT_LBUTTONUP)
{
cout<<"触发左键抬起事件"<<endl;
}
if(event==CV_EVENT_RBUTTONDOWN)
{
cout<<"触发右键按下事件"<<endl;
}
if(event==CV_EVENT_RBUTTONUP)
{
cout<<"触发右键抬起事件"<<endl;
}
if(event==CV_EVENT_LBUTTONDBLCLK)
{
cout<<"触发左键双击事件"<<endl;
}
if(event==CV_EVENT_RBUTTONDBLCLK)
{
cout<<"触发右键双击事件"<<endl;
}
}

前3次调用是在左键单击前鼠标指针在图像窗口移动造成的。不移动位置,单击左键,触发了第4次调用,红色框框内的就是一个完整的鼠标按下再抬起的调用过程:

第一次传入的event事件是左键单击“CV_EVENT_LBUTTONDOWN”;

第二次传入的event事件是左键抬起“CV_EVENT_LBUTTONUP”;

第三次传入的event事件是鼠标移动“CV_EVENT_MOUSEMOVE”,这时候鼠标物理位置其实并没有移动;

setMouseCallback()函数

了解了鼠标回调函数的调用机制后再来看一下创建回调函数的函数setMouseCallback();

原型:

void setMouseCallback(const string& winname,     //图像视窗名称
MouseCallback onMouse,     //鼠标响应函数,监视到鼠标操作后调用并处理相应动作
void* userdata = 0       //鼠标响应处理函数的ID,识别号
);

OnMouseAction()响应函数

鼠标事件回调函数onMouse按照固定格式创建响应函数:

void OnMouseAction(int event,int x,int y,int flags,void *ustc) 

event事件代表了鼠标的各种操作,详细看一下各个event事件:

Event:
#define CV_EVENT_MOUSEMOVE 0 //滑动
#define CV_EVENT_LBUTTONDOWN 1 //左键点击
#define CV_EVENT_RBUTTONDOWN 2 //右键点击
#define CV_EVENT_MBUTTONDOWN 3 //中键点击
#define CV_EVENT_LBUTTONUP 4 //左键放开
#define CV_EVENT_RBUTTONUP 5 //右键放开
#define CV_EVENT_MBUTTONUP 6 //中键放开
#define CV_EVENT_LBUTTONDBLCLK 7 //左键双击
#define CV_EVENT_RBUTTONDBLCLK 8 //右键双击
#define CV_EVENT_MBUTTONDBLCLK 9 //中键双击

int x,int y,代表鼠标位于窗口的(x,y)坐标位置,即Point(x,y);

int flags,代表鼠标的拖拽事件,以及键盘鼠标联合事件,共有32种事件:

flags:
#define CV_EVENT_FLAG_LBUTTON 1 //左鍵拖曳
#define CV_EVENT_FLAG_RBUTTON 2 //右鍵拖曳
#define CV_EVENT_FLAG_MBUTTON 4 //中鍵拖曳
#define CV_EVENT_FLAG_CTRLKEY 8 //(8~15)按Ctrl不放事件
#define CV_EVENT_FLAG_SHIFTKEY 16 //(16~31)按Shift不放事件
#define CV_EVENT_FLAG_ALTKEY 32 //(32~39)按Alt不放事件

函数指针 void *ustc标识了所响应的事件函数,相当于自定义了一个OnMouseAction()函数的ID。

简单应用:记录鼠标按下时坐标和鼠标抬起时坐标,分别做Line、Rectangle、Circle

#include "core/core.hpp"
#include "highgui/highgui.hpp"
#include "imgproc/imgproc.hpp"
#include<iostream> using namespace cv;
using namespace std; void OnMouseAction(int event,int x,int y,int flags,void *ustc); //鼠标回调事件函数
int static times; //记录调用次数 int rowsBegin,rowsEnd;
int colsBegin,colsEnd;
Mat image; int main(int argc,char*argv[])
{
image=imread(argv[1]);
imshow("image",image);
setMouseCallback("image",OnMouseAction);
} //*******************************************************************//
//鼠标回调函数
void OnMouseAction(int event,int x,int y,int flags,void *ustc)
{
if(event==CV_EVENT_MOUSEMOVE)
{
cout<<"触发鼠标移动事件"<<endl;
}
if(event==CV_EVENT_LBUTTONDOWN)
{
rowsBegin=y;
colsBegin=x;
cout<<"触发左键按下事件"<<endl;
}
if(event==CV_EVENT_LBUTTONUP)
{
rowsEnd=y;
colsEnd=x;
line(image,Point(colsBegin,rowsBegin),Point(colsEnd,rowsEnd),Scalar(255,0,0),2,8,0);
rectangle(image,Rect(colsBegin,rowsBegin,colsEnd-colsBegin,rowsEnd-rowsBegin),Scalar(0,255,0),2,8,0);
circle(image,Point((colsEnd+colsBegin)/2,(rowsEnd+rowsBegin)/2),rowsEnd-rowsBegin,Scalar(0,0,255),2,8,0);
imshow("image",image);
cout<<"触发左键抬起事件"<<endl;
}
if(event==CV_EVENT_RBUTTONDOWN)
{
cout<<"触发右键按下事件"<<endl;
}
if(event==CV_EVENT_RBUTTONUP)
{
cout<<"触发右键抬起事件"<<endl;
}
if(event==CV_EVENT_LBUTTONDBLCLK)
{
cout<<"触发左键双击事件"<<endl;
}
if(event==CV_EVENT_RBUTTONDBLCLK)
{
cout<<"触发右键双击事件"<<endl;
}
}

左键单击按下之后拖动鼠标到某一个位置之后松开:

Opencv函数setMouseCallback鼠标事件响应的更多相关文章

  1. DuiLib事件分析(一)——鼠标事件响应

    最近在处理DuiLib中自定义列表行元素事件,因为处理方案得不到较好的效果,于是只好一层一层的去剥离DuiLib事件是怎么来的,看能否在某一层截取消息,自己重写. 我这里使用CListContaine ...

  2. HTML5 精灵8方向移动+背景滚动+音效播放+鼠标事件响应

    如何清空画布 通过调用函数 ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);   如何实现背景滚动 首先我们准备了一张2532*940 ...

  3. 关于CMainFrm不接收鼠标事件响应原因

    CMainFrm即主框架窗口对鼠标的左键和右键在OnLButtonDown中无响应 解决方案: 1.在OnNcLButtonDown中响应.(即非客户区中响应) 参考文献:http://www.cod ...

  4. opencv入门系列教学(四)处理鼠标事件

    一.鼠标事件的简单演示 opencv中的鼠标事件,值得是任何与鼠标相关的任何事物,例如左键按下,左键按下,左键双击等.我们先来看看鼠标事件有哪些,在python中执行下面代码: import cv2 ...

  5. C语言控制台窗体图形界面编程(八):鼠标事件

           上次讲的是键盘事件,这次我们介绍鼠标事件. 以下先介绍下鼠标事件的结构体以及相关信息. typedef struct _MOUSE_EVENT_RECORD //鼠标事件结构体 { CO ...

  6. libevent源码分析一--io事件响应

    这篇文章将分析libevent如何组织io事件,如何捕捉事件的发生并进行相应的响应.这里不会详细分析event与event_base的细节,仅描述io事件如何存储与如何响应. 1.  select l ...

  7. Opencv下图像对鼠标事件的响应

    直接上代码: //////////////////////////////////////////////////////////////////////// // // 该程序从文件中读入一幅图像, ...

  8. opencv鼠标事件

    #include <opencv2\opencv.hpp> using namespace cv; struct mouse_para { cv::Mat org; cv::Mat img ...

  9. Opencv处理鼠标事件-OpenCV步步精深

    在图片上双击过的位置绘制一个 圆圈 鼠标事件就是和鼠标有关的,比如左键按下,左键松开,右键按下,右键松开,双击右键等等. 我们可以通过鼠标事件获得与鼠标对应的图片上的坐标.我们通过以下函数来调用查看所 ...

随机推荐

  1. sqlplus 命令 错误

    SP2-1503: 无法初始化 Oracle 调用界面 用管理员运行就可以了

  2. SecureCRT 配置文件中 找密码

    打开本地电脑如下路径 C:\Users\XXX\AppData\Roaming\VanDyke\Config\Sessions 找到配置文件. 运行命令:python SecureCRTDecrypt ...

  3. noip2015提高组day2解题报告

    1.跳石头 题目描述 一年一度的“跳石头”比赛又要开始了! 这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石.组委会已经选择好了两块岩石作为比赛起点和终点.在起点和终点之间,有 N 块岩石( ...

  4. MySQL、Hive以及MySQL Connector/J安装过程

    MySQL安装 ①官网下载mysql-server(yum安装) wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch. ...

  5. Maven实现多个项目关联自动化构建(maven-invoker-plugin插件的使用)

    以下内容引用自https://ayayui.gitbooks.io/tutorialspoint-maven/content/book/maven_build_automation.html: 注意: ...

  6. SSD TRIM

    SSD 在操作方式上与传统磁性驱动器不同,并且它们需要在软件上另行处理以达到功能优化.-- Don Watkins 编译自: https://opensource.com/article/17/1/s ...

  7. C/C++二进制读写png文件

    以下代码只有最简单的读写.地址定位啥的,个别注释中有.如果要改动png的格式甚么的就要再了解一下png的数据结构如果要十进制的话就跟着注释改一下: /*! * \file CC++二进制读写png文件 ...

  8. C# step by step 学习笔记8 CHAPTER 9 使用枚举和结构创建值类型

    C# 2012 step by step 学习笔记8 CHAPTER 9 使用枚举和结构创建值类型 本章内容 声明一个枚举类型 创建并使用一个枚举类型 声明一个结构类型 创建并使用一个结构类型 解释结 ...

  9. TListView使用方法1(转)

    ListView1.Items 为标准 Tlistitems类 ListView1.Items (1)赋值 with ListView1.Items.Add do begin Caption:=cap ...

  10. to_char(sysdate,'D')的用法

    select to_char(sysdate,'D') from dual;   这周的第几天:Day of week (1–7) 1,2,3,4,5,6,7--注意:每星期的第1天是”星期日“ se ...