热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【OpenCV4实战】掌握OpenCV中的键盘和鼠标事件处理技巧

在《OpenCV4实战》中,本文详细介绍了如何在OpenCV中处理键盘和鼠标事件。首先,针对键盘事件,文章涵盖了基本原理、如何确定按键响应值以及通过按键调节图像亮度的具体方法。接着,对于鼠标事件,文章不仅讲解了基础理论,还提供了示例程序,帮助读者更好地理解和应用这些技术。通过这些内容,读者可以全面掌握OpenCV中键盘和鼠标事件的处理技巧。


键盘与鼠标的响应

    • 一、键盘的响应
        • 1.1 基本知识
        • 1.2 确定按键响应值
        • 1.3 按键调节亮度
    • 二、鼠标的响应
        • 1.1 基本知识
        • 1.2 示例程序


一、键盘的响应


1.1 基本知识

  按键的读取只需要使用waitKey()函数就可以实现,十分简单。

int waitKey(int delay=0)

  函数参数为延时时间(ms)
  delay<&#61;0时&#xff0c;等待时间无限长&#xff0c;按下按键时函数结束&#xff0c;返回按键的键值。·
  delay>0时&#xff0c;等待delay毫秒按键响应&#xff0c;等待时间结束仍未按下按键则返回-1。


本人opencv4&#43;vs2019实操时&#xff0c;没有按键时不返回值&#xff0c;有按键按下时返回对应键值。



1.2 确定按键响应值

  使用如下代码&#xff0c;可以测试自己的键盘对应的键值是多少。

void MyDemo::key_Demo(Mat& image) {while(true) {char k &#61; waitKey(0);std::cout << k << std::endl;}
}


1.3 按键调节亮度

/*按下1时&#xff1a;图片亮度增大
按下2时&#xff0c;图片亮度减小
按下q时&#xff0c;程序退出*/

void MyDemo::key_Demo(Mat& image) {Mat m &#61; Mat::zeros(image.size(),image.type());m &#61; Scalar(10, 10, 10); //增大或减小图片亮度的变化量while(true) {char k &#61; waitKey(10);if (k &#61;&#61; &#39;q&#39;) { // Quitbreak;}if (k &#61;&#61; &#39;1&#39;) { //Key 1std::cout << "You enter key 1 - Lightness Up." << std::endl;add(image, m, image);}if (k &#61;&#61; &#39;2&#39;) { //Key 2std::cout << "You enter key 2 - Lightness Down." << std::endl;subtract(image, m, image);}imshow("Key", image);}
}

二、鼠标的响应


1.1 基本知识

  鼠标响应所使用的函数主要是 setMouseCallback()

void setMousecallback(const string& winname, //窗口的名字MouseCallback onMouse, //鼠标响应回调函数void* userdata&#61;0 //传给回调函数的参数);

  其中onMouse响应回调函数函数&#xff0c;作用为指定窗口里每次鼠标时间发生的时候&#xff0c;被调用的函数指针。 这个函数的原型应该为的原型如下&#xff1a;

void on_Mouse(int event, //事件回传代号int x, //鼠标指针在图像坐标系的坐标xint y, //鼠标指针在图像坐标系的坐标yint flags, //CV_EVENT_FLAG的组合void* userdata //传递的参数
);

Event作用
EVENT_MOUSEMOVE滑动
EVENT_LBUTTONDOWN左键点击
EVENT_RBUTTONDOWN右键点击
EVENT_MBUTTONDOWN中键点击
EVENT_LBUTTONUP左键放开
EVENT_RBUTTONUP右键放开
EVENT_MBUTTONUP中键放开
EVENT_LBUTTONDBLCLK左键双击
EVENT_RBUTTONDBLCLK右键双击
EVENT_MBUTTONDBLCLK中键双击

1.2 示例程序

  在图像上实现拖动绘制矩形的画板功能。
请添加图片描述

Point sp(-1, -1); //起始点&#xff08;初始值-1&#xff0c;-1&#xff09;
Point ep(-1, -1); //结束点&#xff08;初始值-1&#xff0c;-1&#xff09;
Mat temp; //原图的克隆&#xff0c;用于实时刷新图片static void on_draw(int event, int x, int y, int flags, void* userdata) {Mat bg &#61; *(Mat*)userdata; //回调函数传过来的图像数据if (event &#61;&#61; EVENT_LBUTTONDOWN) { //如果左键被按下sp.x &#61; x; //保存左键按下时的xy值sp.y &#61; y;std::cout << "Start point: " << sp << std::endl;}else if (event &#61;&#61; EVENT_LBUTTONUP) {//如果左键被抬起ep.x &#61; x; //保存左键抬起时的xy值ep.y &#61; y;int dx &#61; ep.x - sp.x; //计算矩形长宽int dy &#61; ep.y - sp.y;if (dx > 0 && dy > 0) { //当矩形长宽都为正数时Rect box(sp.x, sp.y, dx, dy);rectangle(bg, box, Scalar(0, 0, 255), 2, 8, 0); //绘制矩形imshow("Mouse Drawing", bg);imshow("ROI", temp(box)); //显示ROI区域&#xff08;被框选的区域&#xff09;sp.x &#61; -1; //起始点坐标复位sp.y &#61; -1;}}else if (event &#61;&#61; EVENT_MOUSEMOVE) {if (sp.x > 0 && sp.y > 0) { //当起始点坐标不是初始值&#xff0c;且鼠标移动时ep.x &#61; x;ep.y &#61; y;int dx &#61; ep.x - sp.x;int dy &#61; ep.y - sp.y;if (dx > 0 && dy > 0) {Rect box(sp.x, sp.y, dx, dy);temp.copyTo(bg); //刷新屏幕&#xff0c;清除上一循环绘制的矩形rectangle(bg, box, Scalar(0, 0, 255), 2, 8, 0); //绘制新矩形imshow("Mouse Drawing", bg);}}}
}void MyDemo::mouseDrawing_Demo(Mat& image) {namedWindow("Mouse Drawing", WINDOW_AUTOSIZE); //创建一个窗口setMouseCallback("Mouse Drawing", on_draw,(void*)(&image)); //调用鼠标回调函数imshow("Mouse Drawing", image);temp &#61; image.clone();
}

推荐阅读
  • Flutter入门指南:实现自动关闭的对话框与提示
    本文为Flutter系列教程的一部分,专注于讲解如何在Flutter应用中实现自动关闭的对话框和提示。通过具体的代码示例,帮助开发者掌握SnackBar、BottomSheet和Dialog的使用方法。 ... [详细]
  • 本文深入探讨了Java注解的基本概念及其在现代Java开发中的应用。文章不仅介绍了如何创建和使用自定义注解,还详细讲解了如何利用反射机制解析注解,以及Java内建注解的使用场景。 ... [详细]
  • InnoSetup打包的软件需要在安装和卸载时检查程序是否在运行,不然会安装失败或者卸载不完全,网上搜了一下,有几种方法: ... [详细]
  • 学习目的:1.了解android线程的使用2.了解主线程与子线程区别3.解析异步处理机制主线程与子线程:所谓主线程,在Windows窗体应用程序中一般指UI线程,这个是程序启动的时 ... [详细]
  • 快速排序是一种高效的排序算法,以其在多数情况下接近最优的性能而著称。本文将详细介绍如何在 Java 中实现快速排序,并分析其工作原理。 ... [详细]
  • 在现代多线程编程中,Lock接口提供的灵活性和控制力超越了传统的synchronized关键字。Lock接口不仅使锁成为一个独立的对象,还提供了更细粒度的锁定机制,例如读写锁(ReadWriteLock)。本文将探讨如何利用ReentrantReadWriteLock提高并发性能。 ... [详细]
  • Java WebSocket 实时通信服务端实现
    本文介绍了一个基于Java的WebSocket实时通信服务端代码示例,包括客户端连接管理、消息接收与分发等功能。 ... [详细]
  • 线程是创建并发的底层工具,因此具有一定的局限性。没有简单的方法可以从联合(Join)线程得到“返回值”。因此必须创建一些共享域。当抛出一个异常时,捕捉和处理异常也是麻烦的。线程完成之后,无法再次启动该 ... [详细]
  • 本文详细介绍了 C# 编程语言中 Main 方法的作用、不同形式及其使用场景,帮助开发者更好地理解和应用这一重要概念。 ... [详细]
  • 本文介绍了一种利用迭代法解决特定方程问题的方法,特别是当给定函数f(x)在区间[x1, x2]内连续且f(x1)0时,存在一个x~使得f(x~)=0。通过逐步细化搜索范围,可以高效地找到方程的根。 ... [详细]
  • 转载网址:http:www.open-open.comlibviewopen1326597582452.html参考资料:http:www.cocos2d-ip ... [详细]
  • 一个产品数组拼图|集合 2 (O(1)空间) ... [详细]
  • 本文档详细介绍了服务器与应用系统迁移的策略与实施步骤。迁移不仅涉及数据的转移,还包括环境配置、应用兼容性测试等多个方面,旨在确保迁移过程的顺利进行及迁移后的系统稳定运行。 ... [详细]
  • 快速排序是基于分治策略的一种排序算法,其平均时间复杂度为O(n log n),在大多数情况下表现优于其他排序算法。本文将详细介绍快速排序的工作原理,并提供一个Java语言的具体实现。 ... [详细]
  • 本文探讨了如何在TensorFlow中使用张量来处理和分析数字图像,特别是通过具体的代码示例展示了张量在图像处理中的作用。 ... [详细]
author-avatar
阿穆尔湾的阿娜莎
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有