100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > Python Opencv 实现鼠标事件(包含一个练习)——事件触发讲解·以及鼠标回调函数的实现

Python Opencv 实现鼠标事件(包含一个练习)——事件触发讲解·以及鼠标回调函数的实现

时间:2018-10-19 17:32:08

相关推荐

Python Opencv 实现鼠标事件(包含一个练习)——事件触发讲解·以及鼠标回调函数的实现

文章目录

鼠标事件概述鼠标事件发生的结构鼠标回调函数的标准格式opencv下包含的所有事件——包含flag和event(可以看一下,熟悉常见事件范围)鼠标事件的实现函数一个完整的鼠标事件由一个自定义的鼠标回调函数+实现鼠标回调函数的设置实现一个鼠标事件第一步·创建自定义鼠标回调函数(记得调用库哦~)第二步·我们在__main__部分里,实现回调函数完整代码效果展示小案例——训练鼠标回调函数——以及多边形绘制要求思路代码实现效果展示

QQ:3020889729 小蔡

鼠标事件概述

opencv可以实现gui拥有的功能——所以,opencv中也包含了鼠标事件——通过点击等等事件,执行相应的回调函数,实现指定的功能,最终实现交互!!!

鼠标事件发生的结构

鼠标回调函数的标准格式

鼠标回调函数的构造:函数名任意——但是参数应依次包含:event(事件),x, y,flags(标志),param(其它参数)

补充一下:事件和标志都可以作为事件触发的条件!!!

import cv2 as cvimport numpy as npdef mouse_circle(event, x, y, flags, param): if event == cv.EVENT_LBUTTONDOWN: # 该事件为鼠标左键按下pass # 执行任务

opencv下包含的所有事件——包含flag和event(可以看一下,熟悉常见事件范围)

事件列表:

if event == cv.EVENT_LBUTTONDBLCLK: # 触发事件为左键双击if event == cv.EVENT_LBUTTONDOWN: # 触发事件为左键按下时if event == cv.EVENT_LBUTTONUP: # 触发事件为左键弹起时if event == cv.EVENT_RBUTTONDBLCLK: # 触发事件为右键双击时if event == cv.EVENT_RBUTTONDOWN: # 触发事件为右键按下时if event == cv.EVENT_RBUTTONUP: # 触发事件为右键弹起时if event == cv.EVENT_MBUTTONDBLCLK: # 触发事件为中键滚轮双击时if event == cv.EVENT_MBUTTONDOWN: # 触发事件为中键滚轮按下时if event == cv.EVENT_MBUTTONUP: # 触发事件为中键滚轮弹起时if event == cv.EVENT_MOUSEWHEEL: # 触发事件为中键滚轮滚动时if event == cv.EVENT_MOUSEMOVE: # 触发事件为鼠标移动时

标志列表:

if flags == cv.EVENT_FLAG_ALTKEY: # 触发标志为ALT键按下时if flags == cv.EVENT_FLAG_CTRLKEY: # 触发标志为CTRL键按下时if flags == cv.EVENT_FLAG_LBUTTON: # 触发标志为鼠标左键按下时if flags == cv.EVENT_FLAG_MBUTTON: # 触发标志为鼠标中键滚轮按下时if flags == cv.EVENT_FLAG_RBUTTON: # 触发标志为鼠标右键按下时if flags == cv.EVENT_FLAG_SHIFTKEY: # 触发标志为SHIFT键按下时

鼠标事件的实现函数

由方法cv.setMouseCallback(‘imag’, mouse_circle) 实现鼠标事件!!!

import cv2 as cvimport numpy as npcv.setMouseCallback('imag', mouse_circle) # 第一个参数为窗体名称——指的是哪个窗体下执行# 第二个参数为鼠标回调函数的名称——传入函数名称,指的是传入整个函数声明,而不是直接执行函数

一个完整的鼠标事件由一个自定义的鼠标回调函数+实现鼠标回调函数的设置

实现一个鼠标事件

这里采用鼠标左键按下为事件触发的条件——所以我们就要设置一个自定义回调函数,里边包含当事件为左键按下时,我们画一个88*88的矩形~

第一步·创建自定义鼠标回调函数(记得调用库哦~)

我们这里用到event——事件参数,当然,你可以修改它的名字,但是呢,只要记住这个位置在后边回调函数实现时,传入的是事件就ok啦~

def mouse_circle(event, x, y, flags, param):if event == cv.EVENT_LBUTTONDOWN: # 触发事件为左键按下时cv.rectangle(img, (x, y), (x+88, y+88), (174, 238, 238), -1) # 画一个88*88的GhostWhite(颜色)矩形

第二步·我们在__main__部分里,实现回调函数

还是老规矩,既然是用opencv的gui——那么我们就需要先创建一张照片(图像),接着创建一个窗体——然后把后边涉及的相关窗体放在同一个窗体下!!!(回调函数的实现也是挂在同一个窗体下的哦,要一一对应)

if __name__ == "__main__":img = np.zeros((512, 512, 3), np.uint8)cv.namedWindow('imag', cv.WINDOW_NORMAL) # 创建一个可改变大小的窗体cv.resizeWindow('imag', 510, 510) # 大小设置cv.setMouseCallback('imag', mouse_circle) # 实现鼠标回调函数到imag的窗体while True:cv.imshow('imag', img)k = cv.waitKey(10) & 0xFF # 读取按键if k == ord('q') or k == ord('Q'): # 结束绘制breakcv.destroyAllWindows()

完整代码

import cv2 as cvimport numpy as np# 该回调函数用来花矩形def mouse_circle(event, x, y, flags, param):if event == cv.EVENT_LBUTTONDOWN: # 触发事件为左键按下时cv.rectangle(img, (x, y), (x+88, y+88), (174, 238, 238), -1) # 画一个88*88的GhostWhite(颜色)矩形if __name__ == "__main__":img = np.zeros((512, 512, 3), np.uint8)cv.namedWindow('imag', cv.WINDOW_NORMAL)cv.resizeWindow('imag', 510, 510)cv.setMouseCallback('imag', mouse_circle) while True:cv.imshow('imag', img)k = cv.waitKey(10) & 0xFFif k == ord('q') or k == ord('Q'):breakcv.destroyAllWindows()

效果展示

点击一次——按下时就产生图形了~

多次按下就有多个图形

我们可以用鼠标点击,用矩形拼凑一个小图形出来~说明,我们实现的事件,是画到了图片上并且保留到图片上了的

小案例——训练鼠标回调函数——以及多边形绘制

要求

在一个回调函数中,实现每一次鼠标点击,产生一个三角形并且,要求,当m按键按下后,三角形倒置!!!并且规定ESC键按下时,退出opencv的界面(也就是破出显示的条件)

思路

按键部分:既然要求按键按下要绘制不同的图形,那么,我们就设置一个全局变量mode_up_down=True,当为True时,正常绘图,否则倒置绘图~这就要用到我们cv.waitKey(10)获取按键,然后判断是否是m键,是就翻转mode_up_down的值——mode_up_down = ~mode_up_down至于退出界面,我们也通过这个办法获取ESC按键!!!绘制部分:至于绘制三角形只需要使用polylines来实现多边形绘制(至于倒置三角形:就是将底边顶点的y值与上顶点的y值互换!)可前往另一篇博客查看polylines的多边形绘制回调函数部分:——代码中去讲解可能会好些~

代码实现

import cv2 as cvimport numpy as npdrawing = False # True时,才绘图mode_up_down = True # 为true时,实现等腰三角形正向图;Flase时,实现倒图ix, iy = -1, -1 # 为画图(上顶点)坐标_采用全局变量获取实时坐标# 我们引入全局变量,实现绘制的控制def mouse_function(event, x, y, flags, param):global drawing, mode_up_down, mode_color, ix, iyif event == cv.EVENT_LBUTTONDOWN: # 鼠标左键按下,允许绘图,以及获取绘图坐标drawing = True # 允许绘图ix, iy = x, y # 获取坐标elif event == cv.EVENT_LBUTTONUP: # 弹起时就绘制图形drawing = False # 关闭绘制功能if mode_up_down:pst = np.array([[ix, iy], [ix - 30, iy + 30], [ix + 30, iy + 30]], np.int32) # 为多边形绘制的顶点配置pst = pst.reshape((3, 1, 2))cv.polylines(img, [pst], True, (0, 0, 255), 2, cv.LINE_AA)else: # 绘制倒置图形pst = np.array([[ix - 30, iy], [ix + 30, iy], [ix, iy + 30]], np.int32) # 倒置顶点的配置pst = pst.reshape((3, 1, 2))cv.polylines(img, [pst], True, (0, 0, 255), 2, cv.LINE_AA)elif event == cv.EVENT_MOUSEMOVE: # 按键未弹起,移动位置之后也发生绘图if drawing == True:if mode_up_down:pst = np.array([[ix, iy], [ix - 30, iy + 30], [ix + 30, iy + 30]], np.int32)pst = pst.reshape((3, 1, 2))cv.polylines(img, [pst], True, (0, 0, 255), 2, cv.LINE_AA)else:pst = np.array([[ix - 30, iy], [ix + 30, iy], [ix, iy + 30]], np.int32)pst = pst.reshape((3, 1, 2))cv.polylines(img, [pst], True, (0, 0, 255), 2, cv.LINE_AA)if __name__ == "__main__":img = np.zeros((512, 512, 3), np.uint8)cv.namedWindow('imag', cv.WINDOW_NORMAL)cv.resizeWindow('imag', 510, 510)cv.setMouseCallback('imag', mouse_function) # 实现鼠标回调函数while True:cv.imshow('imag', img)k = cv.waitKey(10) & 0xFFif k == 27:breakelif k == ord('m') or k == ord('M'):mode_up_down = not mode_up_downcv.destroyAllWindows()

效果展示

默认绘制正图形,按下m键就翻转——正反,反正的变化规则~

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。