如何在使用pyqt5对图像进行注释时打印特定的照片路径?

2024-04-25 08:07:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经建立了一个图像注释工具,可以用来注释不同的图像。我现在的问题是,每当进行注释时,我只会获取作为注释输入的文本和选定区域坐标,但不会获取为其进行注释的图像名称

这是我的密码:

from PyQt5.QtWidgets import QMainWindow, QApplication, QDesktopWidget, QHBoxLayout, QWidget, QLabel, QVBoxLayout
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import glob
import os


class SecondWindow(QWidget):

    def __init__(self):
        super().__init__()
        self.setWindowTitle('Picture annotation')
        self.main_layout = QVBoxLayout(self)
        self.button_layout = QHBoxLayout(self)
        self.name = QtWidgets.QLineEdit(self)
        self.name.setPlaceholderText("Annotation")
        self.pushButton = QtWidgets.QPushButton(self)
        self.pushButton.setText("Save Annotation")
        self.pushButton2 = QtWidgets.QPushButton(self)
        self.pushButton2.setText("Cancel")
        self.main_layout.addWidget(self.name)
        self.main_layout.addLayout(self.button_layout)
        self.button_layout.addWidget(self.pushButton2, 1)
        self.button_layout.addWidget(self.pushButton, 2)
        self.pushButton.clicked.connect(self.save_annotation)
        self.pushButton2.clicked.connect(self.cancel)

        self.show()

    def save_annotation(self):
        with open('coordinates.txt', 'a') as file:
            file.write(f'; Annotation: {self.name.text()}')
        self.close()

    def cancel(self):
        fd = open('coordinates.txt', "r")
        d = fd.read()
        fd.close()
        m = d.split("\n")
        s = "\n".join(m[:-1])
        fd = open('coordinates.txt', "w+")
        for i in range(len(s)):
            fd.write(s[i])
        fd.close()

        self.close()


class TestRect(QLabel):
    def __init__(self):
        super().__init__()
        self.begin = QPoint()
        self.end = QPoint()
        self.begin = QPoint()
        self.end = QPoint()
        self.rectangles = []

    def paintEvent(self, event):
        super().paintEvent(event)
        qp = QPainter(self)
        qp.setPen(QPen(Qt.black, 3, Qt.SolidLine))
        for rectangle in self.rectangles:
            qp.drawRect(rectangle)
        if not self.begin.isNull() and not self.end.isNull():
            qp.drawRect(QRect(self.begin, self.end).normalized())

    def mousePressEvent(self, event):
        self.begin = self.end = event.pos()
        self.update()
        super().mousePressEvent(event)

    def mouseMoveEvent(self, event):
        self.end = event.pos()
        self.update()
        super().mouseMoveEvent(event)

    def mouseReleaseEvent(self, event):
        r = QRect(self.begin, self.end).normalized()
        print(self.begin, self.end)
        with open('coordinates.txt', 'a') as file:
            file.write(f'\ncoordinates: {self.begin.x()}, {self.begin.y()}, {self.end.x()}, {self.end.y()}')
        self.rectangles.append(r)
        self.begin = self.end = QPoint()
        self.update()
        super().mouseReleaseEvent(event)
        self.window2 = SecondWindow()
        self.window2.show()


class TestWindow(QMainWindow):

    def __init__(self):
        super().__init__()
        win_rectangle = self.frameGeometry()
        center_point = QDesktopWidget().availableGeometry().center()
        win_rectangle.moveCenter(center_point)
        self.move(win_rectangle.topLeft())
        self.main_layout = QHBoxLayout()
        self.layout2 = QVBoxLayout()
        self.central_widget = QWidget(self)
        self.test_image()
        self.show()

    def test_image(self):
        self.central_widget.setLayout(self.main_layout)
        self.setCentralWidget(self.central_widget)
        self.listWidget = QtWidgets.QListWidget(self)
        self.main_layout.addWidget(self.listWidget, 1)
        for i in [i.replace('\\', '/') for i in glob.glob("pic/*")]:
            item = i
            self.listWidget.addItem(item)
        self.listWidget.itemClicked.connect(self.change_picture)
        self.Photo = TestRect()
        self.finish = QtWidgets.QPushButton(self)
        self.finish.setText("Finish Annotation and save")
        self.label2 = QtWidgets.QLabel(self)
        self.label2.setText('Always select the picture on the left hand side before you make annotation!!')
        self.label2.setStyleSheet("color: red")
        self.finish.clicked.connect(self.save_annotation)
        self.main_layout.addLayout(self.layout2, 3)
        self.layout2.addWidget(self.label2, 1)
        self.layout2.addWidget(self.Photo, 5)
        self.layout2.addWidget(self.finish, 1)

        self.Photo.setPixmap(QtGui.QPixmap("pic/cat1.jpg").scaled(500, 500))
        self.Photo.setScaledContents(True)

    def change_picture(self):
        i = self.listWidget.currentItem()
        self.Photo.setPixmap(QtGui.QPixmap(i.text()).scaled(500, 500))
        self.Photo.rectangles = []

    def save_annotation(self):
        i = self.listWidget.currentItem().text()
        os.rename(i, i.replace('pic/', 'ready/'))
        listItems = self.listWidget.selectedItems()
        if not listItems:
            return
        for item in listItems:
            self.listWidget.takeItem(self.listWidget.row(item))



if __name__ == '__main__':
    test = QApplication(sys.argv)
    test_window = TestWindow()
    sys.exit(test.exec_())

这就是我得到的结果:

coordinates: 354, 97, 499, 373; Annotation: cat2
coordinates: 139, 10, 260, 334; Annotation: cat
coordinates: 483, 50, 578, 274; Annotation: cat
coordinates: 31, 120, 276, 458; Annotation: pepper
coordinates: 294, 173, 557, 456; Annotation: pepper

但我也想知道注释是针对哪个图像(它的路径)。那么我怎样才能把这些信息包括在内呢

因此,每行的格式应类似于:

C:\images\imagename.jpg; coordinates: 31, 120, 276, 458; Annotation: pepper

另外,如果有人在绘制矩形后单击“取消”,我希望矩形消失。如何做到这一点