流程:
- 首先,創建一個鼠標事件回調函數,當鼠標事件發生時就會被執行。
- 鼠標事件可以是鼠標上的任何動作,比如左鍵按下,左鍵松開,左鍵雙擊等。
- 我們可以通過鼠標事件獲得與鼠標對應的圖片上的坐標。
- 根據這些信息我們可以做任何我們想做的事。
以下代碼查看所有被支持的鼠標事件:

1 # -*- coding: utf-8 -*- 2 3 import cv2 4 events=[i for i in dir(cv2) if 'EVENT'in i] 5 print events
- 所有的鼠標事件回調函數都有一個統一的格式,他們所不同的地方僅僅是被調用后的功能。
例子1:
在雙擊過的地方繪制一個圓圈。下面是代碼:

1 # -*- coding: utf-8 -*- 2 3 import cv2 4 import numpy as np 5 6 #mouse callback function 7 def draw_circle(event,x,y,flags,param): 8 if event==cv2.EVENT_LBUTTONDBLCLK: 9 cv2.circle(img,(x,y),100,(255,0,0),-1) 10 11 # 創建圖像與窗口並將窗口與回調函數綁定 12 img=np.zeros((512,512,3),np.uint8) 13 cv2.namedWindow('image') 14 cv2.setMouseCallback('image',draw_circle) 15 16 while(1): 17 cv2.imshow('image',img) 18 if cv2.waitKey(20)&0xFF==27: 19 break 20 cv2.destroyAllWindows()
效果:
例子2:
- 根據我們選擇的模式在拖動鼠標時繪制矩形或者是圓圈(就像畫圖程序中一樣)。
- 所以我們的回調函數包含兩部分,一部分畫矩形,一部分畫圓圈。
- 這是一個典型的例子他可以幫助我們更好理解與構建人機交互式程序,比如物體跟蹤,圖像分割

1 # -*- coding: utf-8 -*- 2 3 import cv2 4 import numpy as np 5 6 # 當鼠標按下時變為True 7 drawing=False 8 # 如果mode為true繪制矩形。按下'm' 變成繪制曲線。 9 mode=True 10 ix,iy=-1,-1 11 12 # 創建回調函數 13 def draw_circle(event,x,y,flags,param): 14 global ix,iy,drawing,mode 15 16 # 當按下左鍵是返回起始位置坐標 17 if event==cv2.EVENT_LBUTTONDOWN: 18 drawing=True 19 ix,iy=x,y 20 21 # 當鼠標左鍵按下並移動是繪制圖形。event可以查看移動,flag查看是否按下 22 elif event==cv2.EVENT_MOUSEMOVE and flags==cv2.EVENT_FLAG_LBUTTON: 23 if drawing==True: 24 if mode==True: 25 cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),-1) 26 else: 27 # 繪制圓圈,小圓點連在一起就成了線,3代表了筆畫的粗細 28 cv2.circle(img,(x,y),3,(0,0,255),-1) 29 # 下面注釋掉的代碼是起始點為圓心,起點到終點為半徑的 30 # r=int(np.sqrt((x-ix)**2+(y-iy)**2)) 31 # cv2.circle(img,(x,y),r,(0,0,255),-1) 32 # 當鼠標松開停止繪畫。 33 elif event==cv2.EVENT_LBUTTONUP: 34 drawing==False 35 # if mode==True: 36 # cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),-1) 37 # else: 38 # cv2.circle(img,(x,y),5,(0,0,255),-1) 39 40 # 回調函數與OpenCV 窗口綁定在一起, 41 # 在主循環中我們需要將鍵盤上的“m”鍵與模式轉換綁定在一起。 42 img=np.zeros((512,512,3),np.uint8) 43 cv2.namedWindow('image') 44 # 綁定事件 45 cv2.setMouseCallback('image',draw_circle) 46 while(1): 47 cv2.imshow('image',img) 48 k=cv2.waitKey(1)&0xFF 49 if k==ord('m'): 50 mode=not mode 51 elif k==27: 52 break
按下左鍵拖動開始繪畫,按m切換
效果: