autoDialog.py 5.9 KB
Newer Older
qq_25193841's avatar
qq_25193841 已提交
1 2 3 4 5 6 7 8
try:
    from PyQt5.QtGui import *
    from PyQt5.QtCore import *
    from PyQt5.QtWidgets import *
except ImportError:
    from PyQt4.QtGui import *
    from PyQt4.QtCore import *

9 10
import time
import datetime
qq_25193841's avatar
qq_25193841 已提交
11
import json
12 13
import cv2
import numpy as np
qq_25193841's avatar
qq_25193841 已提交
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

from libs.utils import newIcon

BB = QDialogButtonBox


class Worker(QThread):
    progressBarValue = pyqtSignal(int)
    listValue = pyqtSignal(str)
    endsignal = pyqtSignal(int, str)
    handle = 0

    def __init__(self, ocr, mImgList, mainThread, model):
        super(Worker, self).__init__()
        self.ocr = ocr
        self.mImgList = mImgList
        self.mainThread = mainThread
        self.model = model
        self.setStackSize(1024*1024)

    def run(self):
        try:
            findex = 0
            for Imgpath in self.mImgList:
                if self.handle == 0:
                    self.listValue.emit(Imgpath)
                    if self.model == 'paddle':
41 42
                        h, w, _ = cv2.imdecode(np.fromfile(Imgpath, dtype=np.uint8), 1).shape
                        if h > 32 and w > 32:
43
                            self.result_dic = self.ocr.ocr(Imgpath, cls=True, det=True)[0]
44 45 46
                        else:
                            print('The size of', Imgpath, 'is too small to be recognised')
                            self.result_dic = None
qq_25193841's avatar
qq_25193841 已提交
47 48 49

                    # 结果保存
                    if self.result_dic is None or len(self.result_dic) == 0:
50
                        print('Can not recognise file', Imgpath)
qq_25193841's avatar
qq_25193841 已提交
51 52
                        pass
                    else:
qq_25193841's avatar
qq_25193841 已提交
53
                        strs = ''
qq_25193841's avatar
qq_25193841 已提交
54 55 56 57
                        for res in self.result_dic:
                            chars = res[1][0]
                            cond = res[1][1]
                            posi = res[0]
qq_25193841's avatar
qq_25193841 已提交
58 59
                            strs += "Transcription: " + chars + " Probability: " + str(cond) + \
                                    " Location: " + json.dumps(posi) +'\n'
60
                        # Sending large amounts of data repeatedly through pyqtSignal may affect the program efficiency
qq_25193841's avatar
qq_25193841 已提交
61
                        self.listValue.emit(strs)
qq_25193841's avatar
qq_25193841 已提交
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
                        self.mainThread.result_dic = self.result_dic
                        self.mainThread.filePath = Imgpath
                        # 保存
                        self.mainThread.saveFile(mode='Auto')
                    findex += 1
                    self.progressBarValue.emit(findex)
                else:
                    break
            self.endsignal.emit(0, "readAll")
            self.exec()
        except Exception as e:
            print(e)
            raise


class AutoDialog(QDialog):

    def __init__(self, text="Enter object label", parent=None, ocr=None, mImgList=None, lenbar=0):
        super(AutoDialog, self).__init__(parent)
        self.setFixedWidth(1000)
        self.parent = parent
        self.ocr = ocr
        self.mImgList = mImgList
85
        self.lender = lenbar
qq_25193841's avatar
qq_25193841 已提交
86
        self.pb = QProgressBar()
87
        self.pb.setRange(0, self.lender)
qq_25193841's avatar
qq_25193841 已提交
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
        self.pb.setValue(0)

        layout = QVBoxLayout()
        layout.addWidget(self.pb)
        self.model = 'paddle'
        self.listWidget = QListWidget(self)
        layout.addWidget(self.listWidget)

        self.buttonBox = bb = BB(BB.Ok | BB.Cancel, Qt.Horizontal, self)
        bb.button(BB.Ok).setIcon(newIcon('done'))
        bb.button(BB.Cancel).setIcon(newIcon('undo'))
        bb.accepted.connect(self.validate)
        bb.rejected.connect(self.reject)
        layout.addWidget(bb)
        bb.button(BB.Ok).setEnabled(False)

        self.setLayout(layout)
qq_25193841's avatar
qq_25193841 已提交
105
        # self.setWindowTitle("自动标注中")
qq_25193841's avatar
qq_25193841 已提交
106 107 108 109 110 111 112 113
        self.setWindowModality(Qt.ApplicationModal)

        # self.setWindowFlags(Qt.WindowCloseButtonHint)

        self.thread_1 = Worker(self.ocr, self.mImgList, self.parent, 'paddle')
        self.thread_1.progressBarValue.connect(self.handleProgressBarSingal)
        self.thread_1.listValue.connect(self.handleListWidgetSingal)
        self.thread_1.endsignal.connect(self.handleEndsignalSignal)
114
        self.time_start = time.time()  # save start time
qq_25193841's avatar
qq_25193841 已提交
115 116 117 118

    def handleProgressBarSingal(self, i):
        self.pb.setValue(i)

119 120
        # calculate time left of auto labeling
        avg_time = (time.time() - self.time_start) / i  # Use average time to prevent time fluctuations
121
        time_left = str(datetime.timedelta(seconds=avg_time * (self.lender - i))).split(".")[0]  # Remove microseconds
122 123
        self.setWindowTitle("PPOCRLabel  --  " + f"Time Left: {time_left}")  # show

qq_25193841's avatar
qq_25193841 已提交
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
    def handleListWidgetSingal(self, i):
        self.listWidget.addItem(i)
        titem = self.listWidget.item(self.listWidget.count() - 1)
        self.listWidget.scrollToItem(titem)

    def handleEndsignalSignal(self, i, str):
        if i == 0 and str == "readAll":
            self.buttonBox.button(BB.Ok).setEnabled(True)
            self.buttonBox.button(BB.Cancel).setEnabled(False)

    def reject(self):
        print("reject")
        self.thread_1.handle = -1
        self.thread_1.quit()
        # del self.thread_1
        # if self.thread_1.isRunning():
        #     self.thread_1.terminate()
        # self.thread_1.quit()
        # super(AutoDialog,self).reject()
        while not self.thread_1.isFinished():
            pass
        self.accept()

    def validate(self):
        self.accept()

    def postProcess(self):
        try:
            self.edit.setText(self.edit.text().trimmed())
            # print(self.edit.text())
        except AttributeError:
            # PyQt5: AttributeError: 'str' object has no attribute 'trimmed'
            self.edit.setText(self.edit.text())
            print(self.edit.text())

    def popUp(self):
        self.thread_1.start()
        return 1 if self.exec_() else None

    def closeEvent(self, event):
        print("???")
        # if self.thread_1.isRunning():
        #     self.thread_1.quit()
        #
        #     # self._thread.terminate()
        # # del self.thread_1
        # super(AutoDialog, self).closeEvent(event)
        self.reject()