Python OpenCV setMouseCallback 回调函数,取经之旅第 13 天

举报
梦想橡皮擦 发表于 2021/09/16 09:44:53 2021/09/16
【摘要】 你内心肯定有某种火焰,将你和其它人区别本篇博客将与你一起学习 OpenCV 中的 setMouseCallback,它也被称作回调函数。 为何要学习 setMouseCallback昨天学习图像标记之后,橡皮擦瞬间想到的就是能否手动标记,检索了一下资料,发现这部分内容可以从 setMouseCallback 回调函数学起。学习任何函数,建议先去官方手册查看一下基本语法,哪怕是英文的也没有关系...

你内心肯定有某种火焰,将你和其它人区别

本篇博客将与你一起学习 OpenCV 中的 setMouseCallback,它也被称作回调函数。

为何要学习 setMouseCallback

昨天学习图像标记之后,橡皮擦瞬间想到的就是能否手动标记,检索了一下资料,发现这部分内容可以从 setMouseCallback 回调函数学起。

学习任何函数,建议先去官方手册查看一下基本语法,哪怕是英文的也没有关系,看参数命名和返回值,可以猜出大概用法。

本函数在官方手册,并没有找到关于 Python 相关的声明,官方地址
满脸问号,不会被遗漏了吧。

既然没有,那就只能依赖 C++ 的语法,推测一下了。橡皮擦给你准备的语法格式如下:

cv2.setMouseCallback(windowName, onMouse [, userdata])

相关参数说明如下:

  • windowName:窗口的名字;
  • onMouse:鼠标响应函数,回调函数。
  • userdata:传给回调函数的参数

上面三个参数,最重要的是第二个,鼠标回调函数,该函数在鼠标事件发生时执行。

鼠标事件可以是与鼠标相关的任何内容,如左键点击,左键向上,右键点击等。

回调函数格式

上文提及的第二个参数,一般都会遵循下述函数原型,即 MouseCallback onMouse 的函数原型。

on_mouse(event, x, y, flags, param)

上述 on_mouse 可以为任意函数名,其它参数说明如下:

  • event 是 CV_EVENT_* 变量之一,CV_EVENT 见下表;
  • x 和 y 是鼠标在图像坐标系的坐标(不是窗口坐标系);
  • flags 是 CV_EVENT_FLAG 的组合;
  • param 是用户定义的传递到 setMouseCallback 函数调用的参数。

鼠标事件的种类可以通过下述代码获取。

import cv2
events = [i for i in dir(cv2) if 'EVENT' in i]
print(events)

输出下述内容:

['EVENT_FLAG_ALTKEY', 'EVENT_FLAG_CTRLKEY', 'EVENT_FLAG_LBUTTON', 'EVENT_FLAG_MBUTTON', 'EVENT_FLAG_RBUTTON',
'EVENT_FLAG_SHIFTKEY', 'EVENT_LBUTTONDBLCLK', 'EVENT_LBUTTONDOWN',
'EVENT_LBUTTONUP', 'EVENT_MBUTTONDBLCLK', 'EVENT_MBUTTONDOWN', 'EVENT_MBUTTONUP', 'EVENT_MOUSEHWHEEL',
'EVENT_MOUSEMOVE', 'EVENT_MOUSEWHEEL', 'EVENT_RBUTTONDBLCLK', 'EVENT_RBUTTONDOWN', 'EVENT_RBUTTONUP']

event 具体说明如下:

  • 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 //中键双击

flags 具体说明如下:

  • EVENT_FLAG_LBUTTON 1 //左键拖曳
  • EVENT_FLAG_RBUTTON 2 //右键拖曳
  • EVENT_FLAG_MBUTTON 4 //中键拖曳
  • EVENT_FLAG_CTRLKEY 8 //(8~15)按 Ctrl 不放
  • EVENT_FLAG_SHIFTKEY 16 //(16~31)按 Shift 不放
  • EVENT_FLAG_ALTKEY 32 //(32~39)按 Alt 不放

编码环节

准备知识已经学习完毕,接下来是应用环节。

下述案例,实现在河北地图上进行画圆操作,左键按下实心圆,右键按下空心圆。

import cv2 as cv


# 编写回调函数
def draw_circle(event, x, y, flags, param):
    # 鼠标左键按下去,实心圆
    if event == cv.EVENT_LBUTTONDOWN:
        cv.circle(img, center=(x, y), radius=5,
                  color=(255, 0, 0), thickness=-1)
    # 鼠标右键按下去,空心圆
    elif event == cv.EVENT_RBUTTONDOWN:
        cv.circle(img, center=(x, y), radius=5,
                  color=(0, 255, 0), thickness=1)


img = cv.imread('hebei.jpg')

cv.namedWindow(winname='drawing')
cv.setMouseCallback('drawing', draw_circle)

while True:
    cv.imshow('drawing', img)
    # 按 q 键退出
    if cv.waitKey(1) & 0xFF == ord('q'):
        break

cv.destroyAllWindows()

运行结果如下图所示,注意圆圈。

OpenCV 尾声

1 个小时又过去了,对 Python OpenCV 相关的知识点,你掌握了吗?

空闲之余,可以订阅橡皮擦的爬虫百例课程学习爬虫知识。

今天是持续写作的第 47 / 100 天。
如果你有想要交流的想法、技术,欢迎在评论区留言。


如果你想跟博主建立亲密关系,可以关注同名公众号 梦想橡皮擦,近距离接触一个逗趣的互联网高级网虫。
博主 ID:梦想橡皮擦,希望大家点赞评论收藏

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。