OpenCV 鼠标画笔 setMouseCallback()

目标

• 学习使用 OpenCV 处理鼠标事件

• 你将要学习的函数是:cv2.setMouseCallback()


鼠标事件 :cv2.setMouseCallback()

cv2_EVENT_MOUSEMOVE 0 滑动 
cv2_EVENT_LBUTTONDOWN 1 左键点击 
cv2_EVENT_RBUTTONDOWN 2 右键点击 
cv2_EVENT_MBUTTONDOWN 3 中间点击 
cv2_EVENT_LBUTTONUP 4 左键释放 
cv2_EVENT_RBUTTONUP 5 右键释放 
cv2_EVENT_MBUTTONUP 6 中间释放 
cv2_EVENT_LBUTTONDBLCLK 7 左键双击 
cv2_EVENT_RBUTTONDBLCLK 8 右键双击 
cv2_EVENT_MBUTTONDBLCLK 9 中间释放

cv2_EVENT_FLAG_LBUTTON 1 左键拖拽  
cv2_EVENT_FLAG_RBUTTON 2 右键拖拽  
cv2_EVENT_FLAG_MBUTTON 4 中间拖拽  
cv2_EVENT_FLAG_CTRLKEY 8 (8~15)按Ctrl不放事件  
cv2_EVENT_FLAG_SHIFTKEY 16  (16~31)按Shift不放事件  
cv2_EVENT_FLAG_ALTKEY 32  (32~39)按Alt不放事件(后面8-39还有待研究)

实例1 :双击左键画圆圈 

用到的EVENT为:cv2_EVENT_LBUTTONDBLCLK

所有的鼠标事件回调函数都有一个统一的格式,他们所不同的地方仅仅是
被调用后的功能。我们的鼠标事件回调函数只用做一件事:在双击过的地方绘
制一个圆圈。下面是代码,不懂的地方可以看看注释。


 
 
  1. import cv2
  2. import numpy as np
  3. import time
  4. img=cv2.imread( 'PIC/000.jpg') #读取图片作为背景
  5. #定义画圆事件,如果事件双击左键发生
  6. #则以此时双击的点为原点画一个半径为100px BGR为(255,255,0)粗细为3px的圆圈
  7. def draw_circle(event,x,y,flags,param):
  8. if event==cv2.EVENT_LBUTTONDBLCLK:
  9. cv2.circle(img,(x,y), 100,( 255, 255, 0), 3)
  10. # 创建图像与窗口并将窗口与回调函数绑定
  11. cv2.namedWindow( 'image')
  12. cv2.setMouseCallback( 'image',draw_circle)
  13. while( 1):
  14. cv2.imshow( 'image',img)
  15. if cv2.waitKey( 100) == ord( 'q'): #等待100毫秒 刷新一次显示图像
  16. break
  17. cv2.destroyAllWindows()


运行结果:



实例2

现在我们来创建一个更好的程序。这次我们的程序要完成的任务是根据我
们选择的模式在拖动鼠标时绘制矩形或者是圆圈(就像画图程序中一样)。所以
我们的回调函数包含两部分,一部分画矩形,一部分画圆圈。这是一个典型的
例子他可以帮助我们更好理解与构建人机交互式程序,比如物体跟踪,图像分
割等。
下面我们要把这个回调函数与 OpenCV 窗口绑定在一起。在主循环中我
们需要将键盘上的“m”键与模式转换绑定在一起。


 
 
  1. import cv2
  2. import numpy as np
  3. import time
  4. img=cv2.imread( 'PIC/000.jpg')
  5. # 当鼠标按下时变为True
  6. drawing= False
  7. # 如果mode 为true 绘制矩形。按下'm' 变成绘制曲线。
  8. mode= True
  9. ix,iy= -1, -1
  10. # 创建回调函数
  11. def draw_circle(event,x,y,flags,param):
  12. global ix,iy,drawing,mode
  13. # 当按下左键是返回起始位置坐标
  14. if event==cv2.EVENT_LBUTTONDOWN:
  15. drawing= True
  16. ix,iy=x,y
  17. # 当鼠标左键按下并移动是绘制图形。event 可以查看移动,flag 查看是否按下
  18. elif event==cv2.EVENT_MOUSEMOVE and flags==cv2.EVENT_FLAG_LBUTTON:
  19. if drawing== True:
  20. if mode== True:
  21. cv2.rectangle(img,(ix,iy),(x,y),( 0, 255, 0), -1)
  22. else:
  23. # 绘制圆圈,小圆点连在一起就成了线
  24. cv2.circle(img,(x,y), 3,( 0, 0, 255), -1)
  25. # 当鼠标松开停止绘画。
  26. elif event==cv2.EVENT_LBUTTONUP:
  27. drawing== False
  28. cv2.namedWindow( 'image')
  29. cv2.setMouseCallback( 'image',draw_circle)
  30. while( 1):
  31. cv2.imshow( 'image',img)
  32. k=cv2.waitKey( 1)& 0xFF
  33. if k==ord( 'm'):
  34. mode= not mode
  35. elif k==ord( 'q'):
  36. break


运行结果:




全部代码:


 
 
  1. '''函数:cv2.setMouseCallback()'''
  2. import cv2
  3. import numpy as np
  4. import time
  5. img=cv2.imread( 'PIC/000.jpg')
  6. def draw_circle(event,x,y,flags,param):
  7. if event==cv2.EVENT_LBUTTONDBLCLK:
  8. cv2.circle(img,(x,y), 100,( 255, 255, 0), 3)
  9. cv2.namedWindow( 'image')
  10. cv2.setMouseCallback( 'image',draw_circle)
  11. while( 1):
  12. cv2.imshow( 'image',img)
  13. if cv2.waitKey( 100) == ord( 'q'): #等待100毫秒 刷新一次显示图像
  14. break
  15. cv2.destroyAllWindows()
  16. # 当鼠标按下时变为True
  17. drawing= False
  18. # 如果mode 为true 绘制矩形。按下'm' 变成绘制曲线。
  19. mode= True
  20. ix,iy= -1, -1
  21. 6
  22. # 创建回调函数
  23. def draw_circle(event,x,y,flags,param):
  24. global ix,iy,drawing,mode
  25. # 当按下左键是返回起始位置坐标
  26. if event==cv2.EVENT_LBUTTONDOWN:
  27. drawing= True
  28. ix,iy=x,y
  29. # 当鼠标左键按下并移动是绘制图形。event 可以查看移动,flag 查看是否按下
  30. elif event==cv2.EVENT_MOUSEMOVE and flags==cv2.EVENT_FLAG_LBUTTON:
  31. if drawing== True:
  32. if mode== True:
  33. cv2.rectangle(img,(ix,iy),(x,y),( 0, 255, 0), -1)
  34. else:
  35. # 绘制圆圈,小圆点连在一起就成了线
  36. cv2.circle(img,(x,y), 3,( 0, 0, 255), -1)
  37. # 当鼠标松开停止绘画。
  38. elif event==cv2.EVENT_LBUTTONUP:
  39. drawing== False
  40. img=cv2.imread( 'PIC/000.jpg')
  41. cv2.namedWindow( 'image')
  42. cv2.setMouseCallback( 'image',draw_circle)
  43. while( 1):
  44. cv2.imshow( 'image',img)
  45. k=cv2.waitKey( 1)& 0xFF
  46. if k==ord( 'm'):
  47. mode= not mode
  48. elif k==ord( 'q'):
  49. break











  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值