Error with pyclipper inhomogeneous expanded array (#12108)

* pyclipper inhomogeneous expanded array solved

For some images, `np.array(offset.Execute(distance))` can result in inhomogeneous part of the detection box list, which cannot be casted into numpy array directly.

* corrected box reshape position

- box reshape was mistakenly done at line 145 which is now correctly done at line 92 of `db_postprocess.py`
- if box is empty then continue

* reverted mistakenly changed line 147

- reverted mistakenly changed `box.array(box)` to `np.array(box)`

* expanded array fix for `det_box_type=quad`

* polygons padding

For `--det_box_type = poly`, pad the detected polygon arrays if they have different shapes to ensure even shapes of polygon arrays

* fix codestyle

---------

Co-authored-by: Wang Xin <xinwang614@gmail.com>
pull/12140/head
Sanjay Rijal 2024-05-18 07:04:06 +05:45 committed by GitHub
parent 8b71785141
commit 502e1675e4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 23 additions and 3 deletions

View File

@ -89,7 +89,9 @@ class DBPostProcess(object):
continue
else:
continue
box = box.reshape(-1, 2)
box = np.array(box).reshape(-1, 2)
if len(box) == 0:
continue
_, sside = self.get_mini_boxes(box.reshape((-1, 1, 2)))
if sside < self.min_size + 2:
@ -138,7 +140,10 @@ class DBPostProcess(object):
if self.box_thresh > score:
continue
box = self.unclip(points, self.unclip_ratio).reshape(-1, 1, 2)
box = self.unclip(points, self.unclip_ratio)
if len(box) > 1:
continue
box = np.array(box).reshape(-1, 1, 2)
box, sside = self.get_mini_boxes(box)
if sside < self.min_size + 2:
continue
@ -157,7 +162,7 @@ class DBPostProcess(object):
distance = poly.area * unclip_ratio / poly.length
offset = pyclipper.PyclipperOffset()
offset.AddPath(box, pyclipper.JT_ROUND, pyclipper.ET_CLOSEDPOLYGON)
expanded = np.array(offset.Execute(distance))
expanded = offset.Execute(distance)
return expanded
def get_mini_boxes(self, contour):

View File

@ -179,6 +179,14 @@ class TextDetector(object):
rect[3] = tmp[np.argmax(diff)]
return rect
def pad_polygons(self, polygon, max_points):
padding_size = max_points - len(polygon)
if padding_size == 0:
return polygon
last_point = polygon[-1]
padding = np.repeat([last_point], padding_size, axis=0)
return np.vstack([polygon, padding])
def clip_det_res(self, points, img_height, img_width):
for pno in range(points.shape[0]):
points[pno, 0] = int(min(max(points[pno, 0], 0), img_width - 1))
@ -209,6 +217,13 @@ class TextDetector(object):
box = np.array(box)
box = self.clip_det_res(box, img_height, img_width)
dt_boxes_new.append(box)
if len(dt_boxes_new) > 0:
max_points = max(len(polygon) for polygon in dt_boxes_new)
dt_boxes_new = [
self.pad_polygons(polygon, max_points) for polygon in dt_boxes_new
]
dt_boxes = np.array(dt_boxes_new)
return dt_boxes