鼠标事件
鼠标事件就是对鼠标的操作。
用户通过鼠标对图像视窗最常见的操作,例如:
-
左键单击按下
-
左键单击抬起
-
左键按下拖动
- 鼠标指针位置移动
可通过:
import cv2
events=[i for i in dir(cv2) if 'EVENT'in i]
print events
来查看OpenCV所有的鼠标事件。
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不放事件
鼠标事件一次只会响应一个,如鼠标点击、双击、拖曳,使得有时候我们还需要用到FLAG对应的事件。
操作响应事件
setMouseCallback()函数:cv2.setMouseCallback('image',OnMouseAction)
OnMouseAction()响应函数:def OnMouseAction(event,x,y,flags,param):
int x,int y,代表鼠标位于窗口的(x,y)坐标位置,即Point(x,y);
int flags,代表鼠标的拖拽事件,以及键盘鼠标联合事件,共有32种事件:
param 函数指针,标识了所响应的事件函数,相当于自定义了一个OnMouseAction()函数的ID。
代码示例:
Opencv中setMouseCallback()创建了一个鼠标回调函数,每次在图像上点击鼠标左键再释放的过程,都会分3次调用鼠标响应函数,并且响应顺序是:
1.左键单击按下;
2.左键单击抬起;
3.鼠标指针位置移动(即使原地单击,鼠标位置并没有移动);
import cv2
import numpy as np
#创建回调函数
def OnMouseAction(event,x,y,flags,param):
if event == cv2.EVENT_LBUTTONDOWN:
print("左键点击")
elif event==cv2.EVENT_RBUTTONDOWN :
print("右键点击")
elif flags==cv2.EVENT_FLAG_LBUTTON:
print("左鍵拖曳")
elif event==cv2.EVENT_MBUTTONDOWN :
print("中键点击")
'''
创建回调函数的函数setMouseCallback();
下面把回调函数与OpenCV窗口绑定在一起
'''
img = np.zeros((500,500,3),np.uint8)
cv2.namedWindow('image')
cv2.setMouseCallback('image',OnMouseAction)
cv2.imshow('image',img)
cv2.waitKey(30000)
cv2.destroyAllWindows()
鼠标点击切割矩形区域
图形函数:
cv2.rectangle(img, pt1, pt2, color[, thickness[, lineType[, shift]]]) → img
img – Image.
pt1 – Vertex of the rectangle.
pt2 – Vertex of the rectangle opposite to pt1.
color – Rectangle color or brightness (grayscale image).
thickness – Thickness of lines that make up the rectangle.
cv2.circle(img, center, radius, color[, thickness[, lineType[, shift]]]) →img
img – Image where the circle is drawn.
center – Center of the circle.
radius – Radius of the circle.
color – Circle color.
thickness – Thickness of the circle outline, if positive. Negative thickness means that a filled circle is to be drawn.
import cv2
def OnMouseAction(event, x, y, flags, param):
global img, position1, position2
image = img.copy()
if event == cv2.EVENT_LBUTTONDOWN: #按下左键
position1 = (x,y) #获取鼠标的坐标(起始位置)
elif event == cv2.EVENT_MOUSEMOVE and flags == cv2.EVENT_FLAG_LBUTTON: #按住左键拖曳不放开
cv2.rectangle(image, position1, (x,y), (0,255,0), 3) #画出矩形选定框
cv2.imshow('image', image)
elif event == cv2.EVENT_LBUTTONUP: #放开左键
position2 = (x,y) #获取鼠标的最终位置
cv2.rectangle(image, position1, position2, (0,0,255), 3) #画出最终的矩形
cv2.imshow('image', image)
min_x = min(position1[0],position2[0]) #获得最小的坐标,因为可以由下往上拖动选定框
min_y = min(position1[1],position2[1])
width = abs(position1[0] - position2[0]) #切割坐标
height = abs(position1[1] - position2[1])
cut_img = img[min_y:min_y+height, min_x:min_x+width]
cv2.imshow('Cut', cut_img)
def main():
global img
img = cv2.imread(r'C:\Users\x\Desktop\87.jpg',cv2.IMREAD_ANYCOLOR)
cv2.namedWindow('image')
cv2.setMouseCallback('image', OnMouseAction)
cv2.imshow('image', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
if __name__ == '__main__':
main()