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
47 changes: 30 additions & 17 deletions fastlabel/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,8 @@ def create_video_classification_task(
"""
endpoint = "tasks/video/classification"
if not utils.is_video_supported_ext(file_path):
raise FastLabelInvalidException("Supported extensions are mp4.", 422)
raise FastLabelInvalidException(
"Supported extensions are mp4.", 422)
file = utils.base64_encode(file_path)
payload = {"project": project, "name": name, "file": file}
if status:
Expand Down Expand Up @@ -712,12 +713,12 @@ def export_labelme(self, tasks: list, output_dir: str = os.path.join("output", "
with open(file_path, 'w') as f:
json.dump(labelme, f, indent=4, ensure_ascii=False)


# Instance / Semantic Segmetation

def export_instance_segmentation(self, tasks: list, output_dir: str = os.path.join("output", "instance_segmentation"), pallete: List[int] = const.COLOR_PALETTE) -> None:
"""
Convert tasks to index color instance segmentation (PNG files).
Supports only bbox, polygon and segmentation annotation types. Hollowed points are not supported.
Supports only bbox, polygon and segmentation annotation types.
Supports up to 57 instances in default colors palette. Check const.COLOR_PALETTE for more details.

tasks is a list of tasks. (Required)
Expand All @@ -726,12 +727,13 @@ def export_instance_segmentation(self, tasks: list, output_dir: str = os.path.jo
"""
tasks = converters.to_pixel_coordinates(tasks)
for task in tasks:
self.__export_index_color_image(task=task, output_dir=output_dir, pallete=pallete, is_instance_segmentation=True)

self.__export_index_color_image(
task=task, output_dir=output_dir, pallete=pallete, is_instance_segmentation=True)

def export_semantic_segmentation(self, tasks: list, output_dir: str = os.path.join("output", "semantic_segmentation"), pallete: List[int] = const.COLOR_PALETTE) -> None:
"""
Convert tasks to index color semantic segmentation (PNG files).
Supports only bbox, polygon and segmentation annotation types. Hollowed points are not supported.
Supports only bbox, polygon and segmentation annotation types.
Check const.COLOR_PALETTE for color pallete.

tasks is a list of tasks. (Required)
Expand All @@ -747,7 +749,8 @@ def export_semantic_segmentation(self, tasks: list, output_dir: str = os.path.jo

tasks = converters.to_pixel_coordinates(tasks)
for task in tasks:
self.__export_index_color_image(task=task, output_dir=output_dir, pallete=pallete, is_instance_segmentation=False, classes=classes)
self.__export_index_color_image(
task=task, output_dir=output_dir, pallete=pallete, is_instance_segmentation=False, classes=classes)

def __export_index_color_image(self, task: list, output_dir: str, pallete: List[int], is_instance_segmentation: bool = True, classes: list = []) -> None:
image = Image.new("RGB", (task["width"], task["height"]), 0)
Expand All @@ -756,28 +759,39 @@ def __export_index_color_image(self, task: list, output_dir: str, pallete: List[

index = 1
for annotation in task["annotations"]:
color = index if is_instance_segmentation else classes.index(annotation["value"]) + 1
color = index if is_instance_segmentation else classes.index(
annotation["value"]) + 1
if annotation["type"] == AnnotationType.segmentation.value:
for region in annotation["points"]:
count = 0
for points in region:
cv_draw_points = self.__get_cv_draw_points(points)
if count == 0:
cv2.fillPoly(image, [cv_draw_points], color, lineType=cv2.LINE_8, shift=0)
cv_draw_points = self.__get_cv_draw_points(points)
cv2.fillPoly(
image, [cv_draw_points], color, lineType=cv2.LINE_8, shift=0)
else:
cv2.fillPoly(image, [cv_draw_points], 0, lineType=cv2.LINE_8, shift=0)
# 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)
Comment on lines +773 to +777
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

主な変更箇所

count += 1
elif annotation["type"] == AnnotationType.polygon.value:
cv_draw_points = self.__get_cv_draw_points(annotation["points"])
cv2.fillPoly(image, [cv_draw_points], color, lineType=cv2.LINE_8, shift=0)
cv_draw_points = self.__get_cv_draw_points(
annotation["points"])
cv2.fillPoly(image, [cv_draw_points], color,
lineType=cv2.LINE_8, shift=0)
elif annotation["type"] == AnnotationType.bbox.value:
cv_draw_points = self.__get_cv_draw_points(annotation["points"])
cv2.fillPoly(image, [cv_draw_points], color, lineType=cv2.LINE_8, shift=0)
cv_draw_points = self.__get_cv_draw_points(
annotation["points"])
cv2.fillPoly(image, [cv_draw_points], color,
lineType=cv2.LINE_8, shift=0)
else:
continue
index += 1

image_path = os.path.join(output_dir, utils.get_basename(task["name"]) + ".png")
image_path = os.path.join(
output_dir, utils.get_basename(task["name"]) + ".png")
os.makedirs(os.path.dirname(image_path), exist_ok=True)
image = Image.fromarray(image)
image = image.convert('P')
Expand Down Expand Up @@ -826,7 +840,6 @@ def __get_cv_draw_points(self, points: List[int]) -> List[int]:
cv_points.append((new_points[i * 2], new_points[i * 2 + 1]))
return np.array(cv_points)


# Annotation

def find_annotation(self, annotation_id: str) -> dict:
Expand Down
15 changes: 15 additions & 0 deletions fastlabel/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,18 @@ def get_basename(file_path: str) -> str:
path/to/file.jpg -> path/to/file
"""
return os.path.splitext(file_path)[0]


def reverse_points(points: list[int]) -> list[int]:
"""
e.g.)
[4, 5, 4, 9, 8, 9, 8, 5, 4, 5] => [4, 5, 8, 5, 8, 9, 4, 9, 4, 5]
"""
reversed_points = []
for index, _ in enumerate(points):
if index % 2 == 0:
reversed_points.insert(
0, points[index + 1])
reversed_points.insert(
0, points[index])
return reversed_points