2.10鼠标事件

news2024/9/24 17:18:17

目录

实验原理

实验代码

运行结果

文章参考


实验原理

在 OpenCV 中存在鼠标的操作,比如左键单击、双击等。对于 OpenCV 来讲,用户的鼠标操作被认为发生了一个鼠标事件,需要对这个鼠标事件进行处理,这就是事件的响应。下面我们来介绍一下鼠标事件。 
鼠标事件包括左键按下、左键松开、左键双击、鼠标移动等。当鼠标事件发生时,OpenCV 会让一个鼠标响应函数自动被调用,相当于一个回调函数,这个回调函数就是鼠标事件处理函数。 OpenCV 提供了 setMousecallback 来预先设置回调函数(相当于告诉系统鼠标处理的回调函数已经设置好了,有鼠标事件发生时,系统调用这个回调函数即可),注意是系统调用,而不是开发者调用,因此称为回调函数。函数 setMousecallback 声明如下: 

void setMousecallback(const string& winname, MouseCallback onMouse, void*userdata=0);
其中参数
winname 表示窗口的名字,
onMouse 是鼠标事件响应的回调函数指针,
userdate 是传给回调函数的参数。
这个函数名也比较形象,一看就知道是用来设置鼠标回调函数的。 

鼠标事件回调函数类型 MouseCallback 定义如下:

typedef void(* cv::MouseCallback)(int event,int x,int y,int flags,void*useradata);
其中参数 
event 表示鼠标事件,
x 表示鼠标事件的 x 坐标,
y 表示鼠标事件的 y 坐标,
flags 表示鼠标事件的标志,
userdata 是可选的参数。 

鼠标事件 event 主要有以下几种:

enum
{
EVENT_MOUSEMOVE =0, //滑动
EVENT_LBUTTONDOWN =1, //左键单击
EVENT_RBUTTONDOWN=2,//右键单击
EVENT_MBUTTONDOWN=3,//中键单击
EVENT_LBUTTONUP=4,//左键放开
EVENT_RBUTTONUP=5,//右键放开
EVENT_MBUTTONUP=6,//中键放开
EVENT_LBUTTONDBLCLK=7,//左键双击
EVENT_RBUTTONDBLCLK=8,//右键双击
EVENT_MBUTTONDBLCLK=9,//中键双击
EVENT_MOUSEWHEEL=10,//正值表示向前滚动,负值表示向后滚动
EVENT_MOUSEHWHEEL=11//正值表示向左滚动,负值表示向右滚动
};

鼠标事件标志 flags 主要有以下几种:

enum {
EVENT_FLAG_LBUTTON = 1,//按住左键拖曳
EVENT_FLAG_RBUTTON = 2,//按住右键拖曳
EVENT_FLAG_MBUTTON = 4,//按住中键拖曳
EVENT_FLAG_CTRLKEY = 8,//按 Ctrl
EVENT_FLAG_SHIFTKEY = 16,//按 Shift
EVENT_FLAG_ALTKEY = 32//按 Alt
};

通过 event 和 flags 就能清楚地了解当前鼠标发生了哪种操作。

https://cloud.tencent.com/developer/article/1553511icon-default.png?t=N7T8https://cloud.tencent.com/developer/article/1553511

line()函数来对直线的绘制。

//https://www.opencv.org.cn/opencvdoc/2.3.2/html/modules/core/doc/drawing_functions.html?highlight=line#cv.Line
void line(Mat& img, Point pt1, Point pt2, const Scalar& color, int thickness=1, int lineType=8, int shift=0);

参数:
img: 要绘制线段的图像。
pt1: 线段的起点。
pt2: 线段的终点。
color: 线段的颜色,通过一个Scalar对象定义。
thickness: 线条的宽度。
lineType: 线段的类型。可以取值8, 4, 和CV_AA, 
分别代表8邻接连接线,4邻接连接线和反锯齿连接线。
默认值为8邻接。为了获得更好地效果可以选用CV_AA(采用了高斯滤波)。
shift: 坐标点小数点位数。

实验代码


#include "pch.h"
#include <opencv2/highgui/highgui_c.h>
#include <opencv2\opencv.hpp>
//#pragma comment(lib, "opencv_world450d.lib")  //引用引入库 
using namespace cv;
#include<iostream>
using namespace std;
 

#define WINDOW "原图"
Mat g_srcImage, g_dstImage;
Point previousPoint;
bool P = false;
void on_mouse(int event, int x, int y, int flags, void*);
int main()
{
	g_srcImage = imread("200.jpg", 1);
	imshow(WINDOW, g_srcImage);
	setMouseCallback(WINDOW, on_mouse, 0);

	waitKey(0);
	return 0;
}
void on_mouse(int event, int x, int y, int flags, void*)
{
	if (event == EVENT_LBUTTONDOWN)
	{
		previousPoint = Point(x, y);
	}
	else if (event == EVENT_MOUSEMOVE && (flags&EVENT_FLAG_LBUTTON))
	{
		Point pt(x, y);
		line(g_srcImage, previousPoint, pt, Scalar(0, 0, 255), 2, 5, 0);
		//https://blog.csdn.net/hk121/article/details/81085213
		previousPoint = pt;
		imshow(WINDOW, g_srcImage);
	}
}

在代码中,on_mouse 就是用来处理鼠标事件的回调函数,当鼠标有动作产生时,on_mouse 会被系统调用,然后在 on_mouse 中,判断发生了哪种动作,进而进行相应的处理。本例我们关心的是按下鼠标左键,然后按住左键时的鼠标移动。一旦按下鼠标左键,就记录下当时的位置(也就是画线的开始点),位置记录在 previousPoint 中,接着如果继续有鼠标移动事件发生,我们就开始调用函数 line 画线。最后把画了线的图像数据 g_srcImage 用函数 imshow 显示出来。

运行结果

文章参考

程序中如果鼠标右键被按下,则会提示“点击鼠标左键才可以绘制轨迹”,点击左键会输出当前鼠标的坐标,并将该点坐标定义为某段轨迹的起始位置。之后按住左键移动鼠标,会进入到第三个逻辑判断,绘制鼠标的移动轨迹。

示例程序中提供了两种绘制轨迹的方法,

第一种是每次调用回调函数获得鼠标位置时更改周围的图像像素值,这种方式比较直观,但是由于回调函数有一定的执行时间,因此当鼠标移动较快时绘制的图像轨迹会出现断点

第二种绘制轨迹的方式是在前一时刻和当前时刻鼠标位置间绘制直线,这种方式可以避免因鼠标移动过快而带来的轨迹出现断点的问题。

https://cloud.tencent.com/developer/article/1553511

// myMouse.cpp绘制鼠标移动轨迹
#include "pch.h"
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;
using namespace cv;

Mat img, imgPoint; //全局的图像
Point prePoint; //前一时刻鼠标的坐标,用于绘制直线
void mouse(int event, int x, int y, int flags, void*);

int main()
{
	img = imread("200.jpg");
	if (!img.data)
		{
		cout << "请确认输入图像名称是否正确!" << endl;
		system("pause");
		return -1;
		 }
    img.copyTo(imgPoint);
	imshow("图像窗口1", img);
	imshow("图像窗口2", imgPoint);
	setMouseCallback("图像窗口1", mouse, 0); //鼠标事件
	waitKey(0);
	system("pause");
	return 0;
	}

void mouse(int event, int x, int y, int flags, void*)
{
	if (event == EVENT_RBUTTONDOWN) //单击右键
		{
		cout << "点击鼠标左键才可以绘制轨迹" << endl;
		}
	if (event == EVENT_LBUTTONDOWN) //单击左键,输出坐标
		{
		prePoint = Point(x, y);
		cout << "轨迹起使坐标" << prePoint << endl;
		 }
	if (event == EVENT_MOUSEMOVE && (flags & EVENT_FLAG_LBUTTON)) //鼠标按住左键移动
		{
		//通过改变图像像素显示鼠标移动轨迹
		imgPoint.at<Vec3b>(y, x) = Vec3b(0, 0, 255);
		imgPoint.at<Vec3b>(y, x - 1) = Vec3b(0, 0, 255);
		imgPoint.at<Vec3b>(y, x + 1) = Vec3b(0, 0, 255);
		imgPoint.at<Vec3b>(y + 1, x) = Vec3b(0, 0, 255);
		imgPoint.at<Vec3b>(y + 1, x) = Vec3b(0, 0, 255);
		imshow("图像窗口2", imgPoint);
		
      //通过绘制直线显示鼠标移动轨迹
		Point pt(x, y);
		line(img, prePoint, pt, Scalar(0, 0, 255), 2, 5, 0);
		prePoint = pt;
		imshow("图像窗口1", img);
		}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2084284.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

手机ip频繁跳动的原因是什么?手机ip地址老是变怎么解决

在当今数字化时代&#xff0c;‌手机已成为我们生活中不可或缺的一部分。‌然而&#xff0c;‌有些用户可能会遇到手机IP地址频繁变动的问题&#xff0c;‌这不仅可能影响网络连接的稳定性&#xff0c;‌还可能对特定的在线活动造成困扰。‌本文将深入探讨手机IP频繁跳动的原因…

传输大咖36 | 镭速轻松解决医疗卫生行业跨网文件传输难题

在医疗领域&#xff0c;医疗数据的关键性显而易见。病历详尽记载与医学影像数据等&#xff0c;均为确保精确诊断与治疗成效的基石。但是&#xff0c;医疗数据量的迅猛增长使得传统文件传输方法的不足之处日益凸显&#xff0c;难以跟上现代医学的步伐。特别是在跨网文件交换这一…

SSM框架之Mybatis

前言 什么是框架&#xff1f; 框架就是对技术的封装&#xff0c;将基础的技术进行封装&#xff0c;便于程序员使用&#xff0c;提高开发效率 ssm框架是什么&#xff1f; ssm包括spring、springMvc、Mybatis&#xff0c;是后端企业级开发时会使用到的框架组合&#xff0c;在…

无人机搭载高压喷水清洗绝缘子技术详解

随着电力行业的快速发展&#xff0c;高压输电线路作为电力传输的“大动脉”&#xff0c;其安全稳定运行至关重要。绝缘子作为输电线路中的重要组件&#xff0c;长期暴露于自然环境中&#xff0c;易受尘埃、鸟粪、盐雾等污染物附着&#xff0c;导致绝缘性能下降&#xff0c;甚至…

Visual Basic 6.0教程/Visual Basic从入门到实践/Visual Basic学习视频教程

Visual Basic 6.0教程/Visual Basic从入门到实践/Visual Basic学习视频教程 李天生VB从入门到精通 第一章 VisualBasic6基本介绍 第二章 VisualBasic6的数据类型与运算符表达式 第三章 VisualBasic6的内部函数 第四章 VisualBasic6的基本语句 第五章 VisualBasic6的数组 第六章…

AMC8美国数学竞赛备考:吃透625道真题和知识点(持续)

距离接下来最近的2025年AMC8美国数学竞赛还有几个月的时间&#xff0c;实践证明&#xff0c;做真题&#xff0c;吃透真题和背后的知识点是备考AMC8有效的方法之一。 2000-2024年AMC8真题和解析&#xff1a;2023年第13题 这道题的考点是分数。 题意的重点是均匀分布&#xff0c…

OpenCV绘图函数(5)绘制标记函数drawMarker()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 cv::drawMarker 函数在 OpenCV 中用于在一个给定的位置上绘制标记。目前支持几种不同的标记类型&#xff0c;具体信息可以参考 MarkerTypes 函数…

这样图解Transformer应该没人看不懂了吧——多头注意力机制详解

这是关于Transformer系列文章的第三篇部分&#xff0c;我们将用自上而下的方式深入探讨Transformer的功能。 在前两篇文章中&#xff0c;我们已经了解了Transformer是什么、它的架构以及工作原理。 没看过的同学可以点击图片进行查看 Transformer图解1—基础与架构 Transform…

ITopologicalOperator.Intersect 直接崩软件,也不报错的解决方案

1、问题描述&#xff1a; 说多崩溃就有多崩溃&#xff0c;执行到下面这个相交分析的时候&#xff0c;就一直崩软件&#xff0c;用catch也catch不到东西&#xff0c;相同的数据放到另外一个工程中的时候&#xff0c;又是正常的&#xff0c;一直找不到原因。 2、终级方案 最终…

LLM - 自定义图像数据集 使用 LoRA 微调 图像生成 Flux 模型

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/141638928 免责声明&#xff1a;本文来源于个人知识与公开资料&#xff0c;仅用于学术交流&#xff0c;欢迎讨论&#xff0c;不支持转载。 在 Dif…

假设以带头结点的循环链表表示队列,并且只设一个指针指向队尾元素结点(注意不设头指针),试编写相应的置空队列、判断队列是否为空、入队和出队等算法。

typedef int Datatype; typedef struct queue {Datatype data;struct queue* next; }queue; //队列 typedef struct {queue* rear; }LinkQueue; //初始化 void queueinit(LinkQueue* ps) {ps->rear (queue*)malloc(sizeof(queue));if (ps->rear NULL){perror("err…

家里养宠物空气净化器有用吗,应该怎么挑选宠物空气净化器

养猫&#xff0c;无疑给了我们很多陪伴和乐趣&#xff0c;为我们的生活添上了无数温馨的色彩。然而&#xff0c;在这份甜蜜的负担中&#xff0c;猫毛的问题确实成为了不少铲屎官们共同的“小烦恼”。这些浮毛总能在你最不经意的时候&#xff0c;悄悄占领家中的每一个角落。每天…

不仅仅是文化:解决常见安全问题根源

今年&#xff0c;GitLab对DevSecOps专业人士的年度调查发现了一些与组织文化相关的问题&#xff0c;这些问题可能会阻碍工程团队和安全团队之间的更深层次协调。 大多数(58%)的安全受访者表示&#xff0c;他们很难让开发部门优先修复漏洞&#xff0c;52%的人表示&#xff0c;繁…

Getting AttributeError when using openAI python library

题意&#xff1a;“使用 OpenAI Python 库时出现 AttributeError” 问题背景&#xff1a; Im building a new AI chatbot utilizing the openai library and I have a gradio UI set up in one file (app.py) and a predict() function in another (trainedBot.py) Every time…

【Threejs学习】材质灯光投影

一、光源分类 环境光(AmbientLight)&#xff1a;会均匀的照亮场景中的所有物体。无方向&#xff0c;不能投射阴影。平行光(DirectionalLight)&#xff1a;沿特定方向散发的光&#xff0c;发出的光线都是平行的。例如太阳光&#xff0c;可投射阴影。点光源(PointLight)&#xf…

2024年大学生适合入手的蓝牙耳机推荐?四款开放式耳机推荐

2024年大学生入手蓝牙耳机的话&#xff0c;我当然是比较推荐入手开放式蓝牙耳机的。 主要是因为开放式蓝牙耳机佩戴起来真的很舒适&#xff0c;它的开放式设计通常是轻巧且适配贴合不同耳型的&#xff0c;所以既不会对耳朵造成压迫感&#xff0c;也适合长时间佩戴使用。 不仅…

华为AC旁挂二层组网配置详解:从DHCP部署到无线业务配置,完成网络搭建

组网需求 AC组网方式&#xff1a;旁挂二层组网。 DHCP部署方式&#xff1a; AC作为DHCP服务器为AP分配IP地址。 防火墙作为DHCP服务器为STA分配IP地址。 业务数据转发方式&#xff1a;直接转发。 网络拓扑图 对于旁边路直接转发&#xff0c;优点就是数据流量不经过AC&…

ubuntu20.04(wsl2)测试 arcface 人脸识别(计算特征向量)

1. 参考博客和代码、模型仓库&#xff1a; 1.1. 【C随记】collect2: error: ld returned 1 exit status错误分析与解决 1.2. Visual Studio 2022新建 cmake 工程测试 tensorRT 自带样例 sampleOnnxMNIST 1.3.报错&#xff1a;ModuleNotFoundError: No module named ‘ten…

杭州城市开发者社区活动:《聚力AI,共创共荣》第二期线下AI论坛活动等你来!

由中也AI共荣社主办&#xff0c;COC杭州城市开发者社区等多家协办的《聚力AI&#xff0c;共创共荣》AI论坛活动来袭&#xff01; 活动围绕AI技术的创新应用&#xff0c;以及在实际应用落地的场景为主题展开&#xff0c;聚力AI&#xff0c;共同探讨。有机会与行业大咖进行面对面…

沙箱支付支付宝

沙箱支付支付宝 文章目录 沙箱支付支付宝一、进入沙箱应用-支付宝二、基本配置2.1 查看自己的基本信息2.2 生成自定义密钥&#xff0c;进行配置 三、springboot整合沙箱支付3.1 需要导入的两个相关依赖&#xff08;pom.xml&#xff09;3.2 需要加入的配置文件信息&#xff08;a…