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