diff --git a/PPOCRLabel/PPOCRLabel.py b/PPOCRLabel/PPOCRLabel.py index a2906e71756e4f4cdd1d254c693b2cce70fe8b15..b9f35aa352d5be3a77de693a6f3c1acf7469ac41 100644 --- a/PPOCRLabel/PPOCRLabel.py +++ b/PPOCRLabel/PPOCRLabel.py @@ -382,7 +382,7 @@ class MainWindow(QMainWindow): 'w', 'objects', getStr('crtBoxDetail'), enabled=False) delete = action(getStr('delBox'), self.deleteSelectedShape, - 'Alt+X', 'delete', getStr('delBoxDetail'), enabled=False) + 'backspace', 'delete', getStr('delBoxDetail'), enabled=False) copy = action(getStr('dupBox'), self.copySelectedShape, 'Ctrl+C', 'copy', getStr('dupBoxDetail'), @@ -1939,6 +1939,38 @@ class MainWindow(QMainWindow): owidth += itemwidget.width() self.iconlist.setMinimumWidth(owidth + 50) + def gen_quad_from_poly(self, poly): + """ + Generate min area quad from poly. + """ + point_num = poly.shape[0] + min_area_quad = np.zeros((4, 2), dtype=np.float32) + rect = cv2.minAreaRect(poly.astype( + np.int32)) # (center (x,y), (width, height), angle of rotation) + box = np.array(cv2.boxPoints(rect)) + + first_point_idx = 0 + min_dist = 1e4 + for i in range(4): + dist = np.linalg.norm(box[(i + 0) % 4] - poly[0]) + \ + np.linalg.norm(box[(i + 1) % 4] - poly[point_num // 2 - 1]) + \ + np.linalg.norm(box[(i + 2) % 4] - poly[point_num // 2]) + \ + np.linalg.norm(box[(i + 3) % 4] - poly[-1]) + if dist < min_dist: + min_dist = dist + first_point_idx = i + for i in range(4): + min_area_quad[i] = box[(first_point_idx + i) % 4] + + bbox_new = min_area_quad.tolist() + bbox = [] + + for box in bbox_new: + box = list(map(int, box)) + bbox.append(box) + + return bbox + def getImglabelidx(self, filePath): if platform.system() == 'Windows': spliter = '\\' @@ -1973,7 +2005,11 @@ class MainWindow(QMainWindow): rec_flag = 0 for shape in self.canvas.shapes: box = [[int(p.x()), int(p.y())] for p in shape.points] + + if len(box) > 4: + box = self.gen_quad_from_poly(np.array(box)) assert len(box) == 4 + img_crop = get_rotate_crop_image(img, np.array(box, np.float32)) if img_crop is None: msg = 'Can not recognise the detection box in ' + self.filePath + '. Please change manually' @@ -2022,6 +2058,8 @@ class MainWindow(QMainWindow): img = cv2.imread(self.filePath) for shape in self.canvas.selectedShapes: box = [[int(p.x()), int(p.y())] for p in shape.points] + if len(box) > 4: + box = self.gen_quad_from_poly(np.array(box)) assert len(box) == 4 img_crop = get_rotate_crop_image(img, np.array(box, np.float32)) if img_crop is None: diff --git a/PPOCRLabel/README.md b/PPOCRLabel/README.md index 61ebbe926c0a1c9c2922d0f3070e2c39f884e68e..21db1867aa6b6504595096de56b17f01dbf3e4f6 100644 --- a/PPOCRLabel/README.md +++ b/PPOCRLabel/README.md @@ -170,7 +170,7 @@ python PPOCRLabel.py --kie True # [KIE mode] for [detection + recognition + keyw | Ctrl + R | Re-recognize the selected box | | Ctrl + C | Copy and paste the selected box | | Ctrl + Left Mouse Button | Multi select the label box | -| Alt + X | Delete the selected box | +| Backspace | Delete the selected box | | Ctrl + V | Check image | | Ctrl + Shift + d | Delete image | | D | Next image | diff --git a/PPOCRLabel/README_ch.md b/PPOCRLabel/README_ch.md index 18ffea53f95869d2fa65159ab934a55b662d6f5b..9bf898fd79b6b1642ce20fabda3009708473c354 100644 --- a/PPOCRLabel/README_ch.md +++ b/PPOCRLabel/README_ch.md @@ -159,7 +159,7 @@ python PPOCRLabel.py --lang ch --kie True # 启动 【KIE 模式】,用于打 | Ctrl + R | 重新识别所选标记 | | Ctrl + C | 复制并粘贴选中的标记框 | | Ctrl + 鼠标左键 | 多选标记框 | -| Alt + X | 删除所选框 | +| Backspace | 删除所选框 | | Ctrl + V | 确认本张图片标记 | | Ctrl + Shift + d | 删除本张图片 | | D | 下一张图片 | @@ -168,6 +168,7 @@ python PPOCRLabel.py --lang ch --kie True # 启动 【KIE 模式】,用于打 | Ctrl-- | 放大 | | ↑→↓← | 移动标记框 | + ### 3.2 内置模型 - 默认模型:PPOCRLabel默认使用PaddleOCR中的中英文超轻量OCR模型,支持中英文与数字识别,多种语言检测。 diff --git a/PPOCRLabel/libs/canvas.py b/PPOCRLabel/libs/canvas.py index db1071e9b73486d9ca1e6da2f711a0ebf3aa160a..e6cddf13ede235fa193daf84d4395d77c371049a 100644 --- a/PPOCRLabel/libs/canvas.py +++ b/PPOCRLabel/libs/canvas.py @@ -263,7 +263,7 @@ class Canvas(QWidget): if self.current.isClosed(): # print('1111') self.finalise() - elif self.drawSquare: # 增加 + elif self.drawSquare: assert len(self.current.points) == 1 self.current.points = self.line.points self.finalise() diff --git a/PPOCRLabel/libs/shape.py b/PPOCRLabel/libs/shape.py index fc8ab5ec4d7ff2836034d9c7e01acaf49dfe7aa0..18cc4a8e7692c2a88becca2e9ca19dfebbd61779 100644 --- a/PPOCRLabel/libs/shape.py +++ b/PPOCRLabel/libs/shape.py @@ -57,6 +57,7 @@ class Shape(object): self.locked = False self.direction = 0 self.center = None + self.epsilon = 5 # same as canvas self._highlightIndex = None self._highlightMode = self.NEAR_VERTEX self._highlightSettings = { @@ -98,11 +99,14 @@ class Shape(object): return False def addPoint(self, point): - if self.reachMaxPoints(): + if self.reachMaxPoints() and self.closeEnough(self.points[0], point): self.close() else: self.points.append(point) + def closeEnough(self, p1, p2): + return distance(p1 - p2) < self.epsilon + def popPoint(self): if self.points: return self.points.pop()