프로젝트

일반

사용자정보

개정판 1cfeb071

ID1cfeb0713fac060a5dd0a2ad7fcb6b36ebe7348c
상위 d4beff71
하위 9a202857

백흠경이(가) 약 5년 전에 추가함

issue #478: 멀티 라인 텍스트의 크기 조정
- OcrResultDialog에 단축키 't' 적용(텍스트 인식)

Change-Id: Id45af40d59979a626f6e8f7c502294f707e5d644

차이점 보기:

DTI_PID/DTI_PID/OcrResultDialog.py
15 15
import tesseract_ocr_module as TOCR
16 16
from App import App
17 17
from AppDocData import *
18
from TextInfo import TextInfo
18 19

  
19 20

  
20 21
class SpellTextEdit(QTextEdit):
......
54 55
        self._text_item = text_item
55 56
        self.image = qimage
56 57
        self.boundingBox = boundingBox
58
        self._bounding_box = QRectF(0, 0, boundingBox.width(), boundingBox.height())
57 59

  
58
        self.angle = 0  # angle is degree
60
        self.angle = 0  # angle in degree
59 61

  
60 62
        self.ui = OcrResultDialog_UI.Ui_Dialog()
61 63
        self.ui.setupUi(self)
......
77 79

  
78 80
        self.ui.counterClockPushButton_2.clicked.connect(lambda: self.rotateImage(True))
79 81
        self.ui.clockPushButton_2.clicked.connect(lambda: self.rotateImage(False))
80
        self.ui.redetectPushButton_2.clicked.connect(self.detect_text)
82
        # add shortcut for detecting text with 't'
83
        self.ui.redetectPushButton.clicked.connect(self.detect_text)
84
        shortcut = QShortcut(QKeySequence('t'), self.ui.redetectPushButton)
85
        shortcut.activated.connect(self.detect_text)
86
        # up to here
81 87
        self.ui.pushButtonMakeTrainingImage.clicked.connect(self.pushButtonMakeTrainingImageClicked)
82 88

  
83 89
        self.ui.comboBoxOCRData.addItem('eng')
......
94 100
            self.ui.comboBoxOCRData.selectedIndex = 0
95 101

  
96 102
        if not self._text_item:
103
            if self.boundingBox.height() > self.boundingBox.width():
104
                self.rotateImage(False)
105

  
97 106
            self.detect_text()
98 107
        else:
108
            rect = self._text_item.sceneBoundingRect()
109
            text_info = TextInfo(self._text_item.text(), 0, 0, rect.width(), rect.height(), 0)
110
            self.textInfoList.append(text_info)
111
            self.display_text_rect()
112

  
113
            allowed_error = 0.001
114
            if abs(self._text_item.angle - 1.57) < allowed_error or abs(self._text_item.angle - 4.71) < allowed_error:
115
                self.rotateImage(False)
116

  
99 117
            self.ui.detectResultTextEdit.setPlainText(self._text_item.text())
100 118
            self.ui.checkBoxSeperate.setChecked(False)
101 119

  
......
105 123
        """show event"""
106 124
        self.graphicsView.zoomImageInit()
107 125

  
126
    def display_text_rect(self):
127
        """display text bounding rectangle"""
128
        for item in self.graphicsView.scene.items():
129
            if type(item) is not QGraphicsPixmapItem:
130
                self.graphicsView.scene.removeItem(item)
131

  
132
        for text_info in self.textInfoList:
133
            self.graphicsView.scene.addRect(text_info.getX(), text_info.getY(),
134
                                            text_info.getW(), text_info.getH(), QPen(Qt.red, 1, Qt.SolidLine))
135

  
108 136
    '''
109 137
        @brief      Make OCR Training Image
110 138
        @author     euisung
......
124 152
        QDialog.reject(self)
125 153

  
126 154
    def rotateImage(self, isCounterClock):
127
        for item in self.graphicsView.scene.items():
128
            self.graphicsView.scene.removeItem(item)
129
        self.graphicsView.clearImage()
155
        """rotate the image"""
156

  
130 157
        transform = QTransform()
131 158
        if isCounterClock:
132 159
            '''CounterClock'''
......
136 163
            '''Clock'''
137 164
            self.angle = (self.angle - 270) % 360
138 165
            transform.rotate(90)
139
        # print(str(360 - self.angle))
166

  
167
        self.graphicsView.clearImage()
140 168
        self.image = self.image.transformed(transform)
141 169
        self.graphicsView.setImage(self.image)
142
        self.textInfoList = []
170

  
171
        for text_info in self.textInfoList:
172
            rect = QRectF(text_info.getX(), text_info.getY(), text_info.getW(), text_info.getH())
173
            rect = transform.mapRect(rect)
174
            text_info.setX(self.image.width() + rect.left() if rect.left() < 0 else rect.left())
175
            text_info.setY(self.image.height() - max(abs(rect.top()), abs(rect.bottom())) if rect.top() < 0 else rect.top())
176
            text_info.setW(rect.width())
177
            text_info.setH(rect.height())
178

  
179
            self.graphicsView.scene.addRect(QRectF(text_info.getX(), text_info.getY(), text_info.getW(), text_info.getH()),
180
                                            QPen(Qt.red, 1, Qt.SolidLine))
181

  
182
        self._bounding_box = transform.mapRect(self._bounding_box)
143 183

  
144 184
    '''
145 185
        @history 2018.04.26 Jeongwoo    Add Rectangle with modified Coords
......
161 201

  
162 202
            whiteCharList = app_doc_data.getConfigs('Text Recognition', 'White Character List')
163 203
            if len(whiteCharList) is 0:
164
                self.textInfoList = TOCR.getTextInfo(img, (round(self.boundingBox.x()), round(self.boundingBox.y())), 0,
165
                                                     language=ocr_data)
204
                self.textInfoList = TOCR.getTextInfo(img, (0, 0), 0, language=ocr_data)
166 205
            else:
167
                self.textInfoList = TOCR.getTextInfo(img, (round(self.boundingBox.x()), round(self.boundingBox.y())), 0,
168
                                                     language=ocr_data, conf=whiteCharList[0].value)
206
                self.textInfoList = TOCR.getTextInfo(img, (0, 0), 0, language=ocr_data, conf=whiteCharList[0].value)
169 207

  
170
            if self.textInfoList is not None and len(self.textInfoList) > 0:
208
            if self.textInfoList:
171 209
                self.ui.detectResultTextEdit.setText(self.getPlainText(self.textInfoList))
172
                for textInfo in self.textInfoList:
173
                    self.graphicsView.scene.addRect(textInfo.getX() - int(self.boundingBox.x()),
174
                                                    textInfo.getY() - int(self.boundingBox.y()), textInfo.getW(),
175
                                                    textInfo.getH(), QPen(Qt.red, 1, Qt.SolidLine))
210
                self.display_text_rect()
176 211
            else:
177
                self.ui.detectResultTextEdit.setText("Not Found")
212
                self.ui.detectResultTextEdit.setText(self.tr("Not Found"))
178 213
        except Exception as ex:
179 214
            from App import App
180
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
215
            message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
181 216
                                                           sys.exc_info()[-1].tb_lineno)
182 217
            App.mainWnd().addMessage.emit(MessageType.Error, message)
183 218

  
......
217 252

  
218 253
            # try to detect text if there is no result of detection or
219 254
            # count of text info list not match with count of split text
220
            if isSplit and self.textInfoList and (len(self.textInfoList) == len(splitText)):
221
                for index in range(len(self.textInfoList)):
222
                    self.textInfoList[index].setText(splitText[index])
223
            elif isSplit and not self.textInfoList:
224
                self.detect_text()
225
                if len(self.textInfoList) == len(splitText):
255
            if isSplit:
256
                if self.textInfoList and (len(self.textInfoList) == len(splitText)):
226 257
                    for index in range(len(self.textInfoList)):
227 258
                        self.textInfoList[index].setText(splitText[index])
228
                else:
229
                    self.textInfoList = self.getMergedTextInfo(text)
230
            else:
259
                elif not self.textInfoList:
260
                    self.detect_text()
261
                    if len(self.textInfoList) == len(splitText):
262
                        for index in range(len(self.textInfoList)):
263
                            self.textInfoList[index].setText(splitText[index])
264
                    else:
265
                        self.textInfoList = self.getMergedTextInfo(text)
266
            elif len(self.textInfoList) > 1:
231 267
                self.textInfoList = self.getMergedTextInfo(text)
232 268

  
233 269
            radian = round(math.radians(abs(self.angle)), 2)
234
            if radian == 1.57 or radian == 4.71:
235
                for text_info in self.textInfoList:
270
            for idx in range(len(self.textInfoList)):
271
                text_info = self.textInfoList[idx]
272
                # update text using user input text
273
                if idx < len(splitText):
274
                    text_info.setText(splitText[idx])
275
                # up to here
276

  
277
                if radian == 1.57 or radian == 4.71:
236 278
                    text_info.setAngle(radian)  # 360 degree == 6.28319 radian
237
                    width = text_info.getW()
238
                    height = text_info.getH()
239
                    text_info.setW(height)  # SWAP
240
                    text_info.setH(width)  # SWAP
279

  
280
                    # rotate text information
281
                    trans = QTransform()
282
                    trans.rotate(self.angle*-1)
283
                    rect = QRectF(text_info.getX(), text_info.getY(), text_info.getW(), text_info.getH())
284
                    rect = trans.mapRect(rect)
285
                    width, height = self.image.height(), self.image.width()
286
                    x = width + rect.left() if rect.left() < 0 else rect.left()
287
                    y = height - max(abs(rect.top()), abs(rect.bottom())) if rect.top() < 0 else rect.top()
288
                    text_info.setX(self.boundingBox.x() + x)
289
                    text_info.setY(self.boundingBox.y() + y)
290
                    text_info.setW(rect.width())
291
                    text_info.setH(rect.height())
292
                    # up to here
293
                else:
294
                    text_info.setX(int(self.boundingBox.x()) + text_info.getX())
295
                    text_info.setY(int(self.boundingBox.y()) + text_info.getY())
241 296

  
242 297
            QDialog.accept(self)
243 298

  
......
265 320
        contours, hierarchy = cv2.findContours(imgNot, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
266 321
        minX, minY, maxX, maxY = sys.maxsize, sys.maxsize, 0, 0
267 322
        if len(contours) is 0:
268
            minX, minY, maxX, maxY = self.boundingBox.x(), self.boundingBox.y(), self.boundingBox.x() + self.image.width(), self.boundingBox.y() + self.image.height()
323
            minX, minY, maxX, maxY = 0, 0, self.image.width(), self.image.height()
269 324
        else:
270 325
            minX, minY, maxX, maxY = sys.maxsize, sys.maxsize, 0, 0
271 326
            for cnt in contours:
......
274 329
                minY = min(y, minY)
275 330
                maxX = max(x + w, maxX)
276 331
                maxY = max(y + h, maxY)
277
            minX, minY, maxX, maxY = minX + self.boundingBox.x(), minY + self.boundingBox.y(), maxX + self.boundingBox.x(), maxY + self.boundingBox.y()
332
            minX, minY, maxX, maxY = minX, minY, maxX, maxY
278 333

  
279 334
        return [TextInfo(text, minX, minY, maxX - minX, maxY - minY, 0)]
280 335

  
DTI_PID/DTI_PID/OcrResultDialog_UI.py
2 2

  
3 3
# Form implementation generated from reading ui file '.\UI\OcrResultDialog.ui'
4 4
#
5
# Created by: PyQt5 UI code generator 5.13.0
5
# Created by: PyQt5 UI code generator 5.14.1
6 6
#
7 7
# WARNING! All changes made in this file will be lost!
8 8

  
......
48 48
        self.clockPushButton_2.setIconSize(QtCore.QSize(32, 32))
49 49
        self.clockPushButton_2.setObjectName("clockPushButton_2")
50 50
        self.gridLayout.addWidget(self.clockPushButton_2, 0, 5, 1, 1)
51
        self.redetectPushButton_2 = QtWidgets.QPushButton(self.topWidget)
52
        self.redetectPushButton_2.setMinimumSize(QtCore.QSize(0, 60))
53
        self.redetectPushButton_2.setMaximumSize(QtCore.QSize(60, 60))
54
        self.redetectPushButton_2.setText("")
51
        self.redetectPushButton = QtWidgets.QPushButton(self.topWidget)
52
        self.redetectPushButton.setMinimumSize(QtCore.QSize(0, 60))
53
        self.redetectPushButton.setMaximumSize(QtCore.QSize(60, 60))
54
        self.redetectPushButton.setText("")
55 55
        icon1 = QtGui.QIcon()
56 56
        icon1.addPixmap(QtGui.QPixmap(":/newPrefix/OCR.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
57
        self.redetectPushButton_2.setIcon(icon1)
58
        self.redetectPushButton_2.setIconSize(QtCore.QSize(32, 32))
59
        self.redetectPushButton_2.setObjectName("redetectPushButton_2")
60
        self.gridLayout.addWidget(self.redetectPushButton_2, 0, 6, 1, 1)
57
        self.redetectPushButton.setIcon(icon1)
58
        self.redetectPushButton.setIconSize(QtCore.QSize(32, 32))
59
        self.redetectPushButton.setObjectName("redetectPushButton")
60
        self.gridLayout.addWidget(self.redetectPushButton, 0, 6, 1, 1)
61 61
        self.counterClockPushButton_2 = QtWidgets.QPushButton(self.topWidget)
62 62
        self.counterClockPushButton_2.setMinimumSize(QtCore.QSize(0, 60))
63 63
        self.counterClockPushButton_2.setMaximumSize(QtCore.QSize(60, 60))
DTI_PID/DTI_PID/QtImageViewer.py
66 66
        self.command = None
67 67
        self.scene = QtImageViewerScene(self)
68 68
        self.setScene(self.scene)
69
        # self.scene.setBackgroundBrush(Qt.lightGray)
70 69

  
71 70
        self.scaleFactor = 1.0
72 71
        self.numScheduledScalings = 0
DTI_PID/DTI_PID/Shapes/EngineeringTextItem.py
140 140
    def center(self):
141 141
        return self.sceneBoundingRect().center()
142 142

  
143
    def boundingRect(self):
143
    @property
144
    def text_size(self):
144 145
        if self.angle == 1.57 or self.angle == 4.71:
145 146
            return QRectF(0, 0, self.size[1], self.size[0])
146 147
        else:
147 148
            return QRectF(0, 0, self.size[0], self.size[1])
148 149

  
150
    def boundingRect(self) -> QRectF:
151
        return self.text_size
152

  
149 153
    '''
150 154
        @brief      hover event
151 155
        @authro     humkyung
......
187 191
    '''
188 192

  
189 193
    def keyPressEvent(self, event):
194
        import math
195

  
190 196
        if Qt.Key_Return == event.key():
191 197
            self.edit_text()
192 198
        elif event.key() == Qt.Key_R:
......
212 218
            modifiers = QApplication.keyboardModifiers()
213 219
            delta = 10 if modifiers == Qt.ControlModifier else 1
214 220

  
221
            trans = QTransform()
222
            trans.rotateRadians(self.angle)
223
            dx, dy = trans.map(0, -1)
215 224
            self.loc[1] = self.loc[1] - delta
216
            self.rotate()
225

  
226
            trans = self.transform()
227
            trans.translate(dx*delta, dy*delta)
228
            self.setTransform(trans)
217 229
        elif event.key() == Qt.Key_Down:
218 230
            modifiers = QApplication.keyboardModifiers()
219 231
            delta = 10 if modifiers == Qt.ControlModifier else 1
220 232

  
233
            trans = QTransform()
234
            trans.rotateRadians(self.angle)
235
            dx, dy = trans.map(0, 1)
221 236
            self.loc[1] = self.loc[1] + delta
222
            self.rotate()
237

  
238
            trans = self.transform()
239
            trans.translate(dx * delta, dy * delta)
240
            self.setTransform(trans)
223 241
        elif event.key() == Qt.Key_Left:
224 242
            modifiers = QApplication.keyboardModifiers()
225 243
            delta = 10 if modifiers == Qt.ControlModifier else 1
226 244

  
245
            trans = QTransform()
246
            trans.rotateRadians(self.angle)
247
            dx, dy = trans.map(-1, 0)
227 248
            self.loc[0] = self.loc[0] - delta
228
            self.rotate()
249

  
250
            trans = self.transform()
251
            trans.translate(dx * delta, dy * delta)
252
            self.setTransform(trans)
229 253
        elif event.key() == Qt.Key_Right:
230 254
            modifiers = QApplication.keyboardModifiers()
231 255
            delta = 10 if modifiers == Qt.ControlModifier else 1
232 256

  
257
            trans = QTransform()
258
            trans.rotateRadians(self.angle)
259
            dx, dy = trans.map(1, 0)
233 260
            self.loc[0] = self.loc[0] + delta
234
            self.rotate()
261

  
262
            trans = self.transform()
263
            trans.translate(dx * delta, dy * delta)
264
            self.setTransform(trans)
235 265

  
236 266
        # QGraphicsTextItem.keyPressEvent(self, event)
237 267

  
......
248 278
        hilightColor = QColor(255, 0, 0, 127)
249 279
        painter.setBrush(QBrush(hilightColor))
250 280
        painter.setPen(self.focuspen)
251
        painter.drawRect(self.boundingRect())
281
        painter.drawRect(self.text_size)
252 282

  
253 283
    '''
254 284
        @brief  override paint(draw connection points)
......
274 304
            if not configs or not int(configs[0].value) != 1:
275 305
                painter.setPen(Qt.NoPen)
276 306
                painter.setBrush(Qt.white)
277
                painter.drawRect(self.boundingRect())
307
                painter.drawRect(self.text_size)
278 308
        # up to here
279 309

  
280 310
        painter.setPen(QPen(color))
......
282 312
        if self.isSelected():
283 313
            self.drawFocusRect(painter)
284 314

  
315
        #painter.drawText(rect, Qt.AlignCenter, self.text())
285 316
        QGraphicsTextItem.paint(self, painter, options, widget)
286 317

  
287 318
    '''
......
291 322
    '''
292 323

  
293 324
    def boundingRectOnScene(self):
294
        rect = self.boundingRect()
325
        rect = self.text_size
295 326
        rect.moveTo(self.loc[0], self.loc[1])
296 327
        return rect
297 328

  
......
374 405

  
375 406
        transform = QTransform()
376 407
        if (1.57 == self.angle) or (4.71 == self.angle):
377
            rect = self.boundingRect()
408
            rect = self.text_size
378 409
            sx = width / rect.height()
379 410
            sy = height / rect.width()
380 411

  
......
384 415
            transform.rotateRadians(-self.angle)
385 416
            transform.translate(-rect.width() * 0.5, -rect.height() * 0.5)
386 417
        elif 3.14 == self.angle:
387
            rect = self.boundingRect()
418
            rect = self.text_size
388 419
            sx = width / rect.width()
389 420
            sy = height / rect.height()
390 421

  
......
393 424
            transform.rotateRadians(-self.angle)
394 425
            transform.translate(-width * 0.5, -height * 0.5)
395 426
        else:
396
            rect = self.boundingRect()
427
            rect = self.text_size
397 428
            sx = width / rect.width()
398 429
            sy = height / rect.height()
399 430

  
......
404 435
        self.setTransform(transform)
405 436
        self.update()
406 437

  
438
    def text_width(self, font):
439
        """return text width"""
440
        text_width = 0
441
        for _text in self.text().split('\n'):
442
            """
443
            rect = QFontMetricsF(font).tightBoundingRect(_text)
444
            text_width = max(rect.width(), text_width)
445
            """
446
            text_width = max(QFontMetricsF(font).width(_text), text_width)
447

  
448
        return text_width
449

  
407 450
    def update_shape(self):
408 451
        """update text shape"""
409 452

  
......
438 481
                font = QFont(fontName, width if fontSize == -1 else fontSize)
439 482
                font.setBold(True)
440 483

  
441
                x_factor = width / QFontMetricsF(font).height()
442
                y_factor = height / (QFontMetricsF(font).width(self.text()) / line_count)
484
                x_factor = width / QFontMetricsF(font).height() #self.text()).height() / line_count)
485
                y_factor = height / self.text_width(font)
443 486
                factor = min(x_factor, y_factor)
444 487
                font.setPointSizeF(font.pointSizeF() * factor)
445

  
446 488
                self.setFont(font)
447
                rect = self.boundingRect()
448
                sx = rect.height() / QFontMetricsF(font).height()
449
                text_width = (QFontMetricsF(font).width(self.text()) / line_count)
450
                sy = rect.width() / text_width
489

  
490
                rect = self.text_size
491
                sx = rect.height() / QFontMetricsF(font).tightBoundingRect(self.text()).height()
492
                sy = rect.width() / self.text_width(font)
451 493

  
452 494
                transform.translate(x + width * 0.5, y + height * 0.5)
453 495
                transform.rotateRadians(-self.angle)
454
                transform.scale(1, sy)
496
                #transform.scale(1, sy)
455 497
                transform.translate(-rect.width() * 0.5, -rect.height() * 0.5)
456 498
            elif abs(self.angle - 3.14) < allowed_error:
457 499
                font = QFont(fontName, height if fontSize == -1 else fontSize)
458 500
                font.setBold(True)
459 501

  
460
                x_factor = width / (QFontMetricsF(font).width(self.text()) / line_count)
461
                y_factor = height / QFontMetricsF(font).height()
502
                x_factor = width / self.text_width(font)
503
                y_factor = height / QFontMetricsF(font).height() #self.text()).height() / line_count)
462 504
                factor = min(x_factor, y_factor)
463 505
                font.setPointSizeF(font.pointSizeF() * factor)
464

  
465 506
                self.setFont(font)
466
                rect = self.boundingRect()
467
                sx = width / (QFontMetricsF(font).width(self.text()) / line_count)
468
                sy = height / rect.height()
507

  
508
                rect = self.text_size
509
                sx = width / self.text_width(font)
510
                sy = height / QFontMetricsF(font).tightBoundingRect(self.text()).height()
469 511

  
470 512
                transform.translate(x, y - round((rect.height() - height) * 0.5))
471
                transform.scale(sx, 1)
513
                #transform.scale(sx, 1)
472 514
                transform.rotateRadians(-self.angle)
473 515
                transform.translate(-width * 0.5, -height * 0.5)
474 516
            else:
475 517
                font = QFont(fontName, height if fontSize == -1 else fontSize)
476 518
                font.setBold(True)
477 519

  
478
                x_factor = width / (QFontMetricsF(font).width(self.text()) / line_count)
479
                y_factor = height / QFontMetricsF(font).height()
520
                x_factor = width / self.text_width(font)
521
                y_factor = height / QFontMetricsF(font).height() #.boun(self.text()).height() / line_count)
480 522
                factor = min(x_factor, y_factor)
481 523
                font.setPointSizeF(font.pointSizeF() * factor)
482

  
483 524
                self.setFont(font)
484 525

  
485
                text_width = (QFontMetricsF(font).width(self.text()) / line_count)
486
                sx = width / text_width
487
                sy = height / QFontMetricsF(font).height()
526
                sx = width / self.text_width(font)
527
                sy = height / QFontMetricsF(font).tightBoundingRect(self.text()).height()
488 528

  
489 529
                transform.translate(x, y)
490
                #transform.scale(sx, 1)
491 530

  
492 531
            self.setTransform(transform)
493 532

  
DTI_PID/DTI_PID/UI/OcrResultDialog.ui
80 80
            </widget>
81 81
           </item>
82 82
           <item row="0" column="6">
83
            <widget class="QPushButton" name="redetectPushButton_2">
83
            <widget class="QPushButton" name="redetectPushButton">
84 84
             <property name="minimumSize">
85 85
              <size>
86 86
               <width>0</width>

내보내기 Unified diff

클립보드 이미지 추가 (최대 크기: 500 MB)