-
目标
- 学习 opencv的鼠标事件和鼠标事件回调函数cv2.setMouseCallback()的使用。
- 根据获取到的鼠标的位置坐标绘制不同的图形。
-
示例代码
- 查看opencv支持的鼠标事件
python
# -*- coding:utf-8-*-
import numpy as np
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_MOUSEMOVE', 'EVENT_RBUTTONDBLCLK',
'EVENT_RBUTTONDOWN', 'EVENT_RBUTTONUP']
- 利用鼠标事件,以图片上双击的位置为中心,绘制一个圆
python
# -*- coding:utf-8-*-
import numpy as np
import cv2
def draw_circle(event, x, y, flags, param):
if event == cv2.EVENT_LBUTTONDBLCLK:
cv2.circle(img, (x, y), 100, (255, 0, 0), -1)
# 新建图像窗口并将窗口与回调函数绑定
img = np.zeros((512, 512, 3), np.uint8)
cv2.namedWindow('image')
cv2.setMouseCallback('image', draw_circle)
while (1):
# 显示图像并且按键盘上的**ESC**键即可关闭窗口
cv2.imshow('image', img)
if cv2.waitKey(20) & 0xFF == 27:
break
# 最后销毁窗口
cv2.destroyAllWindows()
显示结果
以双击鼠标的位置为圆心,100px为半径,画出的圆如下
- 利用鼠标事件,拖动鼠标时绘制矩形或圆
python
# -*- coding:utf-8-*-
import numpy as np
import cv2
# 默认绘图状态不可用,为False,当鼠标按下时值为True
drawing = False
# mode为True时画矩形,值为False时画圆
mode = True
# 定义x1, y1两个值
x1, y1 = -1, -1
# 创建回调函数
def draw_circle(event, x, y, flags, param):
global ix, iy, drawing, mode
# 按下鼠标左键时返回起始位置坐标
if event == cv2.EVENT_LBUTTONDOWN:
drawing = True
x1, y1 = x, y
# 当鼠标左键按下并移动时绘制图形
elif event == cv2.EVENT_MOUSEMOVE and flags == cv2.EVENT_FLAG_LBUTTON:
if drawing == True:
if mode == True:
# (x1, y1)为矩形起点,矩形颜色为(0, 255, 0),线条粗细为1px
cv2.rectangle(img, (x1, y1), (x, y), (0, 255, 0),1)
else:
# 起始点为圆心,起点到终点为半径的圆
r=int(np.sqrt((x-x1)**2+(y-y1)**2))
cv2.circle(img,(x,y),r,(0,0,255),-1)
# 当鼠标松开停止绘画
elif event==cv2.EVENT_LBUTTONUP:
drawing==False
# 新建图像窗口并将窗口与回调函数绑定
img=np.zeros((512,512,3),np.uint8)
cv2.namedWindow('image')
cv2.setMouseCallback('image',draw_circle)
while(1):
cv2.imshow('image',img)
k=cv2.waitKey(1)&0xFF
# 键盘输入**m**时,画圆
if k==ord('m'):
mode=not mode
elif k==27:
break
cv2.destroyAllWindows()
显示结果
注:在拖动鼠标移动的过程中,随着鼠标的移动会不断地画圆和矩形。
若利用鼠标拖动画圆,最后画出的可能是一条线,将上述画起点到终点为半径的圆的代码改为如下代码
cv2.circle(img,(x,y),3,(0,0,255),-1)
表示以拖动时的鼠标位置为圆心,半径为3px的圆,结果如下
可见在鼠标拖动过程中会不断以起始点为圆心,不断画圆。