OpenCV-Python学习(15)—— OpenCV 鼠标操作和响应(cv.setMouseCallback)

1. 学习目标

  1. 学习如何在OpenCV中处理鼠标事件;
  2. 学习鼠标事件与回调;
  3. 学习鼠标事件回调函数的基本流程。

2. Callback 基本流程

OpenCV-Python学习(15)—— OpenCV 鼠标操作和响应(cv.setMouseCallback)_第1张图片

3. 鼠标事件 cv.setMouseCallback 函数说明

3.1 cv.setMouseCallback() 函数使用

cv.setMouseCallback(winname,onMouse,userdata)

3.2 参数说明

参数 说明
winname 表示监听鼠标事件的窗口。
onMouse 表示响应函数,即当鼠标事件触发时调用的函数。
userdata 表示默认值0。这个参数是用户传递给回调函数的数据,用来处理轨迹条事件。如果使用的第三个参数value是全局变量,完全可以不去管这个userdata参数。传给回调函数的参数!!!

3.3 返回参数

typedef void(*cv::MouseCallback)(int event, int x, int y, int flags, void *userdata)

3.4 返回参数说明

参数 说明
event 表示当前鼠标执行的事件。
x 表示当前鼠标坐标值x。
y 表示当前鼠标坐标值y。
flags 表示鼠标状态。
userdata 表示用户定义的传递到setMouseCallback函数调用的参数。

3.5 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) 表示中键双击事件。

3.6 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 不放。

4. 【通过鼠标绘制随机颜色矩形】实例

4.1 实例代码

import cv2 as cv
import numpy as np

flagMove = False
oldImg = None
startX,startY = -1,-1
endX,endY = -1,-1
b,g,r = 0,0,0

def create_demo():
  global oldImg
  # 创建一个500*500的白色背景图片
  img = np.ones((500,500,3), dtype=np.uint8)*255
  # 复制一个一样大小的白色背景图
  oldImg = np.ones_like(img) * 255
  # 创建一个窗口
  cv.namedWindow('mouse_img')
  # 监听这个窗口的鼠标事件
  cv.setMouseCallback('mouse_img', draw_rectangle, img)
  # 每10毫秒显示一次图片
  while True:
    cv.imshow("mouse_img", img)
    # 监听每10毫秒是否按退出键
    if cv.waitKey(10) & 0xFF == 27:
      break
  # 销毁所有窗口
  cv.destroyAllWindows()

# 鼠标回调函数,绘制矩形
def draw_rectangle(event,x,y,flags,img):
  global flagMove,startX,startY,endX,endY,oldImg,b,g,r
  # 点击起点
  if event == cv.EVENT_LBUTTONDOWN:
    # 当前次鼠标左键开始坐标
    startX,startY = x,y
    # 开始后允许对移动中坐标进行记录
    flagMove = True
    # 产生随机颜色
    b,g,r = np.random.randint(0,256,size=3)
    b,g,r = int(b),int(g),int(r)
  # 移动终点
  if event == cv.EVENT_MOUSEMOVE and flagMove:
    # 将上次绘制的结果给当前图片,为了将当前次移动过程中产生的绘制清除
    img[:] = oldImg[:]
    # 当前次移动结束的坐标
    endX,endY = x,y
    # 绘制移动中的当前矩形
    cv.rectangle(img, (startX,startY), (endX,endY), (b,g,r), lineType=cv.LINE_AA)
  # 最后终点
  if event == cv.EVENT_LBUTTONUP:
    # 当前次坐标点绘制结束坐标点,结束鼠标移动监听
    endX,endY = x,y
    flagMove = False
    # 绘制当前次鼠标左键按下到放开起点和终点组成的矩形
    cv.rectangle(img, (startX,startY), (endX,endY), (b,g,r), lineType=cv.LINE_AA)
    # 保存当前次绘制的图片
    oldImg[:] = img[:]
    # 坐标点还原
    startX,startY = -1,-1
    endX,endY = -1,-1

if __name__ == "__main__":
  create_demo()

4.2 代码解析

  1. 创建一个500*500的白色背景图片;
  2. 复制一个一样大小的白色背景图;
  3. 创建一个窗口,监听这个窗口的鼠标事件;
  4. 鼠标回调函数,绘制矩形;
  5. 当前次鼠标左键开始坐标;
  6. 开始后允许对移动中坐标进行记录;
  7. 产生随机颜色;
  8. 将上次绘制的结果给当前图片,为了将当前次移动过程中产生的绘制清除;
  9. 当前次移动结束的坐标,绘制移动中的当前矩形;
  10. 当前次坐标点绘制结束坐标点,结束鼠标移动监听;
  11. 绘制当前次鼠标左键按下到放开起点和终点组成的矩形;
  12. 保存当前次绘制的图片,坐标点还原;
  13. 每10毫秒显示一次图片;
  14. 监听每10毫秒是否按退出键;
  15. 销毁所有窗口。

4.3 实例运行结果

OpenCV-Python学习(15)—— OpenCV 鼠标操作和响应(cv.setMouseCallback)_第2张图片

5. 注意

  1. 随机颜色的生成的时候,bgr的值必须是int类型;
  2. 每次绘制完成,必须对当前次绘制图片进行保存;
  3. 在移动过程中必须在绘制开始将上次绘制结果的图片覆盖给当前次,否则会出现移动一次一个矩形绘制;
  4. 可以使用鼠标监听事件方法实现图片截图,下一篇实战实现图片截图功能!

你可能感兴趣的:(OpenCV-Python学习,Python,opencv,python,学习)