OpenCV的“画笔”功能

类似于画图软件的自由笔刷功能,当按住鼠标左键,在屏幕上画出连续的线条。

定义函数:

python 复制代码
import cv2
import numpy as np

# 初始化参数
drawing = False  # 鼠标左键按下时为True
ix, iy = -1, -1  # 鼠标初始位置


# 鼠标回调函数
def mouse_paint(event, x, y, flags, param):
    global ix, iy, drawing

    # 左键按下事件
    if event == cv2.EVENT_LBUTTONDOWN:
        drawing = True
        ix, iy = x, y

    # 鼠标移动事件
    elif event == cv2.EVENT_MOUSEMOVE:
        if drawing:
            cv2.line(img, (ix, iy), (x, y), (0, 255, 0), 2)
            ix, iy = x, y
            cv2.imshow('image', img)
    # 左键松开事件
    elif event == cv2.EVENT_LBUTTONUP:
        drawing = False
        # cv2.line(img, (ix, iy), (x, y), (0, 255, 0), 2)

        # cv2.imshow('image', img)
        cv2.waitKey(0)


# 创建空白图像或读取现有图像
img = np.zeros((500, 500, 3), np.uint8)    # 创建空白图像
# img = cv2.imread('d:\\mask1\\3.png', cv2.IMREAD_COLOR)   # 读取现有图像

# 创建一个窗口并将回调函数与窗口绑定
cv2.namedWindow('image')
cv2.setMouseCallback('image', mouse_paint)

# 保存绘制轨迹后的图像
cv2.imshow('image', img)
cv2.waitKey(0)
cv2.imwrite('output_image.jpg', img)
cv2.destroyAllWindows()

这里用到了OpenCV的鼠标回调函数cv2.setMouseCallback():

cv2.setMouseCallback() 是 OpenCV 库中用于设置鼠标事件回调函数的函数。该函数用于与图像窗口交互,通过在图像窗口中进行鼠标操作来获取像素点的坐标或执行一些特定操作。

函数原型为:

复制代码
cv2.setMouseCallback(windowName, onMouse, param=None)
  • windowName 是要操作的图像窗口的名称。
  • onMouse 是回调函数,用于处理鼠标事件。该函数通常包含四个参数: event(事件类型,如 cv2.EVENT_MOUSEMOVEcv2.EVENT_LBUTTONDOWN 等)、x(鼠标点击的 x 坐标)、y(鼠标点击的 y 坐标)、flags(附加参数,如 cv2.EVENT_FLAG_CTRLKEYcv2.EVENT_FLAG_SHIFTKEY 等)。
  • param 是传递给回调函数的可选参数。

封装为类:

python 复制代码
import cv2
import numpy as np


class Painter:
    def __init__(self):
        self.drawing = False
        self.ix, self.iy = -1, -1
        self.img = np.zeros((500, 500, 3), np.uint8)

    def mouse_paint(self, event, x, y, flags, param):
        if event == cv2.EVENT_LBUTTONDOWN:
            self.drawing = True
            self.ix, self.iy = x, y
        elif event == cv2.EVENT_MOUSEMOVE:
            if self.drawing:
                cv2.line(self.img, (self.ix, self.iy), (x, y), (0, 255, 0), 1)
                self.ix, self.iy = x, y
                cv2.imshow('image', self.img)
        elif event == cv2.EVENT_LBUTTONUP:
            self.drawing = False
            cv2.waitKey(0)

    def run(self):

        cv2.setMouseCallback('image', self.mouse_paint)
        cv2.imshow('image', self.img)
        cv2.waitKey(0)
        cv2.imwrite('output_image.jpg', self.img)
        cv2.destroyAllWindows()


if __name__ == "__main__":
    cv2.namedWindow('image')
    painter = Painter()
    painter.run()

使用PySide6和OpenCV实现:

目前阶段我的PySide6熟悉程度要强于OpenCV

python 复制代码
import sys
from PySide6.QtWidgets import QApplication, QLabel, QVBoxLayout, QWidget, QPushButton
from PySide6.QtGui import QPainter, QPixmap, QMouseEvent, QColor, QPen, QImage
from PySide6.QtCore import Qt, QPoint
import cv2
import numpy as np


class PaintLabel(QLabel):
    def __init__(self, parent=None):
        super(PaintLabel, self).__init__(parent)
        self.image = QImage()
        self.drawing = False
        self.last_point = QPoint()

    def set_image(self, image_file):
        self.image = QImage(image_file)
        self.setPixmap(QPixmap.fromImage(self.image))

    def mousePressEvent(self, event: QMouseEvent):
        if event.button() == Qt.LeftButton:
            self.drawing = True
            self.last_point = event.position()

    def mouseMoveEvent(self, event: QMouseEvent):
        if event.buttons() & Qt.LeftButton and self.drawing:
            painter = QPainter(self.image)
            pen = QPen(QColor('red'))
            pen.setWidth(3)
            painter.setPen(pen)
            painter.drawLine(self.last_point, event.position())
            self.last_point = event.position()
            self.setPixmap(QPixmap.fromImage(self.image))

    def mouseReleaseEvent(self, event: QMouseEvent):
        if event.button() == Qt.LeftButton:
            self.drawing = False

    def save_image(self, file_path):
        self.image.save(file_path)


class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.label = PaintLabel()

        # Load an image (you can change the file path)
        img = np.zeros((500, 500, 3), np.uint8)  # 创建空白图像
        q_img = cv2side(img)


        self.label.set_image(q_img)

        save_button = QPushButton('Save Image')
        save_button.clicked.connect(self.save_image)

        layout = QVBoxLayout()
        layout.addWidget(self.label)
        layout.addWidget(save_button)
        self.setLayout(layout)

    def save_image(self):
        self.label.save_image('output_image.png')


# 将OpenCV格式的图像转换为PySide格式
def cv2side(img):
    img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  # 转换 BGR 到 RGB

    # 转换图像到QT的QImage格式
    height, width, channels = img_rgb.shape  # 获取形状
    bytes_per_line = channels * width  # 每行字节数
    q_img = QImage(img_rgb.data, width, height, bytes_per_line, QImage.Format_RGB888)  # 转换成QImage格
    return q_img


if __name__ == "__main__":
    app = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    sys.exit(app.exec())

运行截图:

相关推荐
lizz6665 分钟前
Hermes-Agent 新手安装指南(言简意赅版)
人工智能·ai
Logintern096 分钟前
【大语言模型应用】利用 DuckDuckGo 和 Tavily 搜索引擎
人工智能·搜索引擎·语言模型
chao_66666616 分钟前
2026定制AI玩具/AI硬件头部厂商全解析,定制需求选型参考
人工智能
gorgeous(๑>؂<๑)22 分钟前
【CVPR26-陶大程-南洋理工】启发式推理先验助力数据高效型指代目标检测
人工智能·目标检测·计算机视觉
Sharewinfo_BJ25 分钟前
香港Databricks AI DAYS参会笔记:Agentic Analytics离我们还有多远
大数据·人工智能·数据分析·powerbi
羽师40 分钟前
RAG工作流程的执行时机
人工智能
常宇杏起1 小时前
AI安全进阶:AI模型投毒攻击的检测与防御
大数据·人工智能·安全
ronindong1 小时前
Cursor 插件分享 | md-couture:一键将 Markdown 转换成带精美样式的 HTML
人工智能·python·ai编程
小陈phd1 小时前
多模态大模型学习笔记(三十六)—— 扩散模型与可控生成:从AI涂鸦到精准作画的技术革命
人工智能·笔记·学习