用于AI-CV项目标注的星标模型

功能:生成星标图形项,并在目标点上将底图颜色反色显示,当定位和拖动后输出底图在标记点的像素值。输入和输出使用信号槽机制。

代码:

import math
import sys

from PySide6.QtCore import QPointF, QObject, QRectF, Signal
from PySide6.QtGui import QBrush, QPixmap, QColor, QPen
from PySide6.QtWidgets import QApplication, QGraphicsScene, QGraphicsView, QGraphicsPolygonItem, QGraphicsItem, \
    QGraphicsPixmapItem, QGraphicsRectItem
from fontTools.pens.qtPen import QtPen


class StarItem(QGraphicsPolygonItem, QObject):
    I_position_signal = Signal(QPointF)  # 位置信号(输入)
    O_colorCenter_signal = Signal(QColor)  # 中心点颜色信号(输出)
    def __init__(self, size, baseImageItem, num_points = 5, ratio=0.4, parent=None):
        """
        用来标记图片的星标
        :param size: 尺寸
        :param baseImageItem: 底图
        :param num_points: 顶点数
        :param ratio: 肥瘦比
        :param parent: 父类
        """
        QGraphicsPolygonItem.__init__(self, parent=parent)
        QObject.__init__(self)
        self.outer_radius = size / 2  # 外圆半径
        self.inner_radius = size * ratio / 2  # 内圆半径
        self.num_points = num_points  # 顶点数
        self.setPolygon(self.calculate_star_points())  # 设置多边形
        self.setAcceptHoverEvents(True)  # 启用鼠标跟踪
        self.setFlag(QGraphicsItem.ItemIsMovable, True)  # 设置可移动
        self.basePixmapItem = baseImageItem  # 获取底图图片项
        self.basePixmap = self.basePixmapItem.pixmap()  # 获取底图图片
        # 如果本星标没有父类,则设置底图为父类
        if parent is None:
            self.parent = self.basePixmapItem  # 设置父类
        self.colorCenter = QColor(0, 0, 0)  # 中心点的颜色
        self.signalAndSlot()  # 信号与槽

    def signalAndSlot(self):
        """
        信号与槽
        :return:
        """
        self.I_position_signal.connect(self.setPos)  # 连接信号与槽setPos


    def getInverseColor(self, color):
        """
        获取反色
        :param color:
        :return:
        """
        r = 255 - color.red()
        g = 255 - color.green()
        b = 255 - color.blue()
        return QColor(r, g, b)

    def setColor(self):
        """
        获取中心点颜色,设置画刷和画笔颜色
        :return:
        """
        # pos = self.mapToItem(self.basePixmapItem, self.mapFromParent(self.pos()))
        pos_scene = self.mapToScene(QPointF(0, 0))   # 获取中心点所在位置在场景中的坐标
        pos_base = self.basePixmapItem.mapFromScene(pos_scene)  # 获取中心点所在位置映射到底图的坐标
        self.colorCenter = self.basePixmap.toImage().pixelColor(pos_base.toPoint())  # 获取鼠标所在位置的像素颜色
        # print(self.colorCenter)
        color = self.getInverseColor(self.colorCenter)  # 设置反色
        self.setBrush(QBrush(color))  # 设置画刷
        # ###########如果需要不同的外轮廓颜色###############
        # self.setPen(QPen(QColor("red")))
        # #############################################
        self.setPen(QPen(QColor(color)))  # 设置画笔
        self.O_colorCenter_signal.emit(self.colorCenter)  # 发送信号colorCenter

    # 重写设置位置函数,使星标的参考点在中心
    def setPos(self, pos):
        x = pos.x()  # 使星标的参考点在中心
        y = pos.y()
        self.setColor()  # 设置中心点颜色
        super().setPos(x, y)   # 调用父类的设置位置函数


    def hoverEnterEvent(self, event):
        pass

    def hoverLeaveEvent(self, event):
        pass
        # 重写鼠标移动事件,使星标的颜色与背景图片反色,突出显示
    def mouseMoveEvent(self, event):
        self.setColor()
        super().mouseMoveEvent(event)

    def calculate_star_points(self):
        """
        计算顶点坐标
        :return:
        """
        points = []
        angle_step = 2 * math.pi / self.num_points
        if self.num_points % 2 == 0:
            start_angle = 0
        else:
            start_angle = angle_step / 2
        for i in range(self.num_points * 2):
            if i % 2 == 0:
                current_radius = self.outer_radius
            else:
                current_radius = self.inner_radius
            angle = i * angle_step / 2 + start_angle
            x = current_radius * math.sin(angle)
            y = current_radius * math.cos(angle)
            points.append(QPointF(x, y))
        return points

if __name__ == "__main__":
    app = QApplication(sys.argv)

    # 创建场景和视图
    scene = QGraphicsScene()
    view = QGraphicsView(scene)

    # 创建底图
    pixmap = QPixmap("C:\\Users\\DY\\PycharmProjects\\cncor\\UI_demo\\flower.jpg")
    pixmap_item = QGraphicsPixmapItem(pixmap)

    # 创建矩形框
    rect_item = QGraphicsRectItem(QRectF(0, 0, 200, 200), parent=pixmap_item)
    rect_item.setFlag(QGraphicsItem.ItemIsMovable, True)  # 设置可移动
    rect_item.setPen(QPen(QColor("red")))
    # scene.addItem(rect_item)

    # 创建星标
    star_item = StarItem(30, baseImageItem=pixmap_item, parent=rect_item)
    star_item.O_colorCenter_signal.connect(lambda color: print(f"中心点颜色:{color.red(), color.green(), color.blue()}"))  # 连接信号与槽,显示中心点颜色
    star_item.I_position_signal.emit(QPointF(100, 100))  # 发送信号,将星标移动到指定位置(对应于父系坐标)

    # 将底图添加到场景中
    scene.addItem(pixmap_item)

    # 显示视图
    view.show()

    sys.exit(app.exec())


 

你可能感兴趣的:(pyside6系统学习,机器视觉和人工智能学习,pyside6学习笔记,python,开发语言,pyqt)