Skip to content

Commit a76722b

Browse files
authored
Prevent incorrect projection (#334)
1 parent e192e9b commit a76722b

File tree

2 files changed

+112
-3
lines changed

2 files changed

+112
-3
lines changed

backend/requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ pytest-ordering==0.6
1616
imantics==0.1.9
1717
flask-socketio==3.3.2
1818
celery==4.2.2
19-
19+
Shapely==1.7.0
2020
scipy
2121
Pillow
2222
matplotlib

backend/webserver/util/coco_util.py

Lines changed: 111 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import pycocotools.mask as mask
22
import numpy as np
3+
import shapely
4+
from shapely.geometry import LineString, Point
35

46
from database import (
57
fix_ids,
@@ -48,8 +50,8 @@ def paperjs_to_coco(image_width, image_height, paperjs):
4850

4951
# Point
5052
if len(point) == 2:
51-
x = _fit(round(center[0] + point[0], 2), image_width, 0)
52-
y = _fit(round(center[1] + point[1], 2), image_height, 0)
53+
x = round(center[0] + point[0], 2)
54+
y = round(center[1] + point[1], 2)
5355
segments_to_add.extend([x, y])
5456

5557
# Make sure shape is not all outside the image
@@ -78,6 +80,113 @@ def paperjs_to_coco(image_width, image_height, paperjs):
7880
return segments, area, bbox
7981

8082

83+
def paperjs_to_coco_cliptobounds(image_width, image_height, paperjs): # todo: there's lots of edge cases to this. It needs a different solution or many many if statements :P
84+
"""
85+
Given a paperjs CompoundPath, converts path into coco segmentation format based on children paths
86+
87+
:param image_width: Width of Image
88+
:param image_height: Height of Image
89+
:param paperjs: paperjs CompoundPath in dict format
90+
:return: segmentation, area, bbox
91+
"""
92+
assert image_width > 0
93+
assert image_height > 0
94+
assert len(paperjs) == 2
95+
96+
# Compute segmentation
97+
# paperjs points are relative to the center, so we must shift them relative to the top left.
98+
segments = []
99+
center = [image_width/2, image_height/2]
100+
101+
if paperjs[0] == "Path":
102+
compound_path = {"children": [paperjs]}
103+
else:
104+
compound_path = paperjs[1]
105+
106+
children = compound_path.get('children', [])
107+
108+
for child in children:
109+
110+
child_segments = child[1].get('segments', [])
111+
segments_to_add = []
112+
113+
114+
i_start = 0
115+
inside = False
116+
# find a point that's inside the canvas
117+
while(i_start < len(child_segments)):
118+
point = child_segments[i_start]
119+
if len(point) == 4: point = point[0] # curve
120+
if len(point) == 2: # point
121+
if (abs(point[0]) > image_width/2 or point[1] > image_height/2):
122+
i_start += 1
123+
continue
124+
inside = True
125+
break
126+
i_start += 1
127+
128+
if inside: # if point is inside the canvas. Otherwise ignore it
129+
edges = {
130+
'w_0': np.array([[0,0],[image_width, 0]], np.float),
131+
'w_1': np.array([[0,image_height],[image_width, image_height]], np.float),
132+
'h_0': np.array([[0,0],[0, image_height]], np.float),
133+
'h_1': np.array([[image_width,0],[image_width, image_height]], np.float),
134+
}
135+
prev_point = None
136+
for i in range(i_start, i_start + len(child_segments)):
137+
p = i % len(child_segments)
138+
point = child_segments[p]
139+
140+
# print('point:', point, flush=True)
141+
# Cruve
142+
if len(point) == 4:
143+
point = point[0]
144+
145+
# Point
146+
if len(point) == 2:
147+
x = round(center[0] + point[0], 2)
148+
y = round(center[1] + point[1], 2)
149+
x_orig, y_orig = x,y
150+
point_outside = x > image_width or x < 0 or y > image_height or y < 0
151+
# prev_point_outside = prev_point[0] > image_width or prev_point[0] < 0 or prev_point[1] > image_height or prev_point[1] < 0
152+
if point_outside: # outside canvas
153+
line = LineString([[x,y], prev_point])
154+
for _, edge in edges.items():
155+
intersect = line.intersection(LineString(edge))
156+
if not intersect.is_empty:
157+
if intersect.type == 'LineString': intersect = intersect.xy[0]
158+
else: intersect = [intersect.x, intersect.y]
159+
print(x,y, prev_point)
160+
print(intersect, flush=True)
161+
x,y = intersect
162+
break
163+
segments_to_add.extend([x, y])
164+
prev_point = [x_orig,y_orig]
165+
# Make sure shape is not all outside the image
166+
if sum(segments_to_add) == 0:
167+
continue
168+
169+
if len(segments_to_add) == 4:
170+
# len 4 means this is a line with no width; it contributes
171+
# no area to the mask, and if we include it, coco will treat
172+
# it instead as a bbox (and throw an error)
173+
continue
174+
175+
num_widths = segments_to_add.count(image_width)
176+
num_heights = segments_to_add.count(image_height)
177+
if num_widths + num_heights == len(segments_to_add):
178+
continue
179+
180+
segments.append(segments_to_add)
181+
182+
if len(segments) < 1:
183+
return [], 0, [0, 0, 0, 0]
184+
185+
area, bbox = get_segmentation_area_and_bbox(
186+
segments, image_height, image_width)
187+
188+
return segments, area, bbox
189+
81190
def get_segmentation_area_and_bbox(segmentation, image_height, image_width):
82191
# Convert into rle
83192
rles = mask.frPyObjects(segmentation, image_height, image_width)

0 commit comments

Comments
 (0)