• OpenCV学习(三)——响应鼠标事件(获取点击点坐标和颜色,利用鼠标进行绘图)


    3. 响应鼠标事件

    使用OpenCV读取图像,可以在读取图像的窗口通过鼠标点击可以实现:获取鼠标点击像素点的坐标、获取鼠标点击像素点的颜色和在鼠标点击的像素点生成圆等等。

    # 对窗口的鼠标动作做出回应
    cv2.setMouseCallback(winname, callback, userdata)
    
    • 1
    • 2
    • winname:窗口的名字
    • callback:回调函数
    • userdata:给回调函数的参数
    # 鼠标回调函数,传入到callback参数上去
    def mouse_callback(event, x, y, flags, userdata)
    
    • 1
    • 2
    • enent:鼠标事件
    • x:横坐标
    • y:纵坐标
    • flags:事件组合
    • userdata:与cv2.setMouseCallback中的userdata对应,用于传参
    鼠标事件event对应
    EVENT_MOUSEMOVE鼠标移动
    EVENT_LBUTTONDOWN按下鼠标左键
    EVENT_RBUTTONDOWN按下鼠标右键
    EVENT_LBUTTONUP左键释放
    EVENT_RBUTTONUP右键释放
    EVENT_LBUTTONDBLCLK左键双击
    EVENT_RBUTTONDBLCLK右键双击

    3.1 获取鼠标点击的坐标

    import cv2
    import numpy as np
    
    
    # 回调函数:鼠标点击输出点击的坐标
    # (事件(鼠标移动、左键、右键),横坐标,纵坐标,组合键,setMouseCallback的userdata用于传参)
    def mouse_callback(event, x, y, flags, userdata):
        # 如果鼠标左键点击,则输出横坐标和纵坐标
        if event == cv2.EVENT_LBUTTONDOWN:
            print(f'({x}, {y})')
    
            # 在图像上绘制点
            cv2.circle(img, (x, y), 3, (0, 0, 255), -1)
    
            # 在图像上添加坐标文本
            # (图像,文本内容,坐标点,字体类型,字体大小,颜色,字体粗细)
            cv2.putText(img, f'({x},{y})', (x, y),
                cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
    
            # 获取指定像素点的颜色
            pixel_color = img[x, y]
            print("颜色值BGR:", pixel_color)
    
    
    img = cv2.imread('lena.jpg')
    
    # 创建窗口
    cv2.namedWindow('Point Coordinates')
    
    # 将回调函数绑定到窗口
    cv2.setMouseCallback('Point Coordinates', mouse_callback)
    
    # 显示图像
    while True:
        cv2.imshow('Point Coordinates', img)
        k = cv2.waitKey(1) & 0xFF
        # 按esc键退出
        if k == 27:
            break
    cv2.destroyAllWindows()
    
    • 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

    3.2 获取鼠标点击像素点的颜色

    # 获取指定像素点的颜色
    pixel_color = img[x, y]
    print("颜色值BGR:", pixel_color)
    
    • 1
    • 2
    • 3

    请添加图片描述

    3.3 在鼠标点击的位置生成圆

    import cv2
    
    img = cv2.imread('lena.jpg')
    
    
    # 回调函数:鼠标点击输出点击的坐标
    # (事件(鼠标移动、左键、右键),横坐标,纵坐标,组合键,setMouseCallback的userdata用于传参)
    def mouse_callback(event, x, y, flags, userdata):
        # 如果鼠标左键点击,则输出横坐标和纵坐标
        if event == cv2.EVENT_LBUTTONDOWN:
            print(f'({x}, {y})')
    
            # 在图像上绘制圆
            cv2.circle(img, (x, y), 100, (0, 0, 255), -1)
    
    
    # 创建新窗口
    cv2.namedWindow('mouse')
    
    # 将回调函数绑定在mouse窗口
    cv2.setMouseCallback('mouse', mouse_callback)
    
    while True:
        cv2.imshow('mouse', img)
        k = cv2.waitKey(1) & 0xFF
        # 按esc键退出
        if k == 27:
            break
    cv2.destroyAllWindows()
    
    • 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

    请添加图片描述

    3.4 通过拖动鼠标来绘制填充矩形

    在用QQ截图的时候,会有绘制矩形框的选项,使用OpenCV来进行模拟

    思路:

    1. 鼠标左键点击开始进行绘制
    2. 鼠标未拖动则生成圆点
    3. 鼠标拖动则绘制矩形
    4. 最后在图像上生成矩形框

    可用到的event事件:

    • EVENT_LBUTTONDOWN:按下鼠标左键
    • EVENT_MOUSEMOVE:鼠标移动
    • EVENT_LBUTTONUP:左键释放
    import cv2
    import numpy as np
    
    img = cv2.imread('lena.jpg')
    
    drawing = False # 如果按下鼠标,则为真
    start_x, start_y = -1, -1
    
    
    # 回调函数:鼠标点击输出点击的坐标
    # (事件(鼠标移动、左键、右键),横坐标,纵坐标,组合键,setMouseCallback的userdata用于传参)
    def mouse_callback(event, x, y, flags, userdata):
        global start_x, start_y, drawing
        # 鼠标左键单击
        if event == cv2.EVENT_LBUTTONDOWN:
            drawing = True
            start_x, start_y = x, y
    
        # 鼠标移动
        elif event == cv2.EVENT_MOUSEMOVE:
            if drawing == True:
                cv2.rectangle(img, (start_x, start_y), (x, y), (0, 0, 255), -1)
    
        # 鼠标左键松开
        elif event == cv2.EVENT_LBUTTONUP:
            drawing = False
           
        
    # 创建新窗口
    cv2.namedWindow('mouse')
    
    # 将回调函数绑定在mouse窗口
    cv2.setMouseCallback('mouse', mouse_callback)
    
    while True:
        cv2.imshow('mouse', img)
        k = cv2.waitKey(1) & 0xFF
        # 按esc键退出
        if k == 27:
            break
    cv2.destroyAllWindows()
    
    • 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

    请添加图片描述

    3.5 通过拖动鼠标绘制未填充矩形

    import cv2
    import numpy as np
    
    img = cv2.imread('lena.jpg')
    
    drawing = False # 如果按下鼠标,则为真
    start_x, start_y = -1, -1
    
    
    # 回调函数:鼠标点击输出点击的坐标
    # (事件(鼠标移动、左键、右键),横坐标,纵坐标,组合键,setMouseCallback的userdata用于传参)
    def mouse_callback(event, x, y, flags, userdata):
        global start_x, start_y, drawing
        # 鼠标左键单击
        if event == cv2.EVENT_LBUTTONDOWN:
            drawing = True
            start_x, start_y = x, y
    
        # 鼠标移动
        elif event == cv2.EVENT_MOUSEMOVE:
            pass
    
        # 鼠标左键松开
        elif event == cv2.EVENT_LBUTTONUP:
            drawing = False
            cv2.rectangle(img, (start_x, start_y), (x, y), (0, 0, 255), 3)
           
    
    # 创建新窗口
    cv2.namedWindow('mouse')
    
    # 将回调函数绑定在mouse窗口
    cv2.setMouseCallback('mouse', mouse_callback)
    
    while True:
        cv2.imshow('mouse', img)
        k = cv2.waitKey(1) & 0xFF
        # 按esc键退出
        if k == 27:
            break
    cv2.destroyAllWindows()
    
    • 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

    请添加图片描述

    3.6 使用鼠标选点绘制多边形

    import cv2
    import numpy as np
    
    img = cv2.imread('lena.jpg')
    
    xys = []
    
    
    # 回调函数:鼠标点击输出点击的坐标
    # (事件(鼠标移动、左键、右键),横坐标,纵坐标,组合键,setMouseCallback的userdata用于传参)
    def mouse_callback(event, x, y, flags, userdata):
        global xys, img
        # 鼠标左键单击
        if event == cv2.EVENT_LBUTTONDOWN:
            xys.append([x, y])
            cv2.circle(img, (x, y), 5, (0, 0, 255), -1)
    
        # 鼠标右键单击
        elif event == cv2.EVENT_RBUTTONDOWN:
            pts = np.array(xys, np.int32)
            # 画多条线:(图像,点集合,是否闭合,颜色,粗细)
            cv2.polylines(img, [pts], True, (0, 0, 0), 2)
            xys = []
    
    
    # 创建新窗口
    cv2.namedWindow('mouse')
    
    # 将回调函数绑定在mouse窗口
    cv2.setMouseCallback('mouse', mouse_callback)
    
    while True:
        cv2.imshow('mouse', img)
        k = cv2.waitKey(1) & 0xFF
        # 按esc键退出
        if k == 27:
            break
    cv2.destroyAllWindows()
    
    • 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

    按照鼠标选点的先后位置绘制多边形
    请添加图片描述
    如果相同选点,但顺序不同,绘制的图像也不同
    请添加图片描述

    3.7 按住鼠标左键进行绘图

    可以想象成绘图工具中的橡皮擦操作

    import cv2
    import numpy as np
    
    img = cv2.imread('lena.jpg')
    
    drawing = False # 按下鼠标左键响应
    
    
    # 回调函数:鼠标点击输出点击的坐标
    # (事件(鼠标移动、左键、右键),横坐标,纵坐标,组合键,setMouseCallback的userdata用于传参)
    def mouse_callback(event, x, y, flags, userdata):
        global drawing
        # 鼠标左键单击
        if event == cv2.EVENT_LBUTTONDOWN:
            drawing = True
    
        # 鼠标移动
        elif event == cv2.EVENT_MOUSEMOVE:
            if drawing == True:
                cv2.circle(img, (x, y), 5, (255, 255, 255), -1)
    
        # 鼠标左键释放
        elif event == cv2.EVENT_LBUTTONUP:
            drawing = False
    
    
    
    # 创建新窗口
    cv2.namedWindow('mouse')
    
    # 将回调函数绑定在mouse窗口
    cv2.setMouseCallback('mouse', mouse_callback)
    
    while True:
        cv2.imshow('mouse', img)
        k = cv2.waitKey(1) & 0xFF
        # 按esc键退出
        if k == 27:
            break
    cv2.destroyAllWindows()
    
    • 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

    请添加图片描述

  • 相关阅读:
    GOOGLE SRE 运维模式解读
    阿里云全面降价,释放了什么信号?
    第一百四十五回 如何给组件添加阴影
    Godot 脚本外置参数设置
    莱佛士学生服装设计作品登知名时尚杂志NÜYOU
    ubuntu18.04安装F4PGA教程
    Element-UI+Vue实现开发权限
    SQLMAP自动注入
    为什么选择WordPress作为企业CMS?
    Easyx基本使用(三)
  • 原文地址:https://blog.csdn.net/qq_38473254/article/details/134082649