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


    1. 学习目标

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

    2. Callback 基本流程

    输入图片说明

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

    3.1 cv.setMouseCallback() 函数使用
    cv.setMouseCallback(winname,onMouse,userdata)
    
    • 1
    3.2 参数说明
    参数说明
    winname表示监听鼠标事件的窗口。
    onMouse表示响应函数,即当鼠标事件触发时调用的函数。
    userdata表示默认值0。这个参数是用户传递给回调函数的数据,用来处理轨迹条事件。如果使用的第三个参数value是全局变量,完全可以不去管这个userdata参数。传给回调函数的参数!!!
    3.3 返回参数
    typedef void(*cv::MouseCallback)(int event, int x, int y, int flags, void *userdata)
    
    • 1
    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()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    4.2 代码解析
    1. 创建一个500*500的白色背景图片;
    2. 复制一个一样大小的白色背景图;
    3. 创建一个窗口,监听这个窗口的鼠标事件;
    4. 鼠标回调函数,绘制矩形;
    5. 当前次鼠标左键开始坐标;
    6. 开始后允许对移动中坐标进行记录;
    7. 产生随机颜色;
    8. 将上次绘制的结果给当前图片,为了将当前次移动过程中产生的绘制清除;
    9. 当前次移动结束的坐标,绘制移动中的当前矩形;
    10. 当前次坐标点绘制结束坐标点,结束鼠标移动监听;
    11. 绘制当前次鼠标左键按下到放开起点和终点组成的矩形;
    12. 保存当前次绘制的图片,坐标点还原;
    13. 每10毫秒显示一次图片;
    14. 监听每10毫秒是否按退出键;
    15. 销毁所有窗口。
    4.3 实例运行结果

    输入图片说明

    5. 注意

    1. 随机颜色的生成的时候,bgr的值必须是int类型;
    2. 每次绘制完成,必须对当前次绘制图片进行保存;
    3. 在移动过程中必须在绘制开始将上次绘制结果的图片覆盖给当前次,否则会出现移动一次一个矩形绘制;
    4. 可以使用鼠标监听事件方法实现图片截图,下一篇实战实现图片截图功能!
  • 相关阅读:
    基于JavaWeb的网上销售系统设计与实现
    区块链提供的数字化垃圾分类
    论文阅读笔记(十一)——BioInformatics Agent (BIA)
    RabbitMQ - 死信、TTL原理、延迟队列安装和配置
    springboot+java医疗设备报修系统jsp医院人事办公系统
    vue里面使用EventBus(事件总线)
    golang中for循环的使用详解
    反射,枚举,lambda表达式
    什么是KVM虚拟化
    MobPush数智化推送,精准定位万圣节狂欢年轻一族
  • 原文地址:https://blog.csdn.net/m0_38082783/article/details/127861918