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

响应鼠标事件

    • [3. 响应鼠标事件](#3. 响应鼠标事件)
      • [3.1 获取鼠标点击的坐标](#3.1 获取鼠标点击的坐标)
      • [3.2 获取鼠标点击像素点的颜色](#3.2 获取鼠标点击像素点的颜色)
      • [3.3 在鼠标点击的位置生成圆](#3.3 在鼠标点击的位置生成圆)
      • [3.4 通过拖动鼠标来绘制填充矩形](#3.4 通过拖动鼠标来绘制填充矩形)
      • [3.5 通过拖动鼠标绘制未填充矩形](#3.5 通过拖动鼠标绘制未填充矩形)
      • [3.6 使用鼠标选点绘制多边形](#3.6 使用鼠标选点绘制多边形)
      • [3.7 按住鼠标左键进行绘图](#3.7 按住鼠标左键进行绘图)

3. 响应鼠标事件

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

python 复制代码
# 对窗口的鼠标动作做出回应
cv2.setMouseCallback(winname, callback, userdata)
  • winname:窗口的名字
  • callback:回调函数
  • userdata:给回调函数的参数
python 复制代码
# 鼠标回调函数,传入到callback参数上去
def mouse_callback(event, x, y, flags, userdata)
  • 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 获取鼠标点击的坐标

python 复制代码
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()

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

python 复制代码
# 获取指定像素点的颜色
pixel_color = img[x, y]
print("颜色值BGR:", pixel_color)

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

python 复制代码
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()

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

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

思路:

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

可用到的event事件:

  • EVENT_LBUTTONDOWN:按下鼠标左键
  • EVENT_MOUSEMOVE:鼠标移动
  • EVENT_LBUTTONUP:左键释放
python 复制代码
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()

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

python 复制代码
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()

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

python 复制代码
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()

按照鼠标选点的先后位置绘制多边形

如果相同选点,但顺序不同,绘制的图像也不同

3.7 按住鼠标左键进行绘图

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

python 复制代码
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()
相关推荐
学习路上_write2 分钟前
FPGA/Verilog,Quartus环境下if-else语句和case语句RT视图对比/学习记录
单片机·嵌入式硬件·qt·学习·fpga开发·github·硬件工程
非概念8 分钟前
stm32学习笔记----51单片机和stm32单片机的区别
笔记·stm32·单片机·学习·51单片机
无敌最俊朗@2 小时前
stm32学习之路——八种GPIO口工作模式
c语言·stm32·单片机·学习
EterNity_TiMe_2 小时前
【论文复现】STM32设计的物联网智能鱼缸
stm32·单片机·嵌入式硬件·物联网·学习·性能优化
Jack黄从零学c++2 小时前
opencv(c++)图像的灰度转换
c++·人工智能·opencv
L_cl2 小时前
Python学习从0到1 day28 Python 高阶技巧 ⑤ 多线程
学习
前端SkyRain2 小时前
后端Node学习项目-用户管理-增删改查
后端·学习·node.js
提笔惊蚂蚁3 小时前
结构化(经典)软件开发方法: 需求分析阶段+设计阶段
后端·学习·需求分析
DDDiccc3 小时前
JAVA学习日记(十五) 数据结构
数据结构·学习
Bruce小鬼3 小时前
QT鼠标事件
开发语言·qt·计算机外设