label-studio-sdk 0.0.34__py3-none-any.whl → 1.0.0__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.
- label_studio_sdk/__init__.py +206 -9
- label_studio_sdk/_extensions/label_studio_tools/__init__.py +0 -0
- label_studio_sdk/_extensions/label_studio_tools/core/__init__.py +0 -0
- label_studio_sdk/_extensions/label_studio_tools/core/label_config.py +163 -0
- label_studio_sdk/_extensions/label_studio_tools/core/utils/__init__.py +0 -0
- label_studio_sdk/_extensions/label_studio_tools/core/utils/exceptions.py +2 -0
- label_studio_sdk/_extensions/label_studio_tools/core/utils/io.py +228 -0
- label_studio_sdk/_extensions/label_studio_tools/core/utils/params.py +45 -0
- label_studio_sdk/_extensions/label_studio_tools/etl/__init__.py +1 -0
- label_studio_sdk/_extensions/label_studio_tools/etl/beam.py +34 -0
- label_studio_sdk/_extensions/label_studio_tools/etl/example.py +17 -0
- label_studio_sdk/_extensions/label_studio_tools/etl/registry.py +67 -0
- label_studio_sdk/_extensions/label_studio_tools/postprocessing/__init__.py +0 -0
- label_studio_sdk/_extensions/label_studio_tools/postprocessing/video.py +97 -0
- label_studio_sdk/_legacy/__init__.py +11 -0
- label_studio_sdk/_legacy/client.py +471 -0
- label_studio_sdk/_legacy/label_interface/data_examples.json +96 -0
- label_studio_sdk/{label_interface → _legacy/label_interface}/interface.py +9 -6
- label_studio_sdk/{project.py → _legacy/project.py} +2 -2
- label_studio_sdk/actions/__init__.py +2 -0
- label_studio_sdk/actions/client.py +150 -0
- label_studio_sdk/annotations/__init__.py +2 -0
- label_studio_sdk/annotations/client.py +750 -0
- label_studio_sdk/client.py +162 -450
- label_studio_sdk/converter/__init__.py +7 -0
- label_studio_sdk/converter/audio.py +56 -0
- label_studio_sdk/converter/brush.py +452 -0
- label_studio_sdk/converter/converter.py +1175 -0
- label_studio_sdk/converter/exports/__init__.py +0 -0
- label_studio_sdk/converter/exports/csv.py +82 -0
- label_studio_sdk/converter/exports/csv2.py +103 -0
- label_studio_sdk/converter/funsd.py +85 -0
- label_studio_sdk/converter/imports/__init__.py +0 -0
- label_studio_sdk/converter/imports/coco.py +314 -0
- label_studio_sdk/converter/imports/colors.py +198 -0
- label_studio_sdk/converter/imports/label_config.py +45 -0
- label_studio_sdk/converter/imports/pathtrack.py +269 -0
- label_studio_sdk/converter/imports/yolo.py +236 -0
- label_studio_sdk/converter/main.py +202 -0
- label_studio_sdk/converter/utils.py +473 -0
- label_studio_sdk/core/__init__.py +33 -0
- label_studio_sdk/core/api_error.py +15 -0
- label_studio_sdk/core/client_wrapper.py +55 -0
- label_studio_sdk/core/datetime_utils.py +28 -0
- label_studio_sdk/core/file.py +38 -0
- label_studio_sdk/core/http_client.py +443 -0
- label_studio_sdk/core/jsonable_encoder.py +99 -0
- label_studio_sdk/core/pagination.py +87 -0
- label_studio_sdk/core/pydantic_utilities.py +28 -0
- label_studio_sdk/core/query_encoder.py +33 -0
- label_studio_sdk/core/remove_none_from_dict.py +11 -0
- label_studio_sdk/core/request_options.py +32 -0
- label_studio_sdk/environment.py +7 -0
- label_studio_sdk/errors/__init__.py +6 -0
- label_studio_sdk/errors/bad_request_error.py +8 -0
- label_studio_sdk/errors/internal_server_error.py +8 -0
- label_studio_sdk/export_storage/__init__.py +28 -0
- label_studio_sdk/export_storage/azure/__init__.py +5 -0
- label_studio_sdk/export_storage/azure/client.py +722 -0
- label_studio_sdk/export_storage/azure/types/__init__.py +6 -0
- label_studio_sdk/export_storage/azure/types/azure_create_response.py +52 -0
- label_studio_sdk/export_storage/azure/types/azure_update_response.py +52 -0
- label_studio_sdk/export_storage/client.py +107 -0
- label_studio_sdk/export_storage/gcs/__init__.py +5 -0
- label_studio_sdk/export_storage/gcs/client.py +722 -0
- label_studio_sdk/export_storage/gcs/types/__init__.py +6 -0
- label_studio_sdk/export_storage/gcs/types/gcs_create_response.py +52 -0
- label_studio_sdk/export_storage/gcs/types/gcs_update_response.py +52 -0
- label_studio_sdk/export_storage/local/__init__.py +5 -0
- label_studio_sdk/export_storage/local/client.py +688 -0
- label_studio_sdk/export_storage/local/types/__init__.py +6 -0
- label_studio_sdk/export_storage/local/types/local_create_response.py +47 -0
- label_studio_sdk/export_storage/local/types/local_update_response.py +47 -0
- label_studio_sdk/export_storage/redis/__init__.py +5 -0
- label_studio_sdk/export_storage/redis/client.py +714 -0
- label_studio_sdk/export_storage/redis/types/__init__.py +6 -0
- label_studio_sdk/export_storage/redis/types/redis_create_response.py +57 -0
- label_studio_sdk/export_storage/redis/types/redis_update_response.py +57 -0
- label_studio_sdk/export_storage/s3/__init__.py +5 -0
- label_studio_sdk/export_storage/s3/client.py +820 -0
- label_studio_sdk/export_storage/s3/types/__init__.py +6 -0
- label_studio_sdk/export_storage/s3/types/s3create_response.py +74 -0
- label_studio_sdk/export_storage/s3/types/s3update_response.py +74 -0
- label_studio_sdk/export_storage/types/__init__.py +5 -0
- label_studio_sdk/export_storage/types/export_storage_list_types_response_item.py +30 -0
- label_studio_sdk/files/__init__.py +2 -0
- label_studio_sdk/files/client.py +556 -0
- label_studio_sdk/import_storage/__init__.py +28 -0
- label_studio_sdk/import_storage/azure/__init__.py +5 -0
- label_studio_sdk/import_storage/azure/client.py +812 -0
- label_studio_sdk/import_storage/azure/types/__init__.py +6 -0
- label_studio_sdk/import_storage/azure/types/azure_create_response.py +72 -0
- label_studio_sdk/import_storage/azure/types/azure_update_response.py +72 -0
- label_studio_sdk/import_storage/client.py +107 -0
- label_studio_sdk/import_storage/gcs/__init__.py +5 -0
- label_studio_sdk/import_storage/gcs/client.py +812 -0
- label_studio_sdk/import_storage/gcs/types/__init__.py +6 -0
- label_studio_sdk/import_storage/gcs/types/gcs_create_response.py +72 -0
- label_studio_sdk/import_storage/gcs/types/gcs_update_response.py +72 -0
- label_studio_sdk/import_storage/local/__init__.py +5 -0
- label_studio_sdk/import_storage/local/client.py +690 -0
- label_studio_sdk/import_storage/local/types/__init__.py +6 -0
- label_studio_sdk/import_storage/local/types/local_create_response.py +47 -0
- label_studio_sdk/import_storage/local/types/local_update_response.py +47 -0
- label_studio_sdk/import_storage/redis/__init__.py +5 -0
- label_studio_sdk/import_storage/redis/client.py +768 -0
- label_studio_sdk/import_storage/redis/types/__init__.py +6 -0
- label_studio_sdk/import_storage/redis/types/redis_create_response.py +62 -0
- label_studio_sdk/import_storage/redis/types/redis_update_response.py +62 -0
- label_studio_sdk/import_storage/s3/__init__.py +5 -0
- label_studio_sdk/import_storage/s3/client.py +912 -0
- label_studio_sdk/import_storage/s3/types/__init__.py +6 -0
- label_studio_sdk/import_storage/s3/types/s3create_response.py +99 -0
- label_studio_sdk/import_storage/s3/types/s3update_response.py +99 -0
- label_studio_sdk/import_storage/types/__init__.py +5 -0
- label_studio_sdk/import_storage/types/import_storage_list_types_response_item.py +30 -0
- label_studio_sdk/ml/__init__.py +19 -0
- label_studio_sdk/ml/client.py +981 -0
- label_studio_sdk/ml/types/__init__.py +17 -0
- label_studio_sdk/ml/types/ml_create_request_auth_method.py +5 -0
- label_studio_sdk/ml/types/ml_create_response.py +78 -0
- label_studio_sdk/ml/types/ml_create_response_auth_method.py +5 -0
- label_studio_sdk/ml/types/ml_update_request_auth_method.py +5 -0
- label_studio_sdk/ml/types/ml_update_response.py +78 -0
- label_studio_sdk/ml/types/ml_update_response_auth_method.py +5 -0
- label_studio_sdk/predictions/__init__.py +2 -0
- label_studio_sdk/predictions/client.py +638 -0
- label_studio_sdk/projects/__init__.py +6 -0
- label_studio_sdk/projects/client.py +1053 -0
- label_studio_sdk/projects/exports/__init__.py +2 -0
- label_studio_sdk/projects/exports/client.py +930 -0
- label_studio_sdk/projects/types/__init__.py +7 -0
- label_studio_sdk/projects/types/projects_create_response.py +96 -0
- label_studio_sdk/projects/types/projects_import_tasks_response.py +71 -0
- label_studio_sdk/projects/types/projects_list_response.py +33 -0
- label_studio_sdk/py.typed +0 -0
- label_studio_sdk/tasks/__init__.py +5 -0
- label_studio_sdk/tasks/client.py +811 -0
- label_studio_sdk/tasks/types/__init__.py +6 -0
- label_studio_sdk/tasks/types/tasks_list_request_fields.py +5 -0
- label_studio_sdk/tasks/types/tasks_list_response.py +48 -0
- label_studio_sdk/types/__init__.py +115 -0
- label_studio_sdk/types/annotation.py +116 -0
- label_studio_sdk/types/annotation_filter_options.py +42 -0
- label_studio_sdk/types/annotation_last_action.py +19 -0
- label_studio_sdk/types/azure_blob_export_storage.py +112 -0
- label_studio_sdk/types/azure_blob_export_storage_status.py +7 -0
- label_studio_sdk/types/azure_blob_import_storage.py +113 -0
- label_studio_sdk/types/azure_blob_import_storage_status.py +7 -0
- label_studio_sdk/types/base_task.py +113 -0
- label_studio_sdk/types/base_user.py +42 -0
- label_studio_sdk/types/converted_format.py +36 -0
- label_studio_sdk/types/converted_format_status.py +5 -0
- label_studio_sdk/types/export.py +48 -0
- label_studio_sdk/types/export_convert.py +32 -0
- label_studio_sdk/types/export_create.py +54 -0
- label_studio_sdk/types/export_create_status.py +5 -0
- label_studio_sdk/types/export_status.py +5 -0
- label_studio_sdk/types/file_upload.py +30 -0
- label_studio_sdk/types/filter.py +53 -0
- label_studio_sdk/types/filter_group.py +35 -0
- label_studio_sdk/types/gcs_export_storage.py +112 -0
- label_studio_sdk/types/gcs_export_storage_status.py +7 -0
- label_studio_sdk/types/gcs_import_storage.py +113 -0
- label_studio_sdk/types/gcs_import_storage_status.py +7 -0
- label_studio_sdk/types/local_files_export_storage.py +97 -0
- label_studio_sdk/types/local_files_export_storage_status.py +7 -0
- label_studio_sdk/types/local_files_import_storage.py +92 -0
- label_studio_sdk/types/local_files_import_storage_status.py +7 -0
- label_studio_sdk/types/ml_backend.py +89 -0
- label_studio_sdk/types/ml_backend_auth_method.py +5 -0
- label_studio_sdk/types/ml_backend_state.py +5 -0
- label_studio_sdk/types/prediction.py +78 -0
- label_studio_sdk/types/project.py +198 -0
- label_studio_sdk/types/project_import.py +63 -0
- label_studio_sdk/types/project_import_status.py +5 -0
- label_studio_sdk/types/project_label_config.py +32 -0
- label_studio_sdk/types/project_sampling.py +7 -0
- label_studio_sdk/types/project_skip_queue.py +5 -0
- label_studio_sdk/types/redis_export_storage.py +117 -0
- label_studio_sdk/types/redis_export_storage_status.py +7 -0
- label_studio_sdk/types/redis_import_storage.py +112 -0
- label_studio_sdk/types/redis_import_storage_status.py +7 -0
- label_studio_sdk/types/s3export_storage.py +134 -0
- label_studio_sdk/types/s3export_storage_status.py +7 -0
- label_studio_sdk/types/s3import_storage.py +140 -0
- label_studio_sdk/types/s3import_storage_status.py +7 -0
- label_studio_sdk/types/serialization_option.py +36 -0
- label_studio_sdk/types/serialization_options.py +45 -0
- label_studio_sdk/types/task.py +157 -0
- label_studio_sdk/types/task_filter_options.py +49 -0
- label_studio_sdk/types/user_simple.py +37 -0
- label_studio_sdk/types/view.py +55 -0
- label_studio_sdk/types/webhook.py +67 -0
- label_studio_sdk/types/webhook_actions_item.py +21 -0
- label_studio_sdk/types/webhook_serializer_for_update.py +67 -0
- label_studio_sdk/types/webhook_serializer_for_update_actions_item.py +21 -0
- label_studio_sdk/users/__init__.py +5 -0
- label_studio_sdk/users/client.py +830 -0
- label_studio_sdk/users/types/__init__.py +6 -0
- label_studio_sdk/users/types/users_get_token_response.py +36 -0
- label_studio_sdk/users/types/users_reset_token_response.py +36 -0
- label_studio_sdk/version.py +4 -0
- label_studio_sdk/views/__init__.py +31 -0
- label_studio_sdk/views/client.py +564 -0
- label_studio_sdk/views/types/__init__.py +29 -0
- label_studio_sdk/views/types/views_create_request_data.py +43 -0
- label_studio_sdk/views/types/views_create_request_data_filters.py +43 -0
- label_studio_sdk/views/types/views_create_request_data_filters_conjunction.py +5 -0
- label_studio_sdk/views/types/views_create_request_data_filters_items_item.py +47 -0
- label_studio_sdk/views/types/views_create_request_data_ordering_item.py +38 -0
- label_studio_sdk/views/types/views_create_request_data_ordering_item_direction.py +5 -0
- label_studio_sdk/views/types/views_update_request_data.py +43 -0
- label_studio_sdk/views/types/views_update_request_data_filters.py +43 -0
- label_studio_sdk/views/types/views_update_request_data_filters_conjunction.py +5 -0
- label_studio_sdk/views/types/views_update_request_data_filters_items_item.py +47 -0
- label_studio_sdk/views/types/views_update_request_data_ordering_item.py +38 -0
- label_studio_sdk/views/types/views_update_request_data_ordering_item_direction.py +5 -0
- label_studio_sdk/webhooks/__init__.py +5 -0
- label_studio_sdk/webhooks/client.py +636 -0
- label_studio_sdk/webhooks/types/__init__.py +5 -0
- label_studio_sdk/webhooks/types/webhooks_update_request_actions_item.py +21 -0
- label_studio_sdk-1.0.0.dist-info/METADATA +307 -0
- label_studio_sdk-1.0.0.dist-info/RECORD +239 -0
- {label_studio_sdk-0.0.34.dist-info → label_studio_sdk-1.0.0.dist-info}/WHEEL +1 -2
- label_studio_sdk-0.0.34.dist-info/LICENSE +0 -201
- label_studio_sdk-0.0.34.dist-info/METADATA +0 -24
- label_studio_sdk-0.0.34.dist-info/RECORD +0 -37
- label_studio_sdk-0.0.34.dist-info/top_level.txt +0 -2
- tests/test_client.py +0 -37
- tests/test_export.py +0 -105
- tests/test_interface/__init__.py +0 -1
- tests/test_interface/configs.py +0 -137
- tests/test_interface/mockups.py +0 -22
- tests/test_interface/test_compat.py +0 -64
- tests/test_interface/test_control_tags.py +0 -55
- tests/test_interface/test_data_generation.py +0 -45
- tests/test_interface/test_lpi.py +0 -15
- tests/test_interface/test_main.py +0 -196
- tests/test_interface/test_object_tags.py +0 -36
- tests/test_interface/test_region.py +0 -36
- tests/test_interface/test_validate_summary.py +0 -35
- tests/test_interface/test_validation.py +0 -59
- {tests → label_studio_sdk/_extensions}/__init__.py +0 -0
- /label_studio_sdk/{exceptions.py → _legacy/exceptions.py} +0 -0
- /label_studio_sdk/{label_interface → _legacy/label_interface}/__init__.py +0 -0
- /label_studio_sdk/{label_interface → _legacy/label_interface}/base.py +0 -0
- /label_studio_sdk/{label_interface → _legacy/label_interface}/control_tags.py +0 -0
- /label_studio_sdk/{label_interface → _legacy/label_interface}/label_tags.py +0 -0
- /label_studio_sdk/{label_interface → _legacy/label_interface}/object_tags.py +0 -0
- /label_studio_sdk/{label_interface → _legacy/label_interface}/region.py +0 -0
- /label_studio_sdk/{objects.py → _legacy/objects.py} +0 -0
- /label_studio_sdk/{schema → _legacy/schema}/label_config_schema.json +0 -0
- /label_studio_sdk/{users.py → _legacy/users.py} +0 -0
- /label_studio_sdk/{utils.py → _legacy/utils.py} +0 -0
- /label_studio_sdk/{workspaces.py → _legacy/workspaces.py} +0 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
COLORS = [
|
|
2
|
+
(218, 1, 238),
|
|
3
|
+
(0, 255, 0),
|
|
4
|
+
(1, 146, 243),
|
|
5
|
+
(241, 135, 0),
|
|
6
|
+
(12, 0, 184),
|
|
7
|
+
(72, 124, 73),
|
|
8
|
+
(187, 1, 37),
|
|
9
|
+
(166, 250, 86),
|
|
10
|
+
(178, 135, 216),
|
|
11
|
+
(0, 252, 159),
|
|
12
|
+
(116, 239, 254),
|
|
13
|
+
(252, 65, 124),
|
|
14
|
+
(99, 56, 252),
|
|
15
|
+
(252, 183, 127),
|
|
16
|
+
(115, 41, 127),
|
|
17
|
+
(255, 255, 0),
|
|
18
|
+
(137, 176, 1),
|
|
19
|
+
(95, 192, 153),
|
|
20
|
+
(1, 53, 87),
|
|
21
|
+
(148, 86, 0),
|
|
22
|
+
(179, 123, 99),
|
|
23
|
+
(5, 168, 6),
|
|
24
|
+
(33, 101, 165),
|
|
25
|
+
(3, 232, 254),
|
|
26
|
+
(254, 86, 239),
|
|
27
|
+
(64, 234, 74),
|
|
28
|
+
(188, 228, 185),
|
|
29
|
+
(45, 74, 0),
|
|
30
|
+
(2, 170, 123),
|
|
31
|
+
(251, 53, 7),
|
|
32
|
+
(250, 176, 247),
|
|
33
|
+
(176, 61, 197),
|
|
34
|
+
(127, 255, 0),
|
|
35
|
+
(99, 1, 6),
|
|
36
|
+
(199, 4, 140),
|
|
37
|
+
(0, 71, 252),
|
|
38
|
+
(101, 164, 251),
|
|
39
|
+
(255, 255, 127),
|
|
40
|
+
(215, 197, 46),
|
|
41
|
+
(117, 3, 199),
|
|
42
|
+
(70, 0, 82),
|
|
43
|
+
(116, 120, 156),
|
|
44
|
+
(244, 121, 164),
|
|
45
|
+
(147, 186, 88),
|
|
46
|
+
(183, 55, 82),
|
|
47
|
+
(96, 253, 180),
|
|
48
|
+
(19, 194, 191),
|
|
49
|
+
(0, 0, 255),
|
|
50
|
+
(254, 7, 79),
|
|
51
|
+
(77, 135, 0),
|
|
52
|
+
(103, 62, 54),
|
|
53
|
+
(82, 111, 222),
|
|
54
|
+
(254, 121, 80),
|
|
55
|
+
(176, 195, 252),
|
|
56
|
+
(60, 215, 6),
|
|
57
|
+
(53, 50, 196),
|
|
58
|
+
(186, 168, 150),
|
|
59
|
+
(52, 180, 59),
|
|
60
|
+
(2, 108, 105),
|
|
61
|
+
(5, 3, 119),
|
|
62
|
+
(1, 117, 28),
|
|
63
|
+
(248, 34, 189),
|
|
64
|
+
(212, 92, 35),
|
|
65
|
+
(252, 216, 188),
|
|
66
|
+
(74, 3, 252),
|
|
67
|
+
(255, 0, 0),
|
|
68
|
+
(193, 245, 20),
|
|
69
|
+
(139, 130, 41),
|
|
70
|
+
(1, 223, 106),
|
|
71
|
+
(72, 85, 115),
|
|
72
|
+
(147, 0, 96),
|
|
73
|
+
(160, 22, 253),
|
|
74
|
+
(144, 96, 251),
|
|
75
|
+
(64, 149, 178),
|
|
76
|
+
(182, 254, 244),
|
|
77
|
+
(47, 30, 32),
|
|
78
|
+
(5, 51, 149),
|
|
79
|
+
(138, 176, 198),
|
|
80
|
+
(71, 5, 144),
|
|
81
|
+
(2, 216, 42),
|
|
82
|
+
(73, 208, 226),
|
|
83
|
+
(109, 235, 121),
|
|
84
|
+
(161, 87, 139),
|
|
85
|
+
(120, 221, 46),
|
|
86
|
+
(114, 73, 187),
|
|
87
|
+
(149, 33, 8),
|
|
88
|
+
(207, 218, 117),
|
|
89
|
+
(42, 253, 212),
|
|
90
|
+
(189, 154, 12),
|
|
91
|
+
(1, 0, 56),
|
|
92
|
+
(106, 154, 114),
|
|
93
|
+
(230, 130, 245),
|
|
94
|
+
(3, 149, 73),
|
|
95
|
+
(210, 52, 252),
|
|
96
|
+
(254, 234, 63),
|
|
97
|
+
(216, 159, 83),
|
|
98
|
+
(52, 227, 152),
|
|
99
|
+
(211, 187, 204),
|
|
100
|
+
(0, 142, 181),
|
|
101
|
+
(44, 76, 58),
|
|
102
|
+
(127, 98, 89),
|
|
103
|
+
(149, 209, 148),
|
|
104
|
+
(52, 130, 124),
|
|
105
|
+
(0, 102, 212),
|
|
106
|
+
(58, 198, 109),
|
|
107
|
+
(196, 50, 141),
|
|
108
|
+
(252, 163, 185),
|
|
109
|
+
(254, 207, 3),
|
|
110
|
+
(177, 15, 195),
|
|
111
|
+
(27, 187, 253),
|
|
112
|
+
(224, 79, 187),
|
|
113
|
+
(130, 221, 204),
|
|
114
|
+
(225, 216, 252),
|
|
115
|
+
(251, 0, 149),
|
|
116
|
+
(203, 47, 28),
|
|
117
|
+
(254, 167, 43),
|
|
118
|
+
(94, 96, 17),
|
|
119
|
+
(242, 49, 67),
|
|
120
|
+
(155, 253, 146),
|
|
121
|
+
(63, 42, 96),
|
|
122
|
+
(104, 166, 48),
|
|
123
|
+
(189, 122, 160),
|
|
124
|
+
(35, 36, 247),
|
|
125
|
+
(195, 93, 238),
|
|
126
|
+
(1, 253, 68),
|
|
127
|
+
(217, 95, 107),
|
|
128
|
+
(140, 4, 150),
|
|
129
|
+
(117, 13, 55),
|
|
130
|
+
(93, 45, 0),
|
|
131
|
+
(0, 58, 28),
|
|
132
|
+
(80, 254, 28),
|
|
133
|
+
(165, 200, 34),
|
|
134
|
+
(123, 134, 205),
|
|
135
|
+
(34, 111, 254),
|
|
136
|
+
(208, 18, 86),
|
|
137
|
+
(254, 35, 248),
|
|
138
|
+
(228, 251, 199),
|
|
139
|
+
(64, 2, 202),
|
|
140
|
+
(65, 50, 144),
|
|
141
|
+
(164, 87, 53),
|
|
142
|
+
(113, 254, 75),
|
|
143
|
+
(1, 40, 205),
|
|
144
|
+
(218, 254, 88),
|
|
145
|
+
(154, 98, 193),
|
|
146
|
+
(58, 147, 230),
|
|
147
|
+
(47, 254, 117),
|
|
148
|
+
(145, 137, 254),
|
|
149
|
+
(249, 95, 1),
|
|
150
|
+
(78, 177, 4),
|
|
151
|
+
(128, 42, 216),
|
|
152
|
+
(207, 253, 146),
|
|
153
|
+
(150, 143, 134),
|
|
154
|
+
(52, 78, 230),
|
|
155
|
+
(153, 41, 162),
|
|
156
|
+
(137, 42, 83),
|
|
157
|
+
(185, 112, 1),
|
|
158
|
+
(121, 200, 246),
|
|
159
|
+
(173, 158, 61),
|
|
160
|
+
(10, 203, 146),
|
|
161
|
+
(203, 127, 53),
|
|
162
|
+
(109, 210, 1),
|
|
163
|
+
(43, 143, 38),
|
|
164
|
+
(51, 176, 146),
|
|
165
|
+
(71, 254, 252),
|
|
166
|
+
(221, 145, 132),
|
|
167
|
+
(7, 188, 82),
|
|
168
|
+
(100, 198, 82),
|
|
169
|
+
(90, 179, 200),
|
|
170
|
+
(101, 34, 172),
|
|
171
|
+
(1, 228, 205),
|
|
172
|
+
(205, 163, 245),
|
|
173
|
+
(200, 210, 0),
|
|
174
|
+
(111, 157, 166),
|
|
175
|
+
(152, 254, 208),
|
|
176
|
+
(22, 73, 118),
|
|
177
|
+
(165, 62, 254),
|
|
178
|
+
(254, 84, 59),
|
|
179
|
+
(58, 162, 100),
|
|
180
|
+
(227, 16, 33),
|
|
181
|
+
(233, 30, 124),
|
|
182
|
+
(247, 200, 81),
|
|
183
|
+
(167, 29, 114),
|
|
184
|
+
(230, 177, 1),
|
|
185
|
+
(212, 149, 187),
|
|
186
|
+
(224, 5, 188),
|
|
187
|
+
(153, 248, 40),
|
|
188
|
+
(181, 210, 79),
|
|
189
|
+
(121, 1, 247),
|
|
190
|
+
(115, 78, 140),
|
|
191
|
+
(224, 201, 157),
|
|
192
|
+
(84, 30, 222),
|
|
193
|
+
(33, 248, 35),
|
|
194
|
+
(6, 124, 142),
|
|
195
|
+
(80, 97, 157),
|
|
196
|
+
(216, 113, 201),
|
|
197
|
+
(24, 109, 67),
|
|
198
|
+
]
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
from label_studio_sdk.converter.imports.colors import COLORS
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
LABELS = """
|
|
5
|
+
<{# TAG_NAME #} name="{# FROM_NAME #}" toName="image">
|
|
6
|
+
{# LABELS #} </{# TAG_NAME #}>
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
LABELING_CONFIG = """<View>
|
|
10
|
+
<Image name="{# TO_NAME #}" value="$image"/>
|
|
11
|
+
{# BODY #}</View>
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def generate_label_config(
|
|
16
|
+
categories, tags, to_name="image", from_name="label", filename=None
|
|
17
|
+
):
|
|
18
|
+
labels = ""
|
|
19
|
+
for key in sorted(categories.keys()):
|
|
20
|
+
color = COLORS[int(key) % len(COLORS)]
|
|
21
|
+
label = f' <Label value="{categories[key]}" background="rgba({color[0]}, {color[1]}, {color[2]}, 1)"/>\n'
|
|
22
|
+
labels += label
|
|
23
|
+
|
|
24
|
+
body = ""
|
|
25
|
+
for from_name in tags:
|
|
26
|
+
tag_body = (
|
|
27
|
+
str(LABELS)
|
|
28
|
+
.replace("{# TAG_NAME #}", tags[from_name])
|
|
29
|
+
.replace("{# LABELS #}", labels)
|
|
30
|
+
.replace("{# TO_NAME #}", to_name)
|
|
31
|
+
.replace("{# FROM_NAME #}", from_name)
|
|
32
|
+
)
|
|
33
|
+
body += f'\n <Header value="{tags[from_name]}"/>' + tag_body
|
|
34
|
+
|
|
35
|
+
config = (
|
|
36
|
+
str(LABELING_CONFIG)
|
|
37
|
+
.replace("{# BODY #}", body)
|
|
38
|
+
.replace("{# TO_NAME #}", to_name)
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
if filename:
|
|
42
|
+
with open(filename, "w") as f:
|
|
43
|
+
f.write(config)
|
|
44
|
+
|
|
45
|
+
return config
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
"""PathTrack BBoxes to Label Studio convert
|
|
2
|
+
https://www.trace.ethz.ch/publications/2017/pathtrack/index.html
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import sys
|
|
7
|
+
import json
|
|
8
|
+
import uuid
|
|
9
|
+
import logging
|
|
10
|
+
|
|
11
|
+
from types import SimpleNamespace
|
|
12
|
+
|
|
13
|
+
logger = logging.getLogger()
|
|
14
|
+
logger.setLevel(logging.DEBUG)
|
|
15
|
+
|
|
16
|
+
handler = logging.StreamHandler(sys.stdout)
|
|
17
|
+
handler.setLevel(logging.DEBUG)
|
|
18
|
+
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
|
|
19
|
+
handler.setFormatter(formatter)
|
|
20
|
+
logger.addHandler(handler)
|
|
21
|
+
|
|
22
|
+
try:
|
|
23
|
+
import bs4
|
|
24
|
+
except ImportError:
|
|
25
|
+
logger.info('To use PathTrack convert do "pip install bs4"')
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def get_labels():
|
|
29
|
+
return {i: "Other" for i in range(0, 1000)}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def get_info(path):
|
|
33
|
+
with open(path) as f:
|
|
34
|
+
b = bs4.BeautifulSoup(f.read())
|
|
35
|
+
return SimpleNamespace(
|
|
36
|
+
fps=float(b.root.doc.fps.get_text()),
|
|
37
|
+
original_width=int(b.root.doc.imw.get_text()),
|
|
38
|
+
original_height=int(b.root.doc.imh.get_text()),
|
|
39
|
+
frame_count=int(b.root.doc.num_frames.get_text()),
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def new_task(data, result, ground_truth=False, model_version=None, score=None):
|
|
44
|
+
"""
|
|
45
|
+
:param data: dict
|
|
46
|
+
:param result: annotation results with regions
|
|
47
|
+
:param ground_truth: only for annotations
|
|
48
|
+
:param model_version: if not None, there will be prediction
|
|
49
|
+
:param score: prediction score, used only if model_version is not None
|
|
50
|
+
"""
|
|
51
|
+
task = {"data": data}
|
|
52
|
+
|
|
53
|
+
# add predictions or annotations
|
|
54
|
+
if model_version:
|
|
55
|
+
task["predictions"] = [
|
|
56
|
+
{"result": result, "model_version": model_version, "score": score}
|
|
57
|
+
]
|
|
58
|
+
else:
|
|
59
|
+
task["annotations"] = [{"result": result, "ground_truth": ground_truth}]
|
|
60
|
+
|
|
61
|
+
return task
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def new_region(labels, info, from_name, to_name):
|
|
65
|
+
region = {
|
|
66
|
+
"id": uuid.uuid4().hex[0:10],
|
|
67
|
+
"type": "videorectangle",
|
|
68
|
+
"value": {"sequence": [], "framesCount": info.frame_count},
|
|
69
|
+
"origin": "manual",
|
|
70
|
+
"to_name": to_name,
|
|
71
|
+
"from_name": from_name,
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if labels is not None:
|
|
75
|
+
region["value"]["labels"] = labels
|
|
76
|
+
|
|
77
|
+
return region
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def new_keyframe(region, bbox, info):
|
|
81
|
+
region["value"]["sequence"].append(
|
|
82
|
+
{
|
|
83
|
+
"x": bbox.x / info.original_width * 100,
|
|
84
|
+
"y": bbox.y / info.original_height * 100,
|
|
85
|
+
"width": bbox.width / info.original_width * 100,
|
|
86
|
+
"height": bbox.height / info.original_height * 100,
|
|
87
|
+
"time": bbox.frame / info.fps,
|
|
88
|
+
"frame": bbox.frame,
|
|
89
|
+
"enabled": False,
|
|
90
|
+
"rotation": 0,
|
|
91
|
+
}
|
|
92
|
+
)
|
|
93
|
+
return region
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def generator(path):
|
|
97
|
+
with open(path) as f:
|
|
98
|
+
lines = f.readlines()
|
|
99
|
+
|
|
100
|
+
for line in lines:
|
|
101
|
+
v = line.split()
|
|
102
|
+
yield SimpleNamespace(
|
|
103
|
+
frame=int(v[0]),
|
|
104
|
+
bbox_id=int(v[1]),
|
|
105
|
+
label_id=int(v[1]),
|
|
106
|
+
x=int(v[2]),
|
|
107
|
+
y=int(v[3]),
|
|
108
|
+
width=int(v[4]),
|
|
109
|
+
height=int(v[5]),
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def create_config(
|
|
114
|
+
from_name="box", to_name="video", source_value="video", target_fps=None
|
|
115
|
+
):
|
|
116
|
+
return f"""<View>
|
|
117
|
+
<Header>Label the video:</Header>
|
|
118
|
+
<Video name="{to_name}" value="${source_value}" framerate="{target_fps}"/>
|
|
119
|
+
<VideoRectangle name="{from_name}" toName="{to_name}" />
|
|
120
|
+
<Labels name="videoLabels" toName="{to_name}" allowEmpty="true">
|
|
121
|
+
<Label value="Man" background="blue"/>
|
|
122
|
+
<Label value="Woman" background="red"/>
|
|
123
|
+
<Label value="Other" background="green"/>
|
|
124
|
+
</Labels>
|
|
125
|
+
</View>
|
|
126
|
+
"""
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def convert_shot(
|
|
130
|
+
input_url,
|
|
131
|
+
label_file,
|
|
132
|
+
info_file,
|
|
133
|
+
from_name="box",
|
|
134
|
+
to_name="video",
|
|
135
|
+
source_value="video",
|
|
136
|
+
target_fps=None,
|
|
137
|
+
hop_keyframes=0,
|
|
138
|
+
):
|
|
139
|
+
"""Convert bounding boxes from PathTrack to Label Studio video format
|
|
140
|
+
|
|
141
|
+
:param input_url: video file
|
|
142
|
+
:param label_file: text file with annotations line by line
|
|
143
|
+
:param info_file: info.xml with frame rate and other useful info
|
|
144
|
+
:param from_name: control tag name from Label Studio labeling config
|
|
145
|
+
:param to_name: object name from Label Studio labeling config
|
|
146
|
+
:param source_value: source name for Video tag, e.g. $video
|
|
147
|
+
:param target_fps: keep video with this fps only
|
|
148
|
+
:param hop_keyframes: how many keyframes to skip
|
|
149
|
+
"""
|
|
150
|
+
logger.info("Converting of the shot is starting: %s", input_url)
|
|
151
|
+
if not os.path.exists(label_file):
|
|
152
|
+
return None
|
|
153
|
+
|
|
154
|
+
info = get_info(info_file)
|
|
155
|
+
if target_fps is not None and info.fps != target_fps:
|
|
156
|
+
return None
|
|
157
|
+
|
|
158
|
+
label_map = get_labels()
|
|
159
|
+
regions = {}
|
|
160
|
+
keyframe_count = 0
|
|
161
|
+
|
|
162
|
+
# convert all bounding boxes to Label Studio Results
|
|
163
|
+
for v in generator(label_file):
|
|
164
|
+
idx = v.label_id
|
|
165
|
+
if idx in regions:
|
|
166
|
+
region = regions[idx]
|
|
167
|
+
else:
|
|
168
|
+
labels = [label_map[idx]] if idx in label_map else None
|
|
169
|
+
region = regions[idx] = new_region(labels, info, from_name, to_name)
|
|
170
|
+
|
|
171
|
+
# enable previous lifespan
|
|
172
|
+
if len(regions[idx]["value"]["sequence"]) > 0:
|
|
173
|
+
regions[idx]["value"]["sequence"][-1]["enabled"] = True
|
|
174
|
+
|
|
175
|
+
regions[idx] = new_keyframe(region, bbox=v, info=info)
|
|
176
|
+
keyframe_count += 1
|
|
177
|
+
|
|
178
|
+
# keep only each <hop> keyframe
|
|
179
|
+
if hop_keyframes > 1:
|
|
180
|
+
for r in regions:
|
|
181
|
+
last = regions[r]["value"]["sequence"][-1]
|
|
182
|
+
regions[r]["value"]["sequence"] = regions[r]["value"]["sequence"][
|
|
183
|
+
0:-1:hop_keyframes
|
|
184
|
+
]
|
|
185
|
+
if regions[r]["value"]["sequence"][-1] != last:
|
|
186
|
+
regions[r]["value"]["sequence"].append(last)
|
|
187
|
+
|
|
188
|
+
logger.info(
|
|
189
|
+
"Shot with %i regions and %i keyframes created", len(regions), keyframe_count
|
|
190
|
+
)
|
|
191
|
+
data = {source_value: input_url}
|
|
192
|
+
return new_task(data, result=list(regions.values()))
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def convert_dataset(
|
|
196
|
+
root_dir,
|
|
197
|
+
root_url,
|
|
198
|
+
from_name="box",
|
|
199
|
+
to_name="video",
|
|
200
|
+
source_value="video",
|
|
201
|
+
target_fps=None,
|
|
202
|
+
hop_keyframes=0,
|
|
203
|
+
):
|
|
204
|
+
"""Convert PathTrack dataset to Label Studio video labeling format
|
|
205
|
+
|
|
206
|
+
:param root_dir: root dir with video folders, e.g.: 'pathtrack/train' or 'pathtrack/test'
|
|
207
|
+
:param root_url: where the dataset is served by http/https
|
|
208
|
+
:param to_name: object name from Label Studio labeling config
|
|
209
|
+
:param from_name: control tag name from Label Studio labeling config
|
|
210
|
+
:param source_value: source name for Video tag, e.g. $video
|
|
211
|
+
:param target_fps: keep video with this fps only
|
|
212
|
+
:param hop_keyframes: how many keyframes to skip
|
|
213
|
+
"""
|
|
214
|
+
logger.info("Convert dataset start: %s", root_dir)
|
|
215
|
+
tasks = []
|
|
216
|
+
|
|
217
|
+
if not root_url.endswith("/"):
|
|
218
|
+
root_url += "/"
|
|
219
|
+
|
|
220
|
+
for d in os.listdir(root_dir):
|
|
221
|
+
shot_dir = os.path.join(root_dir, d)
|
|
222
|
+
if not os.path.isdir(shot_dir):
|
|
223
|
+
continue
|
|
224
|
+
|
|
225
|
+
input_url = root_url + d + "/video.mp4"
|
|
226
|
+
label_file = os.path.join(shot_dir, "gt/gt.txt")
|
|
227
|
+
info_file = os.path.join(shot_dir, "info.xml")
|
|
228
|
+
|
|
229
|
+
task = convert_shot(
|
|
230
|
+
input_url,
|
|
231
|
+
label_file,
|
|
232
|
+
info_file,
|
|
233
|
+
from_name,
|
|
234
|
+
to_name,
|
|
235
|
+
source_value,
|
|
236
|
+
target_fps,
|
|
237
|
+
hop_keyframes,
|
|
238
|
+
)
|
|
239
|
+
if task is None:
|
|
240
|
+
continue
|
|
241
|
+
|
|
242
|
+
tasks.append(task)
|
|
243
|
+
|
|
244
|
+
fps_name = int(target_fps)
|
|
245
|
+
path = os.path.join(root_dir, f"import-{fps_name}.json")
|
|
246
|
+
logger.info("Saving Label Studio JSON: %s", path)
|
|
247
|
+
with open(path, "w") as f:
|
|
248
|
+
json.dump(tasks, f)
|
|
249
|
+
|
|
250
|
+
path = os.path.join(root_dir, f"config-{fps_name}.xml")
|
|
251
|
+
logger.info("Saving Labeling Config: %s", path)
|
|
252
|
+
config = create_config(from_name, to_name, source_value, target_fps)
|
|
253
|
+
with open(path, "w") as f:
|
|
254
|
+
f.write(config)
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
if __name__ == "__main__":
|
|
258
|
+
# convert_dataset('../../tests', 'https://data.heartex.net/pathtrack/train/')
|
|
259
|
+
# exit()
|
|
260
|
+
print(f"Usage: {sys.argv[0]} root_url target_fps\n")
|
|
261
|
+
|
|
262
|
+
url = (
|
|
263
|
+
sys.argv[1]
|
|
264
|
+
if len(sys.argv) > 1
|
|
265
|
+
else "https://data.heartex.net/pathtrack/train/"
|
|
266
|
+
)
|
|
267
|
+
fps = float(sys.argv[2]) if len(sys.argv) > 2 else None
|
|
268
|
+
hop = int(sys.argv[3]) if len(sys.argv) > 3 else 0
|
|
269
|
+
convert_dataset("./", url, target_fps=fps, hop_keyframes=hop)
|