autoDialog.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. try:
  2. from PyQt5.QtGui import *
  3. from PyQt5.QtCore import *
  4. from PyQt5.QtWidgets import *
  5. except ImportError:
  6. from PyQt4.QtGui import *
  7. from PyQt4.QtCore import *
  8. import time
  9. import datetime
  10. import json
  11. import cv2
  12. import numpy as np
  13. from libs.utils import newIcon
  14. BB = QDialogButtonBox
  15. class Worker(QThread):
  16. progressBarValue = pyqtSignal(int)
  17. listValue = pyqtSignal(str)
  18. endsignal = pyqtSignal(int, str)
  19. handle = 0
  20. def __init__(self, ocr, mImgList, mainThread, model):
  21. super(Worker, self).__init__()
  22. self.ocr = ocr
  23. self.mImgList = mImgList
  24. self.mainThread = mainThread
  25. self.model = model
  26. self.setStackSize(1024*1024)
  27. def run(self):
  28. try:
  29. findex = 0
  30. for Imgpath in self.mImgList:
  31. if self.handle == 0:
  32. self.listValue.emit(Imgpath)
  33. if self.model == 'paddle':
  34. h, w, _ = cv2.imdecode(np.fromfile(Imgpath, dtype=np.uint8), 1).shape
  35. if h > 32 and w > 32:
  36. self.result_dic = self.ocr.ocr(Imgpath, cls=True, det=True)[0]
  37. else:
  38. print('The size of', Imgpath, 'is too small to be recognised')
  39. self.result_dic = None
  40. # 结果保存
  41. if self.result_dic is None or len(self.result_dic) == 0:
  42. print('Can not recognise file', Imgpath)
  43. pass
  44. else:
  45. strs = ''
  46. for res in self.result_dic:
  47. chars = res[1][0]
  48. cond = res[1][1]
  49. posi = res[0]
  50. strs += "Transcription: " + chars + " Probability: " + str(cond) + \
  51. " Location: " + json.dumps(posi) +'\n'
  52. # Sending large amounts of data repeatedly through pyqtSignal may affect the program efficiency
  53. self.listValue.emit(strs)
  54. self.mainThread.result_dic = self.result_dic
  55. self.mainThread.filePath = Imgpath
  56. # 保存
  57. self.mainThread.saveFile(mode='Auto')
  58. findex += 1
  59. self.progressBarValue.emit(findex)
  60. else:
  61. break
  62. self.endsignal.emit(0, "readAll")
  63. self.exec()
  64. except Exception as e:
  65. print(e)
  66. raise
  67. class AutoDialog(QDialog):
  68. def __init__(self, text="Enter object label", parent=None, ocr=None, mImgList=None, lenbar=0):
  69. super(AutoDialog, self).__init__(parent)
  70. self.setFixedWidth(1000)
  71. self.parent = parent
  72. self.ocr = ocr
  73. self.mImgList = mImgList
  74. self.lender = lenbar
  75. self.pb = QProgressBar()
  76. self.pb.setRange(0, self.lender)
  77. self.pb.setValue(0)
  78. layout = QVBoxLayout()
  79. layout.addWidget(self.pb)
  80. self.model = 'paddle'
  81. self.listWidget = QListWidget(self)
  82. layout.addWidget(self.listWidget)
  83. self.buttonBox = bb = BB(BB.Ok | BB.Cancel, Qt.Horizontal, self)
  84. bb.button(BB.Ok).setIcon(newIcon('done'))
  85. bb.button(BB.Cancel).setIcon(newIcon('undo'))
  86. bb.accepted.connect(self.validate)
  87. bb.rejected.connect(self.reject)
  88. layout.addWidget(bb)
  89. bb.button(BB.Ok).setEnabled(False)
  90. self.setLayout(layout)
  91. # self.setWindowTitle("自动标注中")
  92. self.setWindowModality(Qt.ApplicationModal)
  93. # self.setWindowFlags(Qt.WindowCloseButtonHint)
  94. self.thread_1 = Worker(self.ocr, self.mImgList, self.parent, 'paddle')
  95. self.thread_1.progressBarValue.connect(self.handleProgressBarSingal)
  96. self.thread_1.listValue.connect(self.handleListWidgetSingal)
  97. self.thread_1.endsignal.connect(self.handleEndsignalSignal)
  98. self.time_start = time.time() # save start time
  99. def handleProgressBarSingal(self, i):
  100. self.pb.setValue(i)
  101. # calculate time left of auto labeling
  102. avg_time = (time.time() - self.time_start) / i # Use average time to prevent time fluctuations
  103. time_left = str(datetime.timedelta(seconds=avg_time * (self.lender - i))).split(".")[0] # Remove microseconds
  104. self.setWindowTitle("PPOCRLabel -- " + f"Time Left: {time_left}") # show
  105. def handleListWidgetSingal(self, i):
  106. self.listWidget.addItem(i)
  107. titem = self.listWidget.item(self.listWidget.count() - 1)
  108. self.listWidget.scrollToItem(titem)
  109. def handleEndsignalSignal(self, i, str):
  110. if i == 0 and str == "readAll":
  111. self.buttonBox.button(BB.Ok).setEnabled(True)
  112. self.buttonBox.button(BB.Cancel).setEnabled(False)
  113. def reject(self):
  114. print("reject")
  115. self.thread_1.handle = -1
  116. self.thread_1.quit()
  117. # del self.thread_1
  118. # if self.thread_1.isRunning():
  119. # self.thread_1.terminate()
  120. # self.thread_1.quit()
  121. # super(AutoDialog,self).reject()
  122. while not self.thread_1.isFinished():
  123. pass
  124. self.accept()
  125. def validate(self):
  126. self.accept()
  127. def postProcess(self):
  128. try:
  129. self.edit.setText(self.edit.text().trimmed())
  130. # print(self.edit.text())
  131. except AttributeError:
  132. # PyQt5: AttributeError: 'str' object has no attribute 'trimmed'
  133. self.edit.setText(self.edit.text())
  134. print(self.edit.text())
  135. def popUp(self):
  136. self.thread_1.start()
  137. return 1 if self.exec_() else None
  138. def closeEvent(self, event):
  139. print("???")
  140. # if self.thread_1.isRunning():
  141. # self.thread_1.quit()
  142. #
  143. # # self._thread.terminate()
  144. # # del self.thread_1
  145. # super(AutoDialog, self).closeEvent(event)
  146. self.reject()