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.
Files changed (256) hide show
  1. label_studio_sdk/__init__.py +206 -9
  2. label_studio_sdk/_extensions/label_studio_tools/__init__.py +0 -0
  3. label_studio_sdk/_extensions/label_studio_tools/core/__init__.py +0 -0
  4. label_studio_sdk/_extensions/label_studio_tools/core/label_config.py +163 -0
  5. label_studio_sdk/_extensions/label_studio_tools/core/utils/__init__.py +0 -0
  6. label_studio_sdk/_extensions/label_studio_tools/core/utils/exceptions.py +2 -0
  7. label_studio_sdk/_extensions/label_studio_tools/core/utils/io.py +228 -0
  8. label_studio_sdk/_extensions/label_studio_tools/core/utils/params.py +45 -0
  9. label_studio_sdk/_extensions/label_studio_tools/etl/__init__.py +1 -0
  10. label_studio_sdk/_extensions/label_studio_tools/etl/beam.py +34 -0
  11. label_studio_sdk/_extensions/label_studio_tools/etl/example.py +17 -0
  12. label_studio_sdk/_extensions/label_studio_tools/etl/registry.py +67 -0
  13. label_studio_sdk/_extensions/label_studio_tools/postprocessing/__init__.py +0 -0
  14. label_studio_sdk/_extensions/label_studio_tools/postprocessing/video.py +97 -0
  15. label_studio_sdk/_legacy/__init__.py +11 -0
  16. label_studio_sdk/_legacy/client.py +471 -0
  17. label_studio_sdk/_legacy/label_interface/data_examples.json +96 -0
  18. label_studio_sdk/{label_interface → _legacy/label_interface}/interface.py +9 -6
  19. label_studio_sdk/{project.py → _legacy/project.py} +2 -2
  20. label_studio_sdk/actions/__init__.py +2 -0
  21. label_studio_sdk/actions/client.py +150 -0
  22. label_studio_sdk/annotations/__init__.py +2 -0
  23. label_studio_sdk/annotations/client.py +750 -0
  24. label_studio_sdk/client.py +162 -450
  25. label_studio_sdk/converter/__init__.py +7 -0
  26. label_studio_sdk/converter/audio.py +56 -0
  27. label_studio_sdk/converter/brush.py +452 -0
  28. label_studio_sdk/converter/converter.py +1175 -0
  29. label_studio_sdk/converter/exports/__init__.py +0 -0
  30. label_studio_sdk/converter/exports/csv.py +82 -0
  31. label_studio_sdk/converter/exports/csv2.py +103 -0
  32. label_studio_sdk/converter/funsd.py +85 -0
  33. label_studio_sdk/converter/imports/__init__.py +0 -0
  34. label_studio_sdk/converter/imports/coco.py +314 -0
  35. label_studio_sdk/converter/imports/colors.py +198 -0
  36. label_studio_sdk/converter/imports/label_config.py +45 -0
  37. label_studio_sdk/converter/imports/pathtrack.py +269 -0
  38. label_studio_sdk/converter/imports/yolo.py +236 -0
  39. label_studio_sdk/converter/main.py +202 -0
  40. label_studio_sdk/converter/utils.py +473 -0
  41. label_studio_sdk/core/__init__.py +33 -0
  42. label_studio_sdk/core/api_error.py +15 -0
  43. label_studio_sdk/core/client_wrapper.py +55 -0
  44. label_studio_sdk/core/datetime_utils.py +28 -0
  45. label_studio_sdk/core/file.py +38 -0
  46. label_studio_sdk/core/http_client.py +443 -0
  47. label_studio_sdk/core/jsonable_encoder.py +99 -0
  48. label_studio_sdk/core/pagination.py +87 -0
  49. label_studio_sdk/core/pydantic_utilities.py +28 -0
  50. label_studio_sdk/core/query_encoder.py +33 -0
  51. label_studio_sdk/core/remove_none_from_dict.py +11 -0
  52. label_studio_sdk/core/request_options.py +32 -0
  53. label_studio_sdk/environment.py +7 -0
  54. label_studio_sdk/errors/__init__.py +6 -0
  55. label_studio_sdk/errors/bad_request_error.py +8 -0
  56. label_studio_sdk/errors/internal_server_error.py +8 -0
  57. label_studio_sdk/export_storage/__init__.py +28 -0
  58. label_studio_sdk/export_storage/azure/__init__.py +5 -0
  59. label_studio_sdk/export_storage/azure/client.py +722 -0
  60. label_studio_sdk/export_storage/azure/types/__init__.py +6 -0
  61. label_studio_sdk/export_storage/azure/types/azure_create_response.py +52 -0
  62. label_studio_sdk/export_storage/azure/types/azure_update_response.py +52 -0
  63. label_studio_sdk/export_storage/client.py +107 -0
  64. label_studio_sdk/export_storage/gcs/__init__.py +5 -0
  65. label_studio_sdk/export_storage/gcs/client.py +722 -0
  66. label_studio_sdk/export_storage/gcs/types/__init__.py +6 -0
  67. label_studio_sdk/export_storage/gcs/types/gcs_create_response.py +52 -0
  68. label_studio_sdk/export_storage/gcs/types/gcs_update_response.py +52 -0
  69. label_studio_sdk/export_storage/local/__init__.py +5 -0
  70. label_studio_sdk/export_storage/local/client.py +688 -0
  71. label_studio_sdk/export_storage/local/types/__init__.py +6 -0
  72. label_studio_sdk/export_storage/local/types/local_create_response.py +47 -0
  73. label_studio_sdk/export_storage/local/types/local_update_response.py +47 -0
  74. label_studio_sdk/export_storage/redis/__init__.py +5 -0
  75. label_studio_sdk/export_storage/redis/client.py +714 -0
  76. label_studio_sdk/export_storage/redis/types/__init__.py +6 -0
  77. label_studio_sdk/export_storage/redis/types/redis_create_response.py +57 -0
  78. label_studio_sdk/export_storage/redis/types/redis_update_response.py +57 -0
  79. label_studio_sdk/export_storage/s3/__init__.py +5 -0
  80. label_studio_sdk/export_storage/s3/client.py +820 -0
  81. label_studio_sdk/export_storage/s3/types/__init__.py +6 -0
  82. label_studio_sdk/export_storage/s3/types/s3create_response.py +74 -0
  83. label_studio_sdk/export_storage/s3/types/s3update_response.py +74 -0
  84. label_studio_sdk/export_storage/types/__init__.py +5 -0
  85. label_studio_sdk/export_storage/types/export_storage_list_types_response_item.py +30 -0
  86. label_studio_sdk/files/__init__.py +2 -0
  87. label_studio_sdk/files/client.py +556 -0
  88. label_studio_sdk/import_storage/__init__.py +28 -0
  89. label_studio_sdk/import_storage/azure/__init__.py +5 -0
  90. label_studio_sdk/import_storage/azure/client.py +812 -0
  91. label_studio_sdk/import_storage/azure/types/__init__.py +6 -0
  92. label_studio_sdk/import_storage/azure/types/azure_create_response.py +72 -0
  93. label_studio_sdk/import_storage/azure/types/azure_update_response.py +72 -0
  94. label_studio_sdk/import_storage/client.py +107 -0
  95. label_studio_sdk/import_storage/gcs/__init__.py +5 -0
  96. label_studio_sdk/import_storage/gcs/client.py +812 -0
  97. label_studio_sdk/import_storage/gcs/types/__init__.py +6 -0
  98. label_studio_sdk/import_storage/gcs/types/gcs_create_response.py +72 -0
  99. label_studio_sdk/import_storage/gcs/types/gcs_update_response.py +72 -0
  100. label_studio_sdk/import_storage/local/__init__.py +5 -0
  101. label_studio_sdk/import_storage/local/client.py +690 -0
  102. label_studio_sdk/import_storage/local/types/__init__.py +6 -0
  103. label_studio_sdk/import_storage/local/types/local_create_response.py +47 -0
  104. label_studio_sdk/import_storage/local/types/local_update_response.py +47 -0
  105. label_studio_sdk/import_storage/redis/__init__.py +5 -0
  106. label_studio_sdk/import_storage/redis/client.py +768 -0
  107. label_studio_sdk/import_storage/redis/types/__init__.py +6 -0
  108. label_studio_sdk/import_storage/redis/types/redis_create_response.py +62 -0
  109. label_studio_sdk/import_storage/redis/types/redis_update_response.py +62 -0
  110. label_studio_sdk/import_storage/s3/__init__.py +5 -0
  111. label_studio_sdk/import_storage/s3/client.py +912 -0
  112. label_studio_sdk/import_storage/s3/types/__init__.py +6 -0
  113. label_studio_sdk/import_storage/s3/types/s3create_response.py +99 -0
  114. label_studio_sdk/import_storage/s3/types/s3update_response.py +99 -0
  115. label_studio_sdk/import_storage/types/__init__.py +5 -0
  116. label_studio_sdk/import_storage/types/import_storage_list_types_response_item.py +30 -0
  117. label_studio_sdk/ml/__init__.py +19 -0
  118. label_studio_sdk/ml/client.py +981 -0
  119. label_studio_sdk/ml/types/__init__.py +17 -0
  120. label_studio_sdk/ml/types/ml_create_request_auth_method.py +5 -0
  121. label_studio_sdk/ml/types/ml_create_response.py +78 -0
  122. label_studio_sdk/ml/types/ml_create_response_auth_method.py +5 -0
  123. label_studio_sdk/ml/types/ml_update_request_auth_method.py +5 -0
  124. label_studio_sdk/ml/types/ml_update_response.py +78 -0
  125. label_studio_sdk/ml/types/ml_update_response_auth_method.py +5 -0
  126. label_studio_sdk/predictions/__init__.py +2 -0
  127. label_studio_sdk/predictions/client.py +638 -0
  128. label_studio_sdk/projects/__init__.py +6 -0
  129. label_studio_sdk/projects/client.py +1053 -0
  130. label_studio_sdk/projects/exports/__init__.py +2 -0
  131. label_studio_sdk/projects/exports/client.py +930 -0
  132. label_studio_sdk/projects/types/__init__.py +7 -0
  133. label_studio_sdk/projects/types/projects_create_response.py +96 -0
  134. label_studio_sdk/projects/types/projects_import_tasks_response.py +71 -0
  135. label_studio_sdk/projects/types/projects_list_response.py +33 -0
  136. label_studio_sdk/py.typed +0 -0
  137. label_studio_sdk/tasks/__init__.py +5 -0
  138. label_studio_sdk/tasks/client.py +811 -0
  139. label_studio_sdk/tasks/types/__init__.py +6 -0
  140. label_studio_sdk/tasks/types/tasks_list_request_fields.py +5 -0
  141. label_studio_sdk/tasks/types/tasks_list_response.py +48 -0
  142. label_studio_sdk/types/__init__.py +115 -0
  143. label_studio_sdk/types/annotation.py +116 -0
  144. label_studio_sdk/types/annotation_filter_options.py +42 -0
  145. label_studio_sdk/types/annotation_last_action.py +19 -0
  146. label_studio_sdk/types/azure_blob_export_storage.py +112 -0
  147. label_studio_sdk/types/azure_blob_export_storage_status.py +7 -0
  148. label_studio_sdk/types/azure_blob_import_storage.py +113 -0
  149. label_studio_sdk/types/azure_blob_import_storage_status.py +7 -0
  150. label_studio_sdk/types/base_task.py +113 -0
  151. label_studio_sdk/types/base_user.py +42 -0
  152. label_studio_sdk/types/converted_format.py +36 -0
  153. label_studio_sdk/types/converted_format_status.py +5 -0
  154. label_studio_sdk/types/export.py +48 -0
  155. label_studio_sdk/types/export_convert.py +32 -0
  156. label_studio_sdk/types/export_create.py +54 -0
  157. label_studio_sdk/types/export_create_status.py +5 -0
  158. label_studio_sdk/types/export_status.py +5 -0
  159. label_studio_sdk/types/file_upload.py +30 -0
  160. label_studio_sdk/types/filter.py +53 -0
  161. label_studio_sdk/types/filter_group.py +35 -0
  162. label_studio_sdk/types/gcs_export_storage.py +112 -0
  163. label_studio_sdk/types/gcs_export_storage_status.py +7 -0
  164. label_studio_sdk/types/gcs_import_storage.py +113 -0
  165. label_studio_sdk/types/gcs_import_storage_status.py +7 -0
  166. label_studio_sdk/types/local_files_export_storage.py +97 -0
  167. label_studio_sdk/types/local_files_export_storage_status.py +7 -0
  168. label_studio_sdk/types/local_files_import_storage.py +92 -0
  169. label_studio_sdk/types/local_files_import_storage_status.py +7 -0
  170. label_studio_sdk/types/ml_backend.py +89 -0
  171. label_studio_sdk/types/ml_backend_auth_method.py +5 -0
  172. label_studio_sdk/types/ml_backend_state.py +5 -0
  173. label_studio_sdk/types/prediction.py +78 -0
  174. label_studio_sdk/types/project.py +198 -0
  175. label_studio_sdk/types/project_import.py +63 -0
  176. label_studio_sdk/types/project_import_status.py +5 -0
  177. label_studio_sdk/types/project_label_config.py +32 -0
  178. label_studio_sdk/types/project_sampling.py +7 -0
  179. label_studio_sdk/types/project_skip_queue.py +5 -0
  180. label_studio_sdk/types/redis_export_storage.py +117 -0
  181. label_studio_sdk/types/redis_export_storage_status.py +7 -0
  182. label_studio_sdk/types/redis_import_storage.py +112 -0
  183. label_studio_sdk/types/redis_import_storage_status.py +7 -0
  184. label_studio_sdk/types/s3export_storage.py +134 -0
  185. label_studio_sdk/types/s3export_storage_status.py +7 -0
  186. label_studio_sdk/types/s3import_storage.py +140 -0
  187. label_studio_sdk/types/s3import_storage_status.py +7 -0
  188. label_studio_sdk/types/serialization_option.py +36 -0
  189. label_studio_sdk/types/serialization_options.py +45 -0
  190. label_studio_sdk/types/task.py +157 -0
  191. label_studio_sdk/types/task_filter_options.py +49 -0
  192. label_studio_sdk/types/user_simple.py +37 -0
  193. label_studio_sdk/types/view.py +55 -0
  194. label_studio_sdk/types/webhook.py +67 -0
  195. label_studio_sdk/types/webhook_actions_item.py +21 -0
  196. label_studio_sdk/types/webhook_serializer_for_update.py +67 -0
  197. label_studio_sdk/types/webhook_serializer_for_update_actions_item.py +21 -0
  198. label_studio_sdk/users/__init__.py +5 -0
  199. label_studio_sdk/users/client.py +830 -0
  200. label_studio_sdk/users/types/__init__.py +6 -0
  201. label_studio_sdk/users/types/users_get_token_response.py +36 -0
  202. label_studio_sdk/users/types/users_reset_token_response.py +36 -0
  203. label_studio_sdk/version.py +4 -0
  204. label_studio_sdk/views/__init__.py +31 -0
  205. label_studio_sdk/views/client.py +564 -0
  206. label_studio_sdk/views/types/__init__.py +29 -0
  207. label_studio_sdk/views/types/views_create_request_data.py +43 -0
  208. label_studio_sdk/views/types/views_create_request_data_filters.py +43 -0
  209. label_studio_sdk/views/types/views_create_request_data_filters_conjunction.py +5 -0
  210. label_studio_sdk/views/types/views_create_request_data_filters_items_item.py +47 -0
  211. label_studio_sdk/views/types/views_create_request_data_ordering_item.py +38 -0
  212. label_studio_sdk/views/types/views_create_request_data_ordering_item_direction.py +5 -0
  213. label_studio_sdk/views/types/views_update_request_data.py +43 -0
  214. label_studio_sdk/views/types/views_update_request_data_filters.py +43 -0
  215. label_studio_sdk/views/types/views_update_request_data_filters_conjunction.py +5 -0
  216. label_studio_sdk/views/types/views_update_request_data_filters_items_item.py +47 -0
  217. label_studio_sdk/views/types/views_update_request_data_ordering_item.py +38 -0
  218. label_studio_sdk/views/types/views_update_request_data_ordering_item_direction.py +5 -0
  219. label_studio_sdk/webhooks/__init__.py +5 -0
  220. label_studio_sdk/webhooks/client.py +636 -0
  221. label_studio_sdk/webhooks/types/__init__.py +5 -0
  222. label_studio_sdk/webhooks/types/webhooks_update_request_actions_item.py +21 -0
  223. label_studio_sdk-1.0.0.dist-info/METADATA +307 -0
  224. label_studio_sdk-1.0.0.dist-info/RECORD +239 -0
  225. {label_studio_sdk-0.0.34.dist-info → label_studio_sdk-1.0.0.dist-info}/WHEEL +1 -2
  226. label_studio_sdk-0.0.34.dist-info/LICENSE +0 -201
  227. label_studio_sdk-0.0.34.dist-info/METADATA +0 -24
  228. label_studio_sdk-0.0.34.dist-info/RECORD +0 -37
  229. label_studio_sdk-0.0.34.dist-info/top_level.txt +0 -2
  230. tests/test_client.py +0 -37
  231. tests/test_export.py +0 -105
  232. tests/test_interface/__init__.py +0 -1
  233. tests/test_interface/configs.py +0 -137
  234. tests/test_interface/mockups.py +0 -22
  235. tests/test_interface/test_compat.py +0 -64
  236. tests/test_interface/test_control_tags.py +0 -55
  237. tests/test_interface/test_data_generation.py +0 -45
  238. tests/test_interface/test_lpi.py +0 -15
  239. tests/test_interface/test_main.py +0 -196
  240. tests/test_interface/test_object_tags.py +0 -36
  241. tests/test_interface/test_region.py +0 -36
  242. tests/test_interface/test_validate_summary.py +0 -35
  243. tests/test_interface/test_validation.py +0 -59
  244. {tests → label_studio_sdk/_extensions}/__init__.py +0 -0
  245. /label_studio_sdk/{exceptions.py → _legacy/exceptions.py} +0 -0
  246. /label_studio_sdk/{label_interface → _legacy/label_interface}/__init__.py +0 -0
  247. /label_studio_sdk/{label_interface → _legacy/label_interface}/base.py +0 -0
  248. /label_studio_sdk/{label_interface → _legacy/label_interface}/control_tags.py +0 -0
  249. /label_studio_sdk/{label_interface → _legacy/label_interface}/label_tags.py +0 -0
  250. /label_studio_sdk/{label_interface → _legacy/label_interface}/object_tags.py +0 -0
  251. /label_studio_sdk/{label_interface → _legacy/label_interface}/region.py +0 -0
  252. /label_studio_sdk/{objects.py → _legacy/objects.py} +0 -0
  253. /label_studio_sdk/{schema → _legacy/schema}/label_config_schema.json +0 -0
  254. /label_studio_sdk/{users.py → _legacy/users.py} +0 -0
  255. /label_studio_sdk/{utils.py → _legacy/utils.py} +0 -0
  256. /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)