Skip to content
Merged
22 changes: 12 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2069,14 +2069,15 @@ Support the following annotation types.
Get tasks and export as a [COCO format](https://cocodataset.org/#format-data) file.

```python
tasks = client.get_image_tasks(project="YOUR_PROJECT_SLUG")
client.export_coco(tasks)
project_slug = "YOUR_PROJECT_SLUG"
tasks = client.get_image_tasks(project=project_slug)
client.export_coco(project=project_slug, tasks=tasks)
```

Export with specifying output directory and file name.

```python
client.export_coco(tasks=tasks, output_dir="YOUR_DIRECTROY", output_file_name="YOUR_FILE_NAME")
client.export_coco(project="YOUR_PROJECT_SLUG", tasks=tasks, output_dir="YOUR_DIRECTROY", output_file_name="YOUR_FILE_NAME")
```

If you would like to export pose estimation type annotations, please pass annotations.
Expand All @@ -2085,7 +2086,7 @@ If you would like to export pose estimation type annotations, please pass annota
project_slug = "YOUR_PROJECT_SLUG"
tasks = client.get_image_tasks(project=project_slug)
annotations = client.get_annotations(project=project_slug)
client.export_coco(tasks=tasks, annotations=annotations, output_dir="YOUR_DIRECTROY", output_file_name="YOUR_FILE_NAME")
client.export_coco(project=project_slug, tasks=tasks, annotations=annotations, output_dir="YOUR_DIRECTROY", output_file_name="YOUR_FILE_NAME")
```

### FastLabel To YOLO
Expand All @@ -2098,8 +2099,9 @@ Support the following annotation types.
Get tasks and export as YOLO format files.

```python
tasks = client.get_image_tasks(project="YOUR_PROJECT_SLUG")
client.export_yolo(tasks, output_dir="YOUR_DIRECTROY")
project_slug = "YOUR_PROJECT_SLUG"
tasks = client.get_image_tasks(project=project_slug)
client.export_yolo(project=project_slug, tasks=tasks, output_dir="YOUR_DIRECTROY")
```

Get tasks and export as YOLO format files with classes.txt
Expand All @@ -2110,7 +2112,7 @@ project_slug = "YOUR_PROJECT_SLUG"
tasks = client.get_image_tasks(project=project_slug)
annotations = client.get_annotations(project=project_slug)
classes = list(map(lambda annotation: annotation["value"], annotations))
client.export_yolo(tasks=tasks, classes=classes, output_dir="YOUR_DIRECTROY")
client.export_yolo(project=project_slug, tasks=tasks, classes=classes, output_dir="YOUR_DIRECTROY")
```

### FastLabel To Pascal VOC
Expand All @@ -2123,8 +2125,9 @@ Support the following annotation types.
Get tasks and export as Pascal VOC format files.

```python
tasks = client.get_image_tasks(project="YOUR_PROJECT_SLUG")
client.export_pascalvoc(tasks)
project_slug = "YOUR_PROJECT_SLUG"
tasks = client.get_image_tasks(project=project_slug)
client.export_pascalvoc(project=project_slug, tasks=tasks)
```

### FastLabel To labelme
Expand Down Expand Up @@ -2388,7 +2391,6 @@ for image_file_path in glob.iglob(os.path.join(input_dataset_path, "**/**.jpg"),

> Please check const.COLOR_PALLETE for index colors.


## Execute endpoint

Create the endpoint from the screen at first.
Expand Down
63 changes: 55 additions & 8 deletions fastlabel/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2120,6 +2120,7 @@ def __get_yolo_format_annotations(self, dataset_folder_path: str) -> dict:

def export_coco(
self,
project: str,
Copy link
Contributor Author

@fuji44 fuji44 Mar 6, 2023

Choose a reason for hiding this comment

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

タスクを動画と画像のいずれで処理すべきかを判断するために、プロジェクトタイプを用いることにしました。

そのため、SDK利用者に新たにプロジェクトスラグを指定してもらうようにしました。

Copy link
Contributor

Choose a reason for hiding this comment

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

こちら今後project_slugが必須になると思うので、READMEの方もそれに合わせて変えておいてもらえると助かります!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

READMEを修正しました!

tasks: list,
annotations: list = [],
output_dir: str = os.path.join("output", "coco"),
Expand All @@ -2129,6 +2130,7 @@ def export_coco(
Convert tasks to COCO format and export as a file.
If you pass annotations, you can export Pose Estimation type annotations.

project is slug of your project (Required).
tasks is a list of tasks (Required).
annotations is a list of annotations (Optional).
output_dir is output directory(default: output/coco) (Optional).
Expand All @@ -2138,14 +2140,27 @@ def export_coco(
raise FastLabelInvalidException(
"Output file name must have a json extension", 422
)
coco = converters.to_coco(tasks, annotations)

project = self.find_project_by_slug(project)
if project is None:
raise FastLabelInvalidException(
"Project not found. Check the project slag.", 422
)

os.makedirs(output_dir, exist_ok=True)
coco = converters.to_coco(
project_type=project["type"],
tasks=tasks,
annotations=annotations,
output_dir=output_dir,
)
file_path = os.path.join(output_dir, output_file_name)
with open(file_path, "w") as f:
json.dump(coco, f, indent=4, ensure_ascii=False)

def export_yolo(
self,
project: str,
tasks: list,
classes: list = [],
output_dir: str = os.path.join("output", "yolo"),
Expand All @@ -2156,43 +2171,75 @@ def export_yolo(
If not , classes.txt will be generated based on passed tasks .
(Annotations never used in your project will not be exported.)

project is slug of your project (Required).
tasks is a list of tasks (Required).
classes is a list of annotation values. e.g. ['dog','bird'] (Optional).
output_dir is output directory(default: output/yolo) (Optional).
"""
annos, categories = converters.to_yolo(tasks, classes)

project = self.find_project_by_slug(project)
if project is None:
raise FastLabelInvalidException(
"Project not found. Check the project slag.", 422
)

os.makedirs(output_dir, exist_ok=True)
annos, categories = converters.to_yolo(
project_type=project["type"],
tasks=tasks,
classes=classes,
output_dir=output_dir,
)
for anno in annos:
file_name = anno["filename"]
basename = utils.get_basename(file_name)
file_path = os.path.join(output_dir, "annotations", basename + ".txt")
os.makedirs(os.path.dirname(file_path), exist_ok=True)
with open(file_path, "w", encoding="utf8") as f:
for obj in anno["object"]:
objects = anno.get("object")
if objects is None:
continue
for obj in objects:
f.write(obj)
f.write("\n")
classes_file_path = os.path.join(output_dir, "classes.txt")
os.makedirs(os.path.dirname(classes_file_path), exist_ok=True)
with open(classes_file_path, "w", encoding="utf8") as f:
for category in categories:
f.write(category["name"])
f.write("\n")

def export_pascalvoc(
self, tasks: list, output_dir: str = os.path.join("output", "pascalvoc")
self,
project: str,
tasks: list,
output_dir: str = os.path.join("output", "pascalvoc"),
) -> None:
"""
Convert tasks to Pascal VOC format as files.

project is slug of your project (Required).
tasks is a list of tasks (Required).
output_dir is output directory(default: output/pascalvoc) (Optional).
"""
pascalvoc = converters.to_pascalvoc(tasks)

project = self.find_project_by_slug(project)
if project is None:
raise FastLabelInvalidException(
"Project not found. Check the project slag.", 422
)

os.makedirs(output_dir, exist_ok=True)
pascalvoc = converters.to_pascalvoc(
project_type=project["type"], tasks=tasks, output_dir=output_dir
)
for voc in pascalvoc:
file_name = voc["annotation"]["filename"]
basename = utils.get_basename(file_name)
file_path = os.path.join(output_dir, basename + ".xml")
file_path = os.path.join(output_dir, "annotations", basename + ".xml")
os.makedirs(os.path.dirname(file_path), exist_ok=True)
xml = xmltodict.unparse(voc, pretty=True, full_document=False)
xml = xmltodict.unparse(
voc, pretty=True, indent=" ", full_document=False
)
with open(file_path, "w", encoding="utf8") as f:
f.write(xml)

Expand Down
Loading