annofabcli 1.112.0__py3-none-any.whl → 1.113.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- annofabcli/annotation/change_annotation_attributes.py +1 -1
- annofabcli/annotation/change_annotation_attributes_per_annotation.py +1 -1
- annofabcli/annotation/change_annotation_properties.py +1 -1
- annofabcli/annotation/copy_annotation.py +1 -1
- annofabcli/annotation/create_classification_annotation.py +1 -1
- annofabcli/annotation/delete_annotation.py +1 -1
- annofabcli/annotation/dump_annotation.py +20 -13
- annofabcli/annotation/import_annotation.py +1 -1
- annofabcli/annotation/list_annotation.py +1 -1
- annofabcli/annotation/list_annotation_count.py +1 -1
- annofabcli/annotation/merge_segmentation.py +1 -1
- annofabcli/annotation/remove_segmentation_overlap.py +1 -1
- annofabcli/annotation/restore_annotation.py +1 -1
- annofabcli/annotation_specs/list_annotation_specs_history.py +1 -1
- annofabcli/annotation_zip/list_annotation_3d_bounding_box.py +8 -1
- annofabcli/annotation_zip/list_annotation_bounding_box_2d.py +26 -26
- annofabcli/annotation_zip/list_polygon_annotation.py +390 -0
- annofabcli/annotation_zip/list_polyline_annotation.py +402 -0
- annofabcli/annotation_zip/list_range_annotation.py +1 -1
- annofabcli/annotation_zip/list_single_point_annotation.py +14 -22
- annofabcli/annotation_zip/subcommand_annotation_zip.py +4 -0
- annofabcli/common/cli.py +1 -0
- annofabcli/filesystem/draw_annotation.py +1 -1
- annofabcli/filesystem/mask_user_info.py +1 -1
- annofabcli/filesystem/merge_annotation.py +1 -1
- annofabcli/input_data/delete_input_data.py +1 -1
- annofabcli/input_data/list_all_input_data.py +1 -1
- annofabcli/input_data/list_all_input_data_merged_task.py +1 -1
- annofabcli/input_data/list_input_data.py +1 -1
- annofabcli/input_data/put_input_data.py +1 -1
- annofabcli/input_data/put_input_data_with_zip.py +1 -1
- annofabcli/instruction/copy_instruction.py +1 -1
- annofabcli/instruction/download_instruction.py +1 -1
- annofabcli/instruction/list_instruction_history.py +1 -1
- annofabcli/instruction/upload_instruction.py +1 -1
- annofabcli/job/delete_job.py +1 -1
- annofabcli/job/list_job.py +1 -1
- annofabcli/job/list_last_job.py +1 -1
- annofabcli/my_account/get_my_account.py +1 -1
- annofabcli/organization/list_organization.py +1 -1
- annofabcli/organization_member/list_organization_member.py +1 -1
- annofabcli/project/change_organization_of_project.py +1 -1
- annofabcli/project/change_project_status.py +1 -1
- annofabcli/project/copy_project.py +1 -1
- annofabcli/project/create_project.py +1 -1
- annofabcli/project/list_project.py +1 -1
- annofabcli/project/put_project.py +1 -1
- annofabcli/project/update_configuration.py +1 -1
- annofabcli/project_member/change_project_members.py +1 -1
- annofabcli/project_member/copy_project_members.py +1 -1
- annofabcli/project_member/drop_project_members.py +1 -1
- annofabcli/project_member/list_users.py +1 -1
- annofabcli/project_member/put_project_members.py +1 -1
- annofabcli/statistics/list_worktime.py +1 -1
- annofabcli/supplementary/delete_supplementary_data.py +1 -1
- annofabcli/supplementary/list_supplementary_data.py +1 -1
- annofabcli/supplementary/put_supplementary_data.py +1 -1
- annofabcli/task/delete_tasks.py +1 -1
- annofabcli/task/list_all_tasks.py +1 -1
- annofabcli/task/list_all_tasks_added_task_history.py +2 -1
- annofabcli/task/list_tasks.py +1 -1
- annofabcli/task/list_tasks_added_task_history.py +1 -1
- annofabcli/task/put_tasks.py +1 -1
- annofabcli/task/put_tasks_by_count.py +1 -1
- annofabcli/task_history/list_all_task_history.py +1 -1
- annofabcli/task_history/list_task_history.py +1 -1
- annofabcli/task_history_event/list_all_task_history_event.py +1 -1
- annofabcli/task_history_event/list_worktime.py +2 -1
- {annofabcli-1.112.0.dist-info → annofabcli-1.113.1.dist-info}/METADATA +1 -1
- {annofabcli-1.112.0.dist-info → annofabcli-1.113.1.dist-info}/RECORD +73 -71
- {annofabcli-1.112.0.dist-info → annofabcli-1.113.1.dist-info}/WHEEL +0 -0
- {annofabcli-1.112.0.dist-info → annofabcli-1.113.1.dist-info}/entry_points.txt +0 -0
- {annofabcli-1.112.0.dist-info → annofabcli-1.113.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -14,7 +14,7 @@ import annofabapi
|
|
|
14
14
|
from annofabapi.dataclass.task import Task
|
|
15
15
|
from annofabapi.models import ProjectMemberRole, TaskStatus
|
|
16
16
|
|
|
17
|
-
import annofabcli
|
|
17
|
+
import annofabcli.common.cli
|
|
18
18
|
from annofabcli.annotation.annotation_query import (
|
|
19
19
|
AnnotationQueryForAPI,
|
|
20
20
|
AnnotationQueryForCLI,
|
|
@@ -13,7 +13,7 @@ from annofabapi.models import ProjectMemberRole
|
|
|
13
13
|
from annofabapi.pydantic_models.task_status import TaskStatus
|
|
14
14
|
from pydantic import BaseModel
|
|
15
15
|
|
|
16
|
-
import annofabcli
|
|
16
|
+
import annofabcli.common.cli
|
|
17
17
|
from annofabcli.annotation.annotation_query import convert_attributes_from_cli_to_additional_data_list_v2
|
|
18
18
|
from annofabcli.annotation.dump_annotation import DumpAnnotationMain
|
|
19
19
|
from annofabcli.common.cli import (
|
|
@@ -15,7 +15,7 @@ from annofabapi.models import ProjectMemberRole, SingleAnnotation, TaskStatus
|
|
|
15
15
|
from annofabapi.utils import can_put_annotation, str_now
|
|
16
16
|
from dataclasses_json import DataClassJsonMixin
|
|
17
17
|
|
|
18
|
-
import annofabcli
|
|
18
|
+
import annofabcli.common.cli
|
|
19
19
|
from annofabcli.annotation.annotation_query import AnnotationQueryForAPI, AnnotationQueryForCLI
|
|
20
20
|
from annofabcli.annotation.dump_annotation import DumpAnnotationMain
|
|
21
21
|
from annofabcli.common.cli import (
|
|
@@ -13,7 +13,7 @@ import annofabapi
|
|
|
13
13
|
from annofabapi.models import ProjectMemberRole
|
|
14
14
|
from annofabapi.utils import can_put_annotation
|
|
15
15
|
|
|
16
|
-
import annofabcli
|
|
16
|
+
import annofabcli.common.cli
|
|
17
17
|
from annofabcli.common.cli import (
|
|
18
18
|
COMMAND_LINE_ERROR_STATUS_CODE,
|
|
19
19
|
PARALLELISM_CHOICES,
|
|
@@ -11,7 +11,7 @@ from annofabapi.models import DefaultAnnotationType, ProjectMemberRole, TaskStat
|
|
|
11
11
|
from annofabapi.util.annotation_specs import AnnotationSpecsAccessor
|
|
12
12
|
from annofabapi.utils import can_put_annotation
|
|
13
13
|
|
|
14
|
-
import annofabcli
|
|
14
|
+
import annofabcli.common.cli
|
|
15
15
|
from annofabcli.common.cli import (
|
|
16
16
|
COMMAND_LINE_ERROR_STATUS_CODE,
|
|
17
17
|
PARALLELISM_CHOICES,
|
|
@@ -15,7 +15,7 @@ import requests
|
|
|
15
15
|
from annofabapi.dataclass.task import Task
|
|
16
16
|
from annofabapi.models import ProjectMemberRole, TaskStatus
|
|
17
17
|
|
|
18
|
-
import annofabcli
|
|
18
|
+
import annofabcli.common.cli
|
|
19
19
|
from annofabcli.annotation.annotation_query import AnnotationQueryForAPI, AnnotationQueryForCLI
|
|
20
20
|
from annofabcli.annotation.dump_annotation import DumpAnnotationMain
|
|
21
21
|
from annofabcli.common.cli import (
|
|
@@ -11,7 +11,7 @@ from typing import Any
|
|
|
11
11
|
import annofabapi
|
|
12
12
|
from annofabapi.models import AnnotationDataHoldingType
|
|
13
13
|
|
|
14
|
-
import annofabcli
|
|
14
|
+
import annofabcli.common.cli
|
|
15
15
|
from annofabcli.common.cli import PARALLELISM_CHOICES, ArgumentParser, CommandLine, build_annofabapi_resource_and_login
|
|
16
16
|
from annofabcli.common.facade import AnnofabApiFacade
|
|
17
17
|
|
|
@@ -68,7 +68,7 @@ class DumpAnnotationMain:
|
|
|
68
68
|
json_path = task_dir / f"{input_data_id}.json"
|
|
69
69
|
self.dump_editor_annotation(editor_annotation=editor_annotation, json_path=json_path)
|
|
70
70
|
|
|
71
|
-
def dump_annotation_for_task(self, task_id: str, output_dir: Path, *, task_index: int | None = None, task_history_index: int | None = None) -> bool:
|
|
71
|
+
def dump_annotation_for_task(self, task_id: str, output_dir: Path, *, task_index: int | None = None, task_history_index: int | None = None, task_history_id: str | None = None) -> bool:
|
|
72
72
|
"""
|
|
73
73
|
タスク配下のアノテーションをファイルに保存する。
|
|
74
74
|
|
|
@@ -85,23 +85,23 @@ class DumpAnnotationMain:
|
|
|
85
85
|
logger.warning(f"task_id = '{task_id}' のタスクは存在しません。スキップします。")
|
|
86
86
|
return False
|
|
87
87
|
|
|
88
|
-
|
|
88
|
+
actual_task_history_id: str | None = task_history_id
|
|
89
89
|
if task_history_index is not None:
|
|
90
90
|
task_histories, _ = self.service.api.get_task_histories(self.project_id, task_id)
|
|
91
91
|
if task_history_index >= len(task_histories):
|
|
92
92
|
logger.warning(f"task_id='{task_id}' :: task_history_index='{task_history_index}'のタスク履歴は存在しません。タスク履歴は{len(task_histories)}件です。スキップします。")
|
|
93
93
|
return False
|
|
94
|
-
|
|
94
|
+
actual_task_history_id = task_histories[task_history_index]["task_history_id"]
|
|
95
95
|
|
|
96
96
|
input_data_id_list = task["input_data_id_list"]
|
|
97
97
|
task_dir = output_dir / task_id
|
|
98
98
|
task_dir.mkdir(exist_ok=True, parents=True)
|
|
99
|
-
logger.debug(f"{logger_prefix}task_id = '{task_id}' のアノテーション情報を '{task_dir}' ディレクトリに保存します。 :: task_history_id='{
|
|
99
|
+
logger.debug(f"{logger_prefix}task_id = '{task_id}' のアノテーション情報を '{task_dir}' ディレクトリに保存します。 :: task_history_id='{actual_task_history_id}'")
|
|
100
100
|
|
|
101
101
|
is_failure = False
|
|
102
102
|
for input_data_id in input_data_id_list:
|
|
103
103
|
try:
|
|
104
|
-
self.dump_annotation_for_input_data(task_id, input_data_id, task_dir=task_dir, task_history_id=
|
|
104
|
+
self.dump_annotation_for_input_data(task_id, input_data_id, task_dir=task_dir, task_history_id=actual_task_history_id)
|
|
105
105
|
except Exception:
|
|
106
106
|
logger.warning(f"タスク'{task_id}', 入力データ'{input_data_id}' のアノテーション情報のダンプに失敗しました。", exc_info=True)
|
|
107
107
|
is_failure = True
|
|
@@ -109,15 +109,15 @@ class DumpAnnotationMain:
|
|
|
109
109
|
|
|
110
110
|
return not is_failure
|
|
111
111
|
|
|
112
|
-
def dump_annotation_for_task_wrapper(self, tpl: tuple[int, str], output_dir: Path, *, task_history_index: int | None = None) -> bool:
|
|
112
|
+
def dump_annotation_for_task_wrapper(self, tpl: tuple[int, str], output_dir: Path, *, task_history_index: int | None = None, task_history_id: str | None = None) -> bool:
|
|
113
113
|
task_index, task_id = tpl
|
|
114
114
|
try:
|
|
115
|
-
return self.dump_annotation_for_task(task_id, output_dir=output_dir, task_index=task_index, task_history_index=task_history_index)
|
|
115
|
+
return self.dump_annotation_for_task(task_id, output_dir=output_dir, task_index=task_index, task_history_index=task_history_index, task_history_id=task_history_id)
|
|
116
116
|
except Exception: # pylint: disable=broad-except
|
|
117
117
|
logger.warning(f"タスク'{task_id}'のアノテーション情報のダンプに失敗しました。", exc_info=True)
|
|
118
118
|
return False
|
|
119
119
|
|
|
120
|
-
def dump_annotation(self, task_id_list: list[str], output_dir: Path, *, task_history_index: int | None = None, parallelism: int | None = None) -> None:
|
|
120
|
+
def dump_annotation(self, task_id_list: list[str], output_dir: Path, *, task_history_index: int | None = None, task_history_id: str | None = None, parallelism: int | None = None) -> None:
|
|
121
121
|
project_title = self.facade.get_project_title(self.project_id)
|
|
122
122
|
logger.info(f"プロジェクト'{project_title}'に対して、タスク{len(task_id_list)} 件のアノテーションをファイルに保存します。")
|
|
123
123
|
|
|
@@ -126,7 +126,7 @@ class DumpAnnotationMain:
|
|
|
126
126
|
success_count = 0
|
|
127
127
|
|
|
128
128
|
if parallelism is not None:
|
|
129
|
-
func = functools.partial(self.dump_annotation_for_task_wrapper, task_history_index=task_history_index, output_dir=output_dir)
|
|
129
|
+
func = functools.partial(self.dump_annotation_for_task_wrapper, task_history_index=task_history_index, task_history_id=task_history_id, output_dir=output_dir)
|
|
130
130
|
with multiprocessing.Pool(parallelism) as pool:
|
|
131
131
|
result_bool_list = pool.map(func, enumerate(task_id_list))
|
|
132
132
|
success_count = len([e for e in result_bool_list if e])
|
|
@@ -134,7 +134,7 @@ class DumpAnnotationMain:
|
|
|
134
134
|
else:
|
|
135
135
|
for task_index, task_id in enumerate(task_id_list):
|
|
136
136
|
try:
|
|
137
|
-
result = self.dump_annotation_for_task(task_id, output_dir=output_dir, task_history_index=task_history_index, task_index=task_index)
|
|
137
|
+
result = self.dump_annotation_for_task(task_id, output_dir=output_dir, task_history_index=task_history_index, task_history_id=task_history_id, task_index=task_index)
|
|
138
138
|
if result:
|
|
139
139
|
success_count += 1
|
|
140
140
|
except Exception:
|
|
@@ -157,7 +157,7 @@ class DumpAnnotation(CommandLine):
|
|
|
157
157
|
super().validate_project(project_id, project_member_roles=None)
|
|
158
158
|
|
|
159
159
|
main_obj = DumpAnnotationMain(self.service, project_id)
|
|
160
|
-
main_obj.dump_annotation(task_id_list, output_dir=output_dir, parallelism=args.parallelism, task_history_index=args.task_history_index)
|
|
160
|
+
main_obj.dump_annotation(task_id_list, output_dir=output_dir, parallelism=args.parallelism, task_history_index=args.task_history_index, task_history_id=args.task_history_id)
|
|
161
161
|
|
|
162
162
|
|
|
163
163
|
def main(args: argparse.Namespace) -> None:
|
|
@@ -174,12 +174,19 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
174
174
|
|
|
175
175
|
parser.add_argument("-o", "--output_dir", type=str, required=True, help="出力先ディレクトリのパス")
|
|
176
176
|
|
|
177
|
-
parser.
|
|
177
|
+
task_history_group = parser.add_mutually_exclusive_group()
|
|
178
|
+
task_history_group.add_argument(
|
|
178
179
|
"--task_history_index",
|
|
179
180
|
type=int,
|
|
180
181
|
help="指定したタスク履歴のインデックス(ゼロ始まり)で付与されたアノテーション情報をダンプします。過去のアノテーション結果をダンプする場合に指定します。"
|
|
181
182
|
"ただし、過去のアノテーションデータは30日間しか保持されません。30日より前に更新されたアノテーションをダンプした場合は、アノテーションが0件の状態でダンプされます。",
|
|
182
183
|
)
|
|
184
|
+
task_history_group.add_argument(
|
|
185
|
+
"--task_history_id",
|
|
186
|
+
type=str,
|
|
187
|
+
help="指定したタスク履歴IDで付与されたアノテーション情報をダンプします。過去のアノテーション結果をダンプする場合に指定します。"
|
|
188
|
+
"ただし、過去のアノテーションデータは30日間しか保持されません。30日より前に更新されたアノテーションをダンプした場合は、アノテーションが0件の状態でダンプされます。",
|
|
189
|
+
)
|
|
183
190
|
|
|
184
191
|
parser.add_argument(
|
|
185
192
|
"--parallelism",
|
|
@@ -32,7 +32,7 @@ from annofabapi.util.annotation_specs import AnnotationSpecsAccessor, get_choice
|
|
|
32
32
|
from annofabapi.utils import can_put_annotation
|
|
33
33
|
from dataclasses_json import DataClassJsonMixin
|
|
34
34
|
|
|
35
|
-
import annofabcli
|
|
35
|
+
import annofabcli.common.cli
|
|
36
36
|
from annofabcli.common.cli import (
|
|
37
37
|
COMMAND_LINE_ERROR_STATUS_CODE,
|
|
38
38
|
PARALLELISM_CHOICES,
|
|
@@ -9,7 +9,7 @@ import annofabapi
|
|
|
9
9
|
import pandas
|
|
10
10
|
from annofabapi.models import SingleAnnotation
|
|
11
11
|
|
|
12
|
-
import annofabcli
|
|
12
|
+
import annofabcli.common.cli
|
|
13
13
|
from annofabcli.annotation.annotation_query import AnnotationQueryForAPI, AnnotationQueryForCLI
|
|
14
14
|
from annofabcli.common.cli import (
|
|
15
15
|
COMMAND_LINE_ERROR_STATUS_CODE,
|
|
@@ -9,7 +9,7 @@ import annofabapi
|
|
|
9
9
|
import pandas
|
|
10
10
|
from annofabapi.models import SingleAnnotation
|
|
11
11
|
|
|
12
|
-
import annofabcli
|
|
12
|
+
import annofabcli.common.cli
|
|
13
13
|
from annofabcli.annotation.annotation_query import AnnotationQueryForCLI
|
|
14
14
|
from annofabcli.annotation.list_annotation import ListAnnotationMain
|
|
15
15
|
from annofabcli.common.cli import (
|
|
@@ -19,7 +19,7 @@ from annofabapi.segmentation import read_binary_image, write_binary_image
|
|
|
19
19
|
from annofabapi.util.annotation_specs import AnnotationSpecsAccessor
|
|
20
20
|
from annofabapi.utils import can_put_annotation
|
|
21
21
|
|
|
22
|
-
import annofabcli
|
|
22
|
+
import annofabcli.common.cli
|
|
23
23
|
from annofabcli.common.cli import (
|
|
24
24
|
COMMAND_LINE_ERROR_STATUS_CODE,
|
|
25
25
|
PARALLELISM_CHOICES,
|
|
@@ -17,7 +17,7 @@ from annofabapi.pydantic_models.task_status import TaskStatus
|
|
|
17
17
|
from annofabapi.segmentation import read_binary_image, write_binary_image
|
|
18
18
|
from annofabapi.utils import can_put_annotation
|
|
19
19
|
|
|
20
|
-
import annofabcli
|
|
20
|
+
import annofabcli.common.cli
|
|
21
21
|
from annofabcli.common.cli import (
|
|
22
22
|
COMMAND_LINE_ERROR_STATUS_CODE,
|
|
23
23
|
PARALLELISM_CHOICES,
|
|
@@ -4,7 +4,7 @@ from typing import Any
|
|
|
4
4
|
|
|
5
5
|
import annofabapi
|
|
6
6
|
|
|
7
|
-
import annofabcli
|
|
7
|
+
import annofabcli.common.cli
|
|
8
8
|
from annofabcli.common.cli import ArgumentParser, CommandLine, build_annofabapi_resource_and_login
|
|
9
9
|
from annofabcli.common.enums import FormatArgument
|
|
10
10
|
from annofabcli.common.facade import AnnofabApiFacade
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import argparse
|
|
2
2
|
import logging
|
|
3
|
+
import math
|
|
3
4
|
import sys
|
|
4
5
|
import tempfile
|
|
5
6
|
from collections.abc import Collection
|
|
@@ -65,6 +66,9 @@ class Annotation3DBoundingBoxInfo(DataClassJsonMixin):
|
|
|
65
66
|
top_z: float
|
|
66
67
|
"""天面のZ座標(location.z + height/2)。回転は考慮していない。"""
|
|
67
68
|
|
|
69
|
+
horizontal_distance: float
|
|
70
|
+
"""原点(0, 0)からのXY平面上の距離(sqrt(location.x² + location.y²))"""
|
|
71
|
+
|
|
68
72
|
attributes: dict[str, str | int | bool]
|
|
69
73
|
"""属性情報"""
|
|
70
74
|
|
|
@@ -96,6 +100,7 @@ def get_annotation_3d_bounding_box_info_list(simple_annotation: dict[str, Any],
|
|
|
96
100
|
footprint_area = width * depth
|
|
97
101
|
bottom_z = location.z - height / 2
|
|
98
102
|
top_z = location.z + height / 2
|
|
103
|
+
horizontal_distance = math.hypot(location.x, location.y)
|
|
99
104
|
|
|
100
105
|
result.append(
|
|
101
106
|
Annotation3DBoundingBoxInfo(
|
|
@@ -116,6 +121,7 @@ def get_annotation_3d_bounding_box_info_list(simple_annotation: dict[str, Any],
|
|
|
116
121
|
footprint_area=footprint_area,
|
|
117
122
|
bottom_z=bottom_z,
|
|
118
123
|
top_z=top_z,
|
|
124
|
+
horizontal_distance=horizontal_distance,
|
|
119
125
|
attributes=detail["attributes"],
|
|
120
126
|
updated_datetime=simple_annotation["updated_datetime"],
|
|
121
127
|
)
|
|
@@ -177,6 +183,7 @@ def create_df(
|
|
|
177
183
|
"footprint_area",
|
|
178
184
|
"bottom_z",
|
|
179
185
|
"top_z",
|
|
186
|
+
"horizontal_distance",
|
|
180
187
|
]
|
|
181
188
|
|
|
182
189
|
if len(tmp_annotation_bbox_list) == 0:
|
|
@@ -331,7 +338,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
331
338
|
parser.add_argument(
|
|
332
339
|
"--label_name",
|
|
333
340
|
type=str,
|
|
334
|
-
nargs="
|
|
341
|
+
nargs="+",
|
|
335
342
|
help="指定したラベル名の3Dバウンディングボックスアノテーションのみを対象にします。複数指定できます。",
|
|
336
343
|
)
|
|
337
344
|
|
|
@@ -46,8 +46,13 @@ class AnnotationBoundingBoxInfo(DataClassJsonMixin):
|
|
|
46
46
|
annotation_id: str
|
|
47
47
|
left_top: dict[str, int]
|
|
48
48
|
right_bottom: dict[str, int]
|
|
49
|
+
center: dict[str, float]
|
|
50
|
+
"""バウンディングボックスの中心座標"""
|
|
49
51
|
width: int
|
|
50
52
|
height: int
|
|
53
|
+
area: int
|
|
54
|
+
"""バウンディングボックスの面積"""
|
|
55
|
+
attributes: dict[str, str | int | bool]
|
|
51
56
|
|
|
52
57
|
|
|
53
58
|
def get_annotation_bounding_box_info_list(simple_annotation: dict[str, Any], *, target_label_names: Collection[str] | None = None) -> list[AnnotationBoundingBoxInfo]:
|
|
@@ -64,6 +69,9 @@ def get_annotation_bounding_box_info_list(simple_annotation: dict[str, Any], *,
|
|
|
64
69
|
right_bottom = detail["data"]["right_bottom"]
|
|
65
70
|
width = abs(right_bottom["x"] - left_top["x"])
|
|
66
71
|
height = abs(right_bottom["y"] - left_top["y"])
|
|
72
|
+
center_x = (left_top["x"] + right_bottom["x"]) / 2
|
|
73
|
+
center_y = (left_top["y"] + right_bottom["y"]) / 2
|
|
74
|
+
area = width * height
|
|
67
75
|
|
|
68
76
|
result.append(
|
|
69
77
|
AnnotationBoundingBoxInfo(
|
|
@@ -78,9 +86,12 @@ def get_annotation_bounding_box_info_list(simple_annotation: dict[str, Any], *,
|
|
|
78
86
|
annotation_id=detail["annotation_id"],
|
|
79
87
|
left_top=left_top,
|
|
80
88
|
right_bottom=right_bottom,
|
|
89
|
+
center={"x": center_x, "y": center_y},
|
|
81
90
|
width=width,
|
|
82
91
|
height=height,
|
|
92
|
+
area=area,
|
|
83
93
|
updated_datetime=simple_annotation["updated_datetime"],
|
|
94
|
+
attributes=detail["attributes"],
|
|
84
95
|
)
|
|
85
96
|
)
|
|
86
97
|
|
|
@@ -114,7 +125,7 @@ def get_annotation_bounding_box_info_list_from_annotation_path(
|
|
|
114
125
|
def create_df(
|
|
115
126
|
annotation_bbox_list: list[AnnotationBoundingBoxInfo],
|
|
116
127
|
) -> pandas.DataFrame:
|
|
117
|
-
|
|
128
|
+
base_columns = [
|
|
118
129
|
"project_id",
|
|
119
130
|
"task_id",
|
|
120
131
|
"task_status",
|
|
@@ -129,33 +140,22 @@ def create_df(
|
|
|
129
140
|
"left_top.y",
|
|
130
141
|
"right_bottom.x",
|
|
131
142
|
"right_bottom.y",
|
|
143
|
+
"center.x",
|
|
144
|
+
"center.y",
|
|
132
145
|
"width",
|
|
133
146
|
"height",
|
|
147
|
+
"area",
|
|
134
148
|
]
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
"updated_datetime": e.updated_datetime,
|
|
146
|
-
"label": e.label,
|
|
147
|
-
"annotation_id": e.annotation_id,
|
|
148
|
-
"left_top.x": e.left_top["x"],
|
|
149
|
-
"left_top.y": e.left_top["y"],
|
|
150
|
-
"right_bottom.x": e.right_bottom["x"],
|
|
151
|
-
"right_bottom.y": e.right_bottom["y"],
|
|
152
|
-
"width": e.width,
|
|
153
|
-
"height": e.height,
|
|
154
|
-
}
|
|
155
|
-
for e in annotation_bbox_list
|
|
156
|
-
],
|
|
157
|
-
columns=columns,
|
|
158
|
-
)
|
|
149
|
+
|
|
150
|
+
if not annotation_bbox_list:
|
|
151
|
+
# 空のリストの場合は、base_columnsのみで空のDataFrameを返す
|
|
152
|
+
return pandas.DataFrame(columns=base_columns)
|
|
153
|
+
|
|
154
|
+
tmp_annotation_bbox_list = [e.to_dict(encode_json=True) for e in annotation_bbox_list]
|
|
155
|
+
df = pandas.json_normalize(tmp_annotation_bbox_list)
|
|
156
|
+
|
|
157
|
+
attribute_columns = sorted(col for col in df.columns if col.startswith("attributes."))
|
|
158
|
+
columns = base_columns + attribute_columns
|
|
159
159
|
|
|
160
160
|
return df[columns]
|
|
161
161
|
|
|
@@ -301,7 +301,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
301
301
|
parser.add_argument(
|
|
302
302
|
"--label_name",
|
|
303
303
|
type=str,
|
|
304
|
-
nargs="
|
|
304
|
+
nargs="+",
|
|
305
305
|
help="指定したラベル名のバウンディングボックスアノテーションのみを対象にします。複数指定できます。",
|
|
306
306
|
)
|
|
307
307
|
|