Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 22 additions & 3 deletions fastlabel/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1142,24 +1142,39 @@ def __export_index_color_image(self, task: list, output_dir: str, pallete: List[
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

index = 1
# In case segmentation, to avoid hollowed points overwrite other segmentation in them, segmentation rendering process is different from other annotation type
seg_mask_images = []
for annotation in task["annotations"]:
color = index if is_instance_segmentation else classes.index(
annotation["value"]) + 1
if annotation["type"] == AnnotationType.segmentation.value:
# Create each annotation's masks and merge them finally
seg_mask_ground = Image.new(
"RGB", (task["width"], task["height"]), 0)
seg_mask_image = np.array(seg_mask_ground)
seg_mask_image = cv2.cvtColor(seg_mask_image, cv2.COLOR_BGR2GRAY)

for region in annotation["points"]:
count = 0
for points in region:
if count == 0:
cv_draw_points = self.__get_cv_draw_points(points)
cv_draw_points = []
if utils.is_clockwise(points):
cv_draw_points = self.__get_cv_draw_points(
points)
else:
cv_draw_points = self.__get_cv_draw_points(
utils.reverse_points(points))
cv2.fillPoly(
image, [cv_draw_points], color, lineType=cv2.LINE_8, shift=0)
seg_mask_image, [cv_draw_points], color, lineType=cv2.LINE_8, shift=0)
else:
# Reverse hollow points for opencv because this points are counter clockwise
cv_draw_points = self.__get_cv_draw_points(
utils.reverse_points(points))
cv2.fillPoly(
image, [cv_draw_points], 0, lineType=cv2.LINE_8, shift=0)
seg_mask_image, [cv_draw_points], 0, lineType=cv2.LINE_8, shift=0)
count += 1
seg_mask_images.append(seg_mask_image)
elif annotation["type"] == AnnotationType.polygon.value:
cv_draw_points = self.__get_cv_draw_points(
annotation["points"])
Expand All @@ -1174,6 +1189,10 @@ def __export_index_color_image(self, task: list, output_dir: str, pallete: List[
continue
index += 1

# For segmentation, merge each mask images
for seg_mask_image in seg_mask_images:
image = image | seg_mask_image

image_path = os.path.join(
output_dir, utils.get_basename(task["name"]) + ".png")
os.makedirs(os.path.dirname(image_path), exist_ok=True)
Expand Down
25 changes: 25 additions & 0 deletions fastlabel/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import os
import base64
import numpy as np
import geojson
from typing import List


Expand Down Expand Up @@ -41,3 +43,26 @@ def reverse_points(points: List[int]) -> List[int]:
reversed_points.insert(
0, points[index])
return reversed_points

def is_clockwise(points: list) -> bool:
"""
points: [x1, y1, x2, y2, x3, y3, ... xn, yn]
Sum over the edges, (x2 − x1)(y2 + y1).
If the result is positive the curve is clockwise, if it's negative the curve is counter-clockwise.

The above is assumes a normal Cartesian coordinate system.
HTML5 canvas, use an inverted Y-axis.
Therefore If the area is negative, the curve is clockwise.
"""
points_splitted = [points[idx:idx + 2]
for idx in range(0, len(points), 2)]
polygon_geo = geojson.Polygon(points_splitted)
coords = np.array(list(geojson.utils.coords(polygon_geo)))
xs, ys = map(list, zip(*coords))
xs.append(xs[0])
ys.append(ys[0])
sum_edges = sum((xs[i] - xs[i - 1]) * (ys[i] + ys[i - 1]) for i in range(1, len(points_splitted))) / 2.0

if sum_edges < 0:
return True
return False
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

setuptools.setup(
name="fastlabel",
version="0.11.8",
version="0.11.9",
author="eisuke-ueta",
author_email="eisuke.ueta@fastlabel.ai",
description="The official Python SDK for FastLabel API, the Data Platform for AI",
Expand Down