label-studio-sdk 1.0.20__py3-none-any.whl → 2.0.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.
Potentially problematic release.
This version of label-studio-sdk might be problematic. Click here for more details.
- label_studio_sdk/__init__.py +345 -180
- label_studio_sdk/actions/__init__.py +4 -0
- label_studio_sdk/actions/client.py +46 -10
- label_studio_sdk/actions/types/__init__.py +4 -0
- label_studio_sdk/actions/types/actions_create_request_filters.py +2 -2
- label_studio_sdk/actions/types/actions_create_request_filters_items_item.py +2 -2
- label_studio_sdk/actions/types/actions_create_request_id.py +7 -7
- label_studio_sdk/actions/types/actions_create_request_selected_items_excluded.py +2 -2
- label_studio_sdk/actions/types/actions_create_request_selected_items_included.py +2 -2
- label_studio_sdk/actions/types/actions_list_response_item.py +25 -0
- label_studio_sdk/actions/types/actions_list_response_item_dialog.py +22 -0
- label_studio_sdk/annotations/__init__.py +2 -2
- label_studio_sdk/annotations/client.py +379 -243
- label_studio_sdk/annotations/types/__init__.py +4 -2
- label_studio_sdk/annotations/types/annotation_bulk_serializer_with_selected_items_request_last_action.py +7 -0
- label_studio_sdk/annotations/types/annotations_create_bulk_response_item.py +8 -5
- label_studio_sdk/base_client.py +32 -24
- label_studio_sdk/billing/__init__.py +2 -0
- label_studio_sdk/billing/client.py +112 -0
- label_studio_sdk/comments/client.py +378 -140
- label_studio_sdk/converter/README.md +207 -0
- label_studio_sdk/converter/imports/coco.py +132 -23
- label_studio_sdk/core/__init__.py +4 -0
- label_studio_sdk/core/unchecked_base_model.py +305 -0
- label_studio_sdk/environment.py +1 -1
- label_studio_sdk/errors/__init__.py +10 -1
- label_studio_sdk/errors/forbidden_error.py +9 -0
- label_studio_sdk/errors/method_not_allowed_error.py +9 -0
- label_studio_sdk/export_storage/__init__.py +1 -24
- label_studio_sdk/export_storage/azure/__init__.py +0 -3
- label_studio_sdk/export_storage/azure/client.py +231 -273
- label_studio_sdk/export_storage/client.py +5 -5
- label_studio_sdk/export_storage/gcs/__init__.py +0 -3
- label_studio_sdk/export_storage/gcs/client.py +231 -273
- label_studio_sdk/export_storage/local/__init__.py +0 -3
- label_studio_sdk/export_storage/local/client.py +211 -253
- label_studio_sdk/export_storage/redis/__init__.py +0 -3
- label_studio_sdk/export_storage/redis/client.py +239 -281
- label_studio_sdk/export_storage/s3/__init__.py +0 -3
- label_studio_sdk/export_storage/s3/client.py +254 -296
- label_studio_sdk/export_storage/s3s/client.py +694 -210
- label_studio_sdk/export_storage/types/export_storage_list_types_response_item.py +2 -2
- label_studio_sdk/files/client.py +52 -71
- label_studio_sdk/import_storage/__init__.py +1 -24
- label_studio_sdk/import_storage/azure/__init__.py +0 -3
- label_studio_sdk/import_storage/azure/client.py +249 -299
- label_studio_sdk/import_storage/client.py +5 -5
- label_studio_sdk/import_storage/gcs/__init__.py +0 -3
- label_studio_sdk/import_storage/gcs/client.py +249 -299
- label_studio_sdk/import_storage/local/__init__.py +0 -3
- label_studio_sdk/import_storage/local/client.py +211 -257
- label_studio_sdk/import_storage/redis/__init__.py +0 -3
- label_studio_sdk/import_storage/redis/client.py +239 -285
- label_studio_sdk/import_storage/s3/__init__.py +0 -3
- label_studio_sdk/import_storage/s3/client.py +274 -324
- label_studio_sdk/import_storage/s3s/client.py +728 -434
- label_studio_sdk/import_storage/types/import_storage_list_types_response_item.py +2 -2
- label_studio_sdk/jwt_settings/client.py +56 -58
- label_studio_sdk/label_interface/control_tags.py +48 -8
- label_studio_sdk/label_interface/interface.py +261 -56
- label_studio_sdk/ml/__init__.py +2 -16
- label_studio_sdk/ml/client.py +196 -179
- label_studio_sdk/ml/types/__init__.py +2 -12
- label_studio_sdk/ml/types/ml_list_model_versions_response.py +20 -0
- label_studio_sdk/model_providers/__init__.py +3 -0
- label_studio_sdk/model_providers/client.py +280 -228
- label_studio_sdk/model_providers/types/__init__.py +5 -0
- label_studio_sdk/{prompts/types/prompts_batch_predictions_response.py → model_providers/types/model_providers_list_model_provider_choices_response.py} +3 -3
- label_studio_sdk/organizations/__init__.py +5 -0
- label_studio_sdk/organizations/client.py +331 -0
- label_studio_sdk/organizations/members/__init__.py +2 -0
- label_studio_sdk/organizations/members/client.py +636 -0
- label_studio_sdk/predictions/client.py +29 -77
- label_studio_sdk/projects/__init__.py +18 -9
- label_studio_sdk/projects/client.py +905 -414
- label_studio_sdk/projects/exports/__init__.py +2 -2
- label_studio_sdk/projects/exports/client.py +336 -396
- label_studio_sdk/projects/exports/client_ext.py +30 -30
- label_studio_sdk/projects/exports/types/__init__.py +1 -2
- label_studio_sdk/projects/exports/types/exports_convert_response.py +5 -9
- label_studio_sdk/projects/pauses/client.py +114 -105
- label_studio_sdk/projects/stats/__init__.py +5 -0
- label_studio_sdk/projects/stats/client.py +175 -0
- label_studio_sdk/projects/stats/types/__init__.py +8 -0
- label_studio_sdk/projects/stats/types/stats_iaa_response.py +44 -0
- label_studio_sdk/projects/stats/types/stats_iaa_response_common_tasks.py +7 -0
- label_studio_sdk/projects/stats/types/stats_iaa_response_iaa.py +5 -0
- label_studio_sdk/{types/base_task_file_upload.py → projects/stats/types/stats_iaa_response_std.py} +1 -1
- label_studio_sdk/projects/types/__init__.py +10 -6
- label_studio_sdk/projects/types/lse_project_create_request_sampling.py +7 -0
- label_studio_sdk/projects/types/lse_project_create_request_skip_queue.py +7 -0
- label_studio_sdk/projects/types/patched_lse_project_update_request_sampling.py +7 -0
- label_studio_sdk/projects/types/patched_lse_project_update_request_skip_queue.py +7 -0
- label_studio_sdk/{prompts/types/prompts_batch_failed_predictions_response.py → projects/types/projects_duplicate_response.py} +8 -5
- label_studio_sdk/projects/types/projects_import_tasks_response.py +2 -2
- label_studio_sdk/projects/types/projects_list_request_filter.py +1 -1
- label_studio_sdk/prompts/__init__.py +4 -10
- label_studio_sdk/prompts/client.py +511 -442
- label_studio_sdk/prompts/indicators/__init__.py +3 -0
- label_studio_sdk/prompts/indicators/client.py +47 -49
- label_studio_sdk/prompts/indicators/types/__init__.py +5 -0
- label_studio_sdk/{types/key_indicator_value.py → prompts/indicators/types/indicators_list_response_item.py} +3 -3
- label_studio_sdk/prompts/runs/client.py +113 -135
- label_studio_sdk/prompts/types/__init__.py +2 -12
- label_studio_sdk/prompts/types/prompts_compatible_projects_request_project_type.py +7 -0
- label_studio_sdk/prompts/versions/client.py +372 -312
- label_studio_sdk/tasks/__init__.py +2 -2
- label_studio_sdk/tasks/client.py +514 -213
- label_studio_sdk/tasks/types/__init__.py +1 -2
- label_studio_sdk/tokens/client.py +160 -152
- label_studio_sdk/tokens/client_ext.py +3 -3
- label_studio_sdk/types/__init__.py +276 -142
- label_studio_sdk/{webhooks/types/webhooks_update_request_actions_item.py → types/actions_enum.py} +4 -1
- label_studio_sdk/types/all_roles_project_list.py +197 -0
- label_studio_sdk/types/all_roles_project_list_sampling.py +7 -0
- label_studio_sdk/types/all_roles_project_list_skip_queue.py +7 -0
- label_studio_sdk/types/annotated_enum.py +5 -0
- label_studio_sdk/types/annotation.py +24 -10
- label_studio_sdk/types/annotation_last_action.py +3 -15
- label_studio_sdk/types/{annotations_dm_field.py → annotation_request.py} +21 -30
- label_studio_sdk/types/annotation_request_last_action.py +7 -0
- label_studio_sdk/types/assignment_settings.py +31 -0
- label_studio_sdk/types/assignment_settings_label_stream_task_distribution.py +7 -0
- label_studio_sdk/types/assignment_settings_request.py +32 -0
- label_studio_sdk/types/assignment_settings_request_label_stream_task_distribution.py +7 -0
- label_studio_sdk/types/associated_project.py +30 -0
- label_studio_sdk/types/auth_method_enum.py +5 -0
- label_studio_sdk/types/azure_blob_export_storage.py +8 -12
- label_studio_sdk/types/azure_blob_import_storage.py +8 -12
- label_studio_sdk/types/{prompt_associated_projects_item_id.py → batch_failed_predictions.py} +4 -4
- label_studio_sdk/types/{access_token_response.py → batch_predictions.py} +6 -8
- label_studio_sdk/types/billing_checks.py +39 -0
- label_studio_sdk/types/billing_flags.py +44 -0
- label_studio_sdk/types/billing_info_response.py +22 -0
- label_studio_sdk/types/blank_enum.py +5 -0
- label_studio_sdk/types/{key_indicators_item_extra_kpis_item.py → blueprint_list.py} +12 -6
- label_studio_sdk/types/budget_reset_period_enum.py +5 -0
- label_studio_sdk/types/child_filter.py +44 -0
- label_studio_sdk/types/comment.py +39 -14
- label_studio_sdk/types/comment_request.py +32 -0
- label_studio_sdk/types/comment_serializer_with_expanded_user.py +53 -0
- label_studio_sdk/types/converted_format.py +5 -5
- label_studio_sdk/types/{api_token_response.py → converted_format_request.py} +8 -15
- label_studio_sdk/types/count_limit.py +22 -0
- label_studio_sdk/types/custom_scripts_editable_by_enum.py +5 -0
- label_studio_sdk/types/default_role_enum.py +5 -0
- label_studio_sdk/types/edition_enum.py +5 -0
- label_studio_sdk/types/export.py +7 -7
- label_studio_sdk/types/file_upload.py +5 -5
- label_studio_sdk/types/filter.py +9 -6
- label_studio_sdk/types/filter_group.py +3 -3
- label_studio_sdk/types/finished_enum.py +5 -0
- label_studio_sdk/types/gcs_export_storage.py +8 -12
- label_studio_sdk/types/gcs_import_storage.py +8 -12
- label_studio_sdk/types/{rotate_token_response.py → hotkeys.py} +5 -8
- label_studio_sdk/types/{base_task.py → import_api_request.py} +11 -34
- label_studio_sdk/types/inference_run_cost_estimate.py +2 -2
- label_studio_sdk/types/label_stream_task_distribution_enum.py +5 -0
- label_studio_sdk/types/{annotations_dm_field_last_action.py → last_action_enum.py} +1 -1
- label_studio_sdk/types/local_files_export_storage.py +8 -12
- label_studio_sdk/types/local_files_import_storage.py +8 -12
- label_studio_sdk/types/{annotation_filter_options.py → lse_annotation_filter_options.py} +12 -2
- label_studio_sdk/types/lse_annotation_filter_options_request.py +42 -0
- label_studio_sdk/types/lse_annotation_filter_options_request_reviewed.py +7 -0
- label_studio_sdk/types/lse_annotation_filter_options_reviewed.py +7 -0
- label_studio_sdk/types/{export_snapshot.py → lse_export_create.py} +11 -11
- label_studio_sdk/types/lse_fields.py +49 -0
- label_studio_sdk/types/lse_fields_onboarding_state.py +8 -0
- label_studio_sdk/types/lse_fields_trial_role.py +8 -0
- label_studio_sdk/types/lse_key_indicator_value.py +35 -0
- label_studio_sdk/types/lse_organization.py +57 -0
- label_studio_sdk/types/lse_organization_custom_scripts_editable_by.py +7 -0
- label_studio_sdk/types/{key_indicators_item_additional_kpis_item.py → lse_organization_member_list.py} +12 -7
- label_studio_sdk/types/lse_project_create.py +196 -0
- label_studio_sdk/types/lse_project_create_sampling.py +7 -0
- label_studio_sdk/types/lse_project_create_skip_queue.py +7 -0
- label_studio_sdk/types/lse_project_update.py +215 -0
- label_studio_sdk/types/lse_project_update_sampling.py +7 -0
- label_studio_sdk/types/lse_project_update_skip_queue.py +7 -0
- label_studio_sdk/types/lse_s3export_storage.py +134 -0
- label_studio_sdk/{import_storage/s3/types/s3create_response.py → types/lse_s3export_storage_request.py} +47 -21
- label_studio_sdk/{import_storage/s3/types/s3update_response.py → types/lse_s3import_storage.py} +60 -21
- label_studio_sdk/types/{s3s_import_storage.py → lse_s3import_storage_request.py} +32 -21
- label_studio_sdk/types/lse_task.py +117 -0
- label_studio_sdk/types/{data_manager_task_serializer_drafts_item.py → lse_task_drafts_item.py} +2 -2
- label_studio_sdk/types/lse_task_filter_options.py +63 -0
- label_studio_sdk/types/lse_task_filter_options_annotated.py +7 -0
- label_studio_sdk/types/lse_task_filter_options_finished.py +7 -0
- label_studio_sdk/types/lse_task_filter_options_request.py +63 -0
- label_studio_sdk/types/lse_task_filter_options_request_annotated.py +7 -0
- label_studio_sdk/types/lse_task_filter_options_request_finished.py +7 -0
- label_studio_sdk/types/lse_task_filter_options_request_reviewed.py +7 -0
- label_studio_sdk/types/lse_task_filter_options_request_skipped.py +7 -0
- label_studio_sdk/types/lse_task_filter_options_reviewed.py +7 -0
- label_studio_sdk/types/lse_task_filter_options_skipped.py +7 -0
- label_studio_sdk/types/{data_manager_task_serializer_predictions_item.py → lse_task_predictions_item.py} +4 -5
- label_studio_sdk/types/lse_task_serializer_for_annotators.py +54 -0
- label_studio_sdk/types/lse_task_serializer_for_annotators_drafts_item.py +22 -0
- label_studio_sdk/types/lse_task_serializer_for_annotators_predictions_item.py +28 -0
- label_studio_sdk/types/lse_task_serializer_for_reviewers.py +117 -0
- label_studio_sdk/types/lse_task_serializer_for_reviewers_drafts_item.py +22 -0
- label_studio_sdk/types/lse_task_serializer_for_reviewers_predictions_item.py +28 -0
- label_studio_sdk/types/lse_user.py +49 -0
- label_studio_sdk/types/{base_user.py → lse_user_api.py} +17 -6
- label_studio_sdk/types/lse_user_organization_member_list.py +48 -0
- label_studio_sdk/types/lseapi_token_create.py +21 -0
- label_studio_sdk/types/lseapi_token_list.py +21 -0
- label_studio_sdk/types/lsejwt_settings.py +32 -0
- label_studio_sdk/types/maybe_expanded_comment.py +7 -0
- label_studio_sdk/types/ml_backend.py +16 -17
- label_studio_sdk/types/mode_enum.py +5 -0
- label_studio_sdk/types/model_interface.py +44 -0
- label_studio_sdk/types/model_interface_request.py +40 -0
- label_studio_sdk/types/model_interface_serializer_get.py +45 -0
- label_studio_sdk/types/model_provider_connection.py +48 -17
- label_studio_sdk/types/model_provider_connection_budget_reset_period.py +3 -1
- label_studio_sdk/types/model_provider_connection_request.py +71 -0
- label_studio_sdk/types/model_run.py +40 -0
- label_studio_sdk/types/{inference_run_status.py → model_run_status_enum.py} +1 -1
- label_studio_sdk/types/null_enum.py +3 -0
- label_studio_sdk/types/onboarding_state_enum.py +7 -0
- label_studio_sdk/types/organization_billing.py +20 -0
- label_studio_sdk/types/organization_id.py +28 -0
- label_studio_sdk/types/organization_invite.py +20 -0
- label_studio_sdk/types/organization_member.py +37 -0
- label_studio_sdk/types/organization_membership.py +24 -0
- label_studio_sdk/{projects/types/projects_list_response.py → types/paginated_all_roles_project_list_list.py} +5 -5
- label_studio_sdk/types/paginated_lse_organization_member_list_list.py +23 -0
- label_studio_sdk/types/{jwt_settings_response.py → paginated_role_based_task_list.py} +11 -9
- label_studio_sdk/types/pause.py +55 -14
- label_studio_sdk/types/pause_request.py +41 -0
- label_studio_sdk/types/prediction.py +7 -11
- label_studio_sdk/types/prediction_request.py +56 -0
- label_studio_sdk/types/project.py +32 -39
- label_studio_sdk/types/project_import.py +12 -13
- label_studio_sdk/types/project_label_config.py +2 -2
- label_studio_sdk/types/project_label_config_request.py +22 -0
- label_studio_sdk/types/project_sampling.py +3 -3
- label_studio_sdk/types/project_skip_queue.py +3 -1
- label_studio_sdk/types/project_subset_enum.py +5 -0
- label_studio_sdk/types/prompts_status_enum.py +16 -0
- label_studio_sdk/types/{prompt_version_provider.py → provider_enum.py} +1 -1
- label_studio_sdk/types/reason_enum.py +7 -0
- label_studio_sdk/types/redis_export_storage.py +8 -12
- label_studio_sdk/types/redis_import_storage.py +8 -12
- label_studio_sdk/types/refined_prompt_response.py +5 -6
- label_studio_sdk/types/requeue_rejected_tasks_mode_enum.py +5 -0
- label_studio_sdk/types/review_criteria_enum.py +5 -0
- label_studio_sdk/types/review_settings.py +80 -0
- label_studio_sdk/types/review_settings_request.py +80 -0
- label_studio_sdk/types/review_settings_request_requeue_rejected_tasks_mode.py +8 -0
- label_studio_sdk/types/review_settings_request_review_criteria.py +7 -0
- label_studio_sdk/types/review_settings_requeue_rejected_tasks_mode.py +8 -0
- label_studio_sdk/types/review_settings_review_criteria.py +7 -0
- label_studio_sdk/types/reviewed_enum.py +5 -0
- label_studio_sdk/types/role9e7enum.py +5 -0
- label_studio_sdk/types/role_based_task.py +8 -0
- label_studio_sdk/types/s3export_storage.py +8 -12
- label_studio_sdk/types/s3import_storage.py +8 -12
- label_studio_sdk/types/sampling_enum.py +7 -0
- label_studio_sdk/types/scope_enum.py +5 -0
- label_studio_sdk/types/selected_items_request.py +23 -0
- label_studio_sdk/types/serialization_option.py +2 -6
- label_studio_sdk/types/serialization_option_request.py +22 -0
- label_studio_sdk/types/serialization_options.py +17 -5
- label_studio_sdk/types/serialization_options_request.py +47 -0
- label_studio_sdk/types/skill_name_enum.py +5 -0
- label_studio_sdk/types/skip_queue_enum.py +5 -0
- label_studio_sdk/types/skipped_enum.py +5 -0
- label_studio_sdk/types/state_enum.py +5 -0
- label_studio_sdk/types/status7bf_enum.py +5 -0
- label_studio_sdk/types/{azure_blob_import_storage_status.py → status_c5a_enum.py} +2 -2
- label_studio_sdk/types/third_party_model_version.py +65 -0
- label_studio_sdk/types/third_party_model_version_request.py +54 -0
- label_studio_sdk/types/token_refresh_response.py +19 -0
- label_studio_sdk/types/token_rotate_response.py +19 -0
- label_studio_sdk/types/trial_role_enum.py +16 -0
- label_studio_sdk/types/user_simple.py +8 -5
- label_studio_sdk/types/user_simple_request.py +28 -0
- label_studio_sdk/types/version_response.py +49 -0
- label_studio_sdk/types/view.py +8 -15
- label_studio_sdk/types/webhook.py +9 -13
- label_studio_sdk/types/webhook_serializer_for_update.py +15 -13
- label_studio_sdk/types/workspace.py +14 -34
- label_studio_sdk/types/workspace_member_create.py +27 -0
- label_studio_sdk/types/workspace_member_list.py +24 -0
- label_studio_sdk/users/client.py +604 -87
- label_studio_sdk/users/types/users_get_token_response.py +4 -11
- label_studio_sdk/users/types/users_reset_token_response.py +4 -11
- label_studio_sdk/versions/__init__.py +0 -3
- label_studio_sdk/versions/client.py +14 -14
- label_studio_sdk/views/client.py +227 -141
- label_studio_sdk/views/types/views_create_request_data.py +2 -2
- label_studio_sdk/views/types/views_create_request_data_filters.py +2 -2
- label_studio_sdk/views/types/views_create_request_data_filters_items_item.py +2 -2
- label_studio_sdk/views/types/views_update_request_data.py +2 -2
- label_studio_sdk/views/types/views_update_request_data_filters.py +2 -2
- label_studio_sdk/views/types/views_update_request_data_filters_items_item.py +2 -2
- label_studio_sdk/webhooks/__init__.py +36 -2
- label_studio_sdk/webhooks/client.py +173 -367
- label_studio_sdk/webhooks/types/__init__.py +34 -2
- label_studio_sdk/webhooks/types/webhooks_info_response.py +80 -0
- label_studio_sdk/webhooks/types/webhooks_info_response_annotation_created.py +24 -0
- label_studio_sdk/webhooks/types/webhooks_info_response_annotation_updated.py +24 -0
- label_studio_sdk/webhooks/types/webhooks_info_response_annotations_created.py +24 -0
- label_studio_sdk/webhooks/types/webhooks_info_response_annotations_deleted.py +24 -0
- label_studio_sdk/webhooks/types/webhooks_info_response_label_link_created.py +24 -0
- label_studio_sdk/webhooks/types/webhooks_info_response_label_link_deleted.py +24 -0
- label_studio_sdk/webhooks/types/webhooks_info_response_label_link_updated.py +24 -0
- label_studio_sdk/webhooks/types/webhooks_info_response_project_created.py +24 -0
- label_studio_sdk/webhooks/types/webhooks_info_response_project_deleted.py +24 -0
- label_studio_sdk/webhooks/types/webhooks_info_response_project_updated.py +24 -0
- label_studio_sdk/webhooks/types/webhooks_info_response_review_created.py +24 -0
- label_studio_sdk/webhooks/types/webhooks_info_response_review_updated.py +24 -0
- label_studio_sdk/webhooks/types/webhooks_info_response_reviews_deleted.py +24 -0
- label_studio_sdk/webhooks/types/webhooks_info_response_tasks_created.py +24 -0
- label_studio_sdk/webhooks/types/webhooks_info_response_tasks_deleted.py +24 -0
- label_studio_sdk/workspaces/__init__.py +1 -2
- label_studio_sdk/workspaces/client.py +97 -117
- label_studio_sdk/workspaces/members/__init__.py +0 -3
- label_studio_sdk/workspaces/members/client.py +65 -81
- {label_studio_sdk-1.0.20.dist-info → label_studio_sdk-2.0.1.dist-info}/METADATA +73 -25
- label_studio_sdk-2.0.1.dist-info/RECORD +435 -0
- {label_studio_sdk-1.0.20.dist-info → label_studio_sdk-2.0.1.dist-info}/WHEEL +1 -1
- label_studio_sdk/annotations/types/annotations_create_bulk_request_selected_items.py +0 -34
- label_studio_sdk/export_storage/azure/types/__init__.py +0 -6
- label_studio_sdk/export_storage/azure/types/azure_create_response.py +0 -57
- label_studio_sdk/export_storage/azure/types/azure_update_response.py +0 -57
- label_studio_sdk/export_storage/gcs/types/__init__.py +0 -6
- label_studio_sdk/export_storage/gcs/types/gcs_create_response.py +0 -57
- label_studio_sdk/export_storage/gcs/types/gcs_update_response.py +0 -57
- label_studio_sdk/export_storage/local/types/__init__.py +0 -6
- label_studio_sdk/export_storage/local/types/local_create_response.py +0 -47
- label_studio_sdk/export_storage/local/types/local_update_response.py +0 -47
- label_studio_sdk/export_storage/redis/types/__init__.py +0 -6
- label_studio_sdk/export_storage/redis/types/redis_create_response.py +0 -62
- label_studio_sdk/export_storage/redis/types/redis_update_response.py +0 -62
- label_studio_sdk/export_storage/s3/types/__init__.py +0 -6
- label_studio_sdk/export_storage/s3/types/s3create_response.py +0 -81
- label_studio_sdk/export_storage/s3/types/s3update_response.py +0 -81
- label_studio_sdk/import_storage/azure/types/__init__.py +0 -6
- label_studio_sdk/import_storage/azure/types/azure_create_response.py +0 -72
- label_studio_sdk/import_storage/azure/types/azure_update_response.py +0 -72
- label_studio_sdk/import_storage/gcs/types/__init__.py +0 -6
- label_studio_sdk/import_storage/gcs/types/gcs_create_response.py +0 -72
- label_studio_sdk/import_storage/gcs/types/gcs_update_response.py +0 -72
- label_studio_sdk/import_storage/local/types/__init__.py +0 -6
- label_studio_sdk/import_storage/local/types/local_create_response.py +0 -47
- label_studio_sdk/import_storage/local/types/local_update_response.py +0 -47
- label_studio_sdk/import_storage/redis/types/__init__.py +0 -6
- label_studio_sdk/import_storage/redis/types/redis_create_response.py +0 -62
- label_studio_sdk/import_storage/redis/types/redis_update_response.py +0 -62
- label_studio_sdk/import_storage/s3/types/__init__.py +0 -6
- label_studio_sdk/ml/types/ml_create_response.py +0 -68
- label_studio_sdk/ml/types/ml_create_response_auth_method.py +0 -5
- label_studio_sdk/ml/types/ml_update_response.py +0 -68
- label_studio_sdk/ml/types/ml_update_response_auth_method.py +0 -5
- label_studio_sdk/projects/exports/types/exports_list_formats_response_item.py +0 -44
- label_studio_sdk/projects/types/projects_create_response.py +0 -91
- label_studio_sdk/projects/types/projects_update_response.py +0 -96
- label_studio_sdk/prompts/types/prompts_batch_failed_predictions_request_failed_predictions_item.py +0 -32
- label_studio_sdk/prompts/types/prompts_batch_predictions_request_results_item.py +0 -59
- label_studio_sdk/tasks/types/tasks_list_response.py +0 -38
- label_studio_sdk/types/annotation_completed_by.py +0 -6
- label_studio_sdk/types/azure_blob_export_storage_status.py +0 -7
- label_studio_sdk/types/base_task_updated_by.py +0 -7
- label_studio_sdk/types/comment_created_by.py +0 -5
- label_studio_sdk/types/converted_format_status.py +0 -5
- label_studio_sdk/types/data_manager_task_serializer.py +0 -118
- label_studio_sdk/types/data_manager_task_serializer_annotators_item.py +0 -5
- label_studio_sdk/types/data_manager_task_serializer_comment_authors_item.py +0 -5
- label_studio_sdk/types/data_manager_task_serializer_predictions_item_model_run.py +0 -5
- label_studio_sdk/types/export_format.py +0 -25
- label_studio_sdk/types/export_snapshot_status.py +0 -5
- label_studio_sdk/types/export_status.py +0 -5
- label_studio_sdk/types/gcs_export_storage_status.py +0 -7
- label_studio_sdk/types/gcs_import_storage_status.py +0 -7
- label_studio_sdk/types/inference_run.py +0 -34
- label_studio_sdk/types/inference_run_created_by.py +0 -5
- label_studio_sdk/types/inference_run_organization.py +0 -5
- label_studio_sdk/types/inference_run_project_subset.py +0 -5
- label_studio_sdk/types/key_indicators.py +0 -6
- label_studio_sdk/types/key_indicators_item.py +0 -41
- label_studio_sdk/types/local_files_export_storage_status.py +0 -7
- label_studio_sdk/types/local_files_import_storage_status.py +0 -7
- label_studio_sdk/types/ml_backend_auth_method.py +0 -5
- label_studio_sdk/types/ml_backend_state.py +0 -5
- label_studio_sdk/types/model_provider_connection_created_by.py +0 -5
- label_studio_sdk/types/model_provider_connection_organization.py +0 -5
- label_studio_sdk/types/model_provider_connection_provider.py +0 -7
- label_studio_sdk/types/model_provider_connection_scope.py +0 -5
- label_studio_sdk/types/pause_paused_by.py +0 -5
- label_studio_sdk/types/project_import_status.py +0 -5
- label_studio_sdk/types/prompt.py +0 -71
- label_studio_sdk/types/prompt_associated_projects_item.py +0 -6
- label_studio_sdk/types/prompt_created_by.py +0 -5
- label_studio_sdk/types/prompt_organization.py +0 -5
- label_studio_sdk/types/prompt_version.py +0 -32
- label_studio_sdk/types/prompt_version_created_by.py +0 -5
- label_studio_sdk/types/prompt_version_organization.py +0 -5
- label_studio_sdk/types/redis_export_storage_status.py +0 -7
- label_studio_sdk/types/redis_import_storage_status.py +0 -7
- label_studio_sdk/types/refined_prompt_response_refinement_status.py +0 -7
- label_studio_sdk/types/s3export_storage_status.py +0 -7
- label_studio_sdk/types/s3import_storage_status.py +0 -7
- label_studio_sdk/types/s3s_export_storage.py +0 -73
- label_studio_sdk/types/s3s_import_storage_status.py +0 -7
- label_studio_sdk/types/task.py +0 -156
- label_studio_sdk/types/task_annotators_item.py +0 -5
- label_studio_sdk/types/task_comment_authors_item.py +0 -5
- label_studio_sdk/types/task_filter_options.py +0 -39
- label_studio_sdk/types/webhook_actions_item.py +0 -21
- label_studio_sdk/types/webhook_serializer_for_update_actions_item.py +0 -21
- label_studio_sdk/versions/types/__init__.py +0 -6
- label_studio_sdk/versions/types/versions_get_response.py +0 -73
- label_studio_sdk/versions/types/versions_get_response_edition.py +0 -5
- label_studio_sdk/workspaces/members/types/__init__.py +0 -6
- label_studio_sdk/workspaces/members/types/members_create_response.py +0 -22
- label_studio_sdk/workspaces/members/types/members_list_response_item.py +0 -22
- label_studio_sdk-1.0.20.dist-info/RECORD +0 -374
- {label_studio_sdk-1.0.20.dist-info → label_studio_sdk-2.0.1.dist-info}/LICENSE +0 -0
|
@@ -425,6 +425,213 @@ e.g.:
|
|
|
425
425
|
- The Local Storage in Label Studio is set up correctly with the Absolute local path to your images (`/yolo/datasets/one/images`)
|
|
426
426
|
- For more details, refer to the documentation on [importing pre-annotated data](https://labelstud.io/guide/predictions.html) and [setting up Cloud Storages](https://labelstud.io/guide/storage).
|
|
427
427
|
|
|
428
|
+
# COCO to Label Studio Converter
|
|
429
|
+
|
|
430
|
+
### COCO dataset structure
|
|
431
|
+
|
|
432
|
+
Check the structure of COCO dataset first. The typical COCO dataset structure:
|
|
433
|
+
|
|
434
|
+
```
|
|
435
|
+
/coco/dataset
|
|
436
|
+
annotations/
|
|
437
|
+
- instances_train2017.json
|
|
438
|
+
- instances_val2017.json
|
|
439
|
+
- person_keypoints_train2017.json
|
|
440
|
+
- (other annotation files...)
|
|
441
|
+
train2017/
|
|
442
|
+
- 000000000139.jpg
|
|
443
|
+
- 000000000285.jpg
|
|
444
|
+
- ...
|
|
445
|
+
val2017/
|
|
446
|
+
- 000000000139.jpg
|
|
447
|
+
- 000000000285.jpg
|
|
448
|
+
- ...
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
*COCO JSON annotation file structure*
|
|
452
|
+
|
|
453
|
+
```json
|
|
454
|
+
{
|
|
455
|
+
"images": [
|
|
456
|
+
{
|
|
457
|
+
"id": 139,
|
|
458
|
+
"width": 426,
|
|
459
|
+
"height": 640,
|
|
460
|
+
"file_name": "000000000139.jpg"
|
|
461
|
+
}
|
|
462
|
+
],
|
|
463
|
+
"annotations": [
|
|
464
|
+
{
|
|
465
|
+
"id": 1768,
|
|
466
|
+
"image_id": 139,
|
|
467
|
+
"category_id": 64,
|
|
468
|
+
"bbox": [412.8, 157.61, 11.65, 12.64],
|
|
469
|
+
"area": 147.24,
|
|
470
|
+
"iscrowd": 0,
|
|
471
|
+
"segmentation": [[...]]
|
|
472
|
+
}
|
|
473
|
+
],
|
|
474
|
+
"categories": [
|
|
475
|
+
{
|
|
476
|
+
"id": 1,
|
|
477
|
+
"name": "person",
|
|
478
|
+
"supercategory": "person"
|
|
479
|
+
}
|
|
480
|
+
]
|
|
481
|
+
}
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
### Usage
|
|
485
|
+
|
|
486
|
+
```
|
|
487
|
+
label-studio-converter import coco -i /coco/dataset/annotations/instances_val2017.json -o ls-tasks.json --image-root-url "/data/local-files/?d=val2017"
|
|
488
|
+
```
|
|
489
|
+
Where the URL path from `?d=` is relative to the path you set in `LABEL_STUDIO_LOCAL_FILES_DOCUMENT_ROOT`.
|
|
490
|
+
|
|
491
|
+
**Note for Local Storages**
|
|
492
|
+
* It's very important to set `LABEL_STUDIO_LOCAL_FILES_DOCUMENT_ROOT=/coco/dataset` (**not** to `/coco/dataset/val2017`, but **`/coco/dataset`**) for Label Studio to run.
|
|
493
|
+
* [Add a new Local Storage](https://labelstud.io/guide/storage#Local-storage) in the project settings and set **Absolute local path** to `/coco/dataset/val2017` (or `c:\coco\dataset\val2017` for Windows).
|
|
494
|
+
|
|
495
|
+
**Note for Cloud Storages**
|
|
496
|
+
* Use `--image-root-url` to make correct prefixes for task URLs, e.g. `--image-root-url s3://my-bucket/coco/val2017/`.
|
|
497
|
+
* [Add a new Cloud Storage](https://labelstud.io/guide/storage) in the project settings with the corresponding bucket and prefix.
|
|
498
|
+
|
|
499
|
+
**Additional Options**
|
|
500
|
+
* Use `--use-super-categories` to include COCO super categories in label names (e.g., "vehicle:car" instead of "car")
|
|
501
|
+
* Use `--out-type predictions` to import as predictions instead of ground truth annotations
|
|
502
|
+
* Use `--point-width 2.0` to adjust keypoint size for pose estimation tasks
|
|
503
|
+
|
|
504
|
+
**Help command**
|
|
505
|
+
|
|
506
|
+
```
|
|
507
|
+
label-studio-converter import coco -h
|
|
508
|
+
|
|
509
|
+
usage: label-studio-converter import coco [-h] -i INPUT [-o OUTPUT]
|
|
510
|
+
[--to-name TO_NAME]
|
|
511
|
+
[--from-name FROM_NAME]
|
|
512
|
+
[--out-type OUT_TYPE]
|
|
513
|
+
[--image-root-url IMAGE_ROOT_URL]
|
|
514
|
+
[--point-width POINT_WIDTH]
|
|
515
|
+
|
|
516
|
+
optional arguments:
|
|
517
|
+
-h, --help show this help message and exit
|
|
518
|
+
-i INPUT, --input INPUT
|
|
519
|
+
input COCO json file
|
|
520
|
+
-o OUTPUT, --output OUTPUT
|
|
521
|
+
output file with Label Studio JSON tasks
|
|
522
|
+
--to-name TO_NAME object name from Label Studio labeling config
|
|
523
|
+
--from-name FROM_NAME
|
|
524
|
+
control tag name from Label Studio labeling config
|
|
525
|
+
--out-type OUT_TYPE annotation type - "annotations" or "predictions"
|
|
526
|
+
--image-root-url IMAGE_ROOT_URL
|
|
527
|
+
root URL path where images will be hosted, e.g.:
|
|
528
|
+
http://example.com/images or s3://my-bucket
|
|
529
|
+
--point-width POINT_WIDTH
|
|
530
|
+
key point width (size)
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
## Tutorial: Importing COCO Pre-Annotated Images to Label Studio using Local Storage
|
|
534
|
+
|
|
535
|
+
This tutorial will guide you through the process of importing a COCO dataset into Label Studio for further annotation or review.
|
|
536
|
+
We'll cover setting up your environment, converting COCO annotations to Label Studio's format, and importing them into your project.
|
|
537
|
+
|
|
538
|
+
### Prerequisites
|
|
539
|
+
- Label Studio installed locally
|
|
540
|
+
- COCO dataset with JSON annotation file and images in the directory `/coco/dataset`.
|
|
541
|
+
- Label Studio SDK installed (available via `pip install label-studio-sdk`) -- this includes the `label-studio-converter` tool that you will use
|
|
542
|
+
|
|
543
|
+
### Step 1: Set Up Your Environment and Run Label Studio
|
|
544
|
+
Before starting Label Studio, set the following environment variables to enable Local Storage file serving:
|
|
545
|
+
|
|
546
|
+
Unix systems:
|
|
547
|
+
```
|
|
548
|
+
export LABEL_STUDIO_LOCAL_FILES_SERVING_ENABLED=true
|
|
549
|
+
export LABEL_STUDIO_LOCAL_FILES_DOCUMENT_ROOT=/coco/dataset
|
|
550
|
+
label-studio
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
Windows:
|
|
554
|
+
```
|
|
555
|
+
set LABEL_STUDIO_LOCAL_FILES_SERVING_ENABLED=true
|
|
556
|
+
set LABEL_STUDIO_LOCAL_FILES_DOCUMENT_ROOT=C:\\coco\\dataset
|
|
557
|
+
label-studio
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
Replace `/coco/dataset` with the actual path to your COCO dataset directory.
|
|
561
|
+
|
|
562
|
+
### Step 2: Setup Local Storage
|
|
563
|
+
1. Create a new project.
|
|
564
|
+
2. Go to the project settings and select **Cloud Storage**.
|
|
565
|
+
3. Click **Add Source Storage** and select **Local files** from the **Storage Type** options.
|
|
566
|
+
4. Set the **Absolute local path** to `/coco/dataset/val2017` (or your image folder path, e.g., `c:\coco\dataset\val2017` on Windows).
|
|
567
|
+
5. Click `Add storage`.
|
|
568
|
+
|
|
569
|
+
Check more details about Local Storages [in the documentation](https://labelstud.io/guide/storage.html#Local-storage).
|
|
570
|
+
|
|
571
|
+
### Step 3: Verify Image Access
|
|
572
|
+
Before importing the converted annotations from COCO, verify that you can access an image from your Local storage via Label Studio. Open a new browser tab and enter the following URL:
|
|
573
|
+
|
|
574
|
+
```
|
|
575
|
+
http://localhost:8080/data/local-files/?d=val2017/000000000139.jpg
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
Replace `val2017/000000000139.jpg` with the path to one of your images. The image should display **in the new tab of the browser**.
|
|
579
|
+
If you can't open an image, the Local Storage configuration is incorrect. The most likely reason is that you made a mistake when specifying your `Path` in Local Storage settings or in `LABEL_STUDIO_LOCAL_FILES_DOCUMENT_ROOT`.
|
|
580
|
+
|
|
581
|
+
**Note:** The URL path from `?d=` should be relative to `LABEL_STUDIO_LOCAL_FILES_DOCUMENT_ROOT=/coco/dataset`,
|
|
582
|
+
it means that the real path will be `/coco/dataset/val2017/000000000139.jpg` and this image should exist on your hard drive.
|
|
583
|
+
|
|
584
|
+
### Step 4: Convert COCO Annotations
|
|
585
|
+
Use the label-studio-converter to convert your COCO annotations to a format that Label Studio can understand:
|
|
586
|
+
|
|
587
|
+
```
|
|
588
|
+
label-studio-converter import coco -i /coco/dataset/annotations/instances_val2017.json -o output.json --image-root-url "/data/local-files/?d=val2017/"
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
**For different annotation types:**
|
|
592
|
+
- **Object Detection (bounding boxes)**: Use `instances_*.json` files
|
|
593
|
+
- **Instance Segmentation**: Use `instances_*.json` files (includes both bboxes and polygon segmentations)
|
|
594
|
+
- **Keypoint Detection (pose estimation)**: Use `person_keypoints_*.json` files
|
|
595
|
+
- **With super categories**: Add `--use-super-categories` flag
|
|
596
|
+
|
|
597
|
+
### Step 5: Import Converted Annotations
|
|
598
|
+
Now import the `output.json` file into Label Studio:
|
|
599
|
+
1. Go to your Label Studio project.
|
|
600
|
+
2. From the Data Manager, click **Import**.
|
|
601
|
+
3. Select the `output.json` file and import it.
|
|
602
|
+
4. If a label configuration file was generated (e.g., `output.label_config.xml`), you can use it in your project settings under **Labeling Interface**.
|
|
603
|
+
|
|
604
|
+
### Step 6: Verify Annotations
|
|
605
|
+
After importing, you should see your images with the pre-annotated bounding boxes, segmentations, or keypoints in Label Studio. Verify that the annotations are correct and make any necessary adjustments.
|
|
606
|
+
|
|
607
|
+
### Annotation Type Support
|
|
608
|
+
The COCO converter supports (see more details and examples here: https://labelstud.io/guide/export.html#COCO):
|
|
609
|
+
- ✅ **Bounding boxes** (object detection)
|
|
610
|
+
- ✅ **Polygon segmentations** (instance segmentation) - experimental
|
|
611
|
+
- ✅ **Keypoint detection** (pose estimation) - without skeleton connections
|
|
612
|
+
- ❌ **RLE segmentations** - not yet supported
|
|
613
|
+
|
|
614
|
+
### Troubleshooting
|
|
615
|
+
If you encounter issues with paths or image access, ensure that:
|
|
616
|
+
- The LABEL_STUDIO_LOCAL_FILES_DOCUMENT_ROOT is set correctly.
|
|
617
|
+
- The `--image-root-url` in the conversion command matches the relative path:
|
|
618
|
+
```
|
|
619
|
+
`Absolute local path from Local Storage Settings` - `LABEL_STUDIO_LOCAL_FILES_DOCUMENT_ROOT` = `path for --image_root_url`
|
|
620
|
+
```
|
|
621
|
+
e.g.:
|
|
622
|
+
```
|
|
623
|
+
/coco/dataset/val2017 - /coco/dataset/ = val2017/
|
|
624
|
+
```
|
|
625
|
+
- The Local Storage in Label Studio is set up correctly with the Absolute local path to your images (`/coco/dataset/val2017`)
|
|
626
|
+
- Your COCO JSON file is valid and contains the expected structure
|
|
627
|
+
- Image file names in the COCO JSON match the actual files in your images directory
|
|
628
|
+
- For more details, refer to the documentation on [importing pre-annotated data](https://labelstud.io/guide/predictions.html) and [setting up Cloud Storages](https://labelstud.io/guide/storage).
|
|
629
|
+
|
|
630
|
+
**Common Issues:**
|
|
631
|
+
- **"No labels converted"**: Check that your COCO JSON file contains annotations and that image files exist
|
|
632
|
+
- **Images not loading**: Verify the image paths and Local Storage configuration
|
|
633
|
+
- **Missing annotations**: Ensure the image IDs in the COCO JSON match the imported images
|
|
634
|
+
|
|
428
635
|
------------
|
|
429
636
|
|
|
430
637
|
# Contributing
|
|
@@ -11,6 +11,16 @@ logger = logging.getLogger("root")
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
def new_task(out_type, root_url, file_name):
|
|
14
|
+
"""Create a new Label Studio task structure.
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
out_type (str): Type of output - either 'annotations' or 'predictions'
|
|
18
|
+
root_url (str): Root URL path where images will be hosted
|
|
19
|
+
file_name (str): Name of the image file
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
dict: Label Studio task structure with image data and empty result array
|
|
23
|
+
"""
|
|
14
24
|
return {
|
|
15
25
|
"data": {"image": os.path.join(root_url, file_name)},
|
|
16
26
|
# 'annotations' or 'predictions'
|
|
@@ -24,9 +34,27 @@ def new_task(out_type, root_url, file_name):
|
|
|
24
34
|
|
|
25
35
|
|
|
26
36
|
def create_bbox(annotation, categories, from_name, image_height, image_width, to_name):
|
|
37
|
+
"""Convert COCO bounding box annotation to Label Studio format.
|
|
38
|
+
|
|
39
|
+
COCO bbox format: [x, y, width, height] where (x,y) is top-left corner
|
|
40
|
+
Label Studio format: percentages relative to image dimensions
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
annotation (dict): COCO annotation containing bbox and category_id
|
|
44
|
+
categories (dict): Mapping of category_id to category name
|
|
45
|
+
from_name (str): Control tag name from Label Studio labeling config
|
|
46
|
+
image_height (int): Height of the source image in pixels
|
|
47
|
+
image_width (int): Width of the source image in pixels
|
|
48
|
+
to_name (str): Object name from Label Studio labeling config
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
dict: Label Studio rectangle annotation item
|
|
52
|
+
"""
|
|
27
53
|
label = categories[int(annotation["category_id"])]
|
|
28
54
|
x, y, width, height = annotation["bbox"]
|
|
29
55
|
x, y, width, height = float(x), float(y), float(width), float(height)
|
|
56
|
+
|
|
57
|
+
# Convert absolute coordinates to percentages
|
|
30
58
|
item = {
|
|
31
59
|
"id": uuid.uuid4().hex[0:10],
|
|
32
60
|
"type": "rectanglelabels",
|
|
@@ -50,9 +78,28 @@ def create_bbox(annotation, categories, from_name, image_height, image_width, to
|
|
|
50
78
|
def create_segmentation(
|
|
51
79
|
category_id, segmentation, categories, from_name, image_height, image_width, to_name
|
|
52
80
|
):
|
|
81
|
+
"""Convert COCO segmentation annotation to Label Studio polygon format.
|
|
82
|
+
|
|
83
|
+
COCO segmentation format: flat array of [x1,y1,x2,y2,...] coordinates
|
|
84
|
+
Label Studio format: array of [x,y] points as percentages
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
category_id (int): COCO category ID for this segmentation
|
|
88
|
+
segmentation (list): Flat list of polygon coordinates [x1,y1,x2,y2,...]
|
|
89
|
+
categories (dict): Mapping of category_id to category name
|
|
90
|
+
from_name (str): Control tag name from Label Studio labeling config
|
|
91
|
+
image_height (int): Height of the source image in pixels
|
|
92
|
+
image_width (int): Width of the source image in pixels
|
|
93
|
+
to_name (str): Object name from Label Studio labeling config
|
|
94
|
+
|
|
95
|
+
Returns:
|
|
96
|
+
dict: Label Studio polygon annotation item
|
|
97
|
+
"""
|
|
53
98
|
label = categories[int(category_id)]
|
|
99
|
+
# Convert flat array [x1,y1,x2,y2,...] to array of points [[x1,y1],[x2,y2],...]
|
|
54
100
|
points = [list(x) for x in zip(*[iter(segmentation)] * 2)]
|
|
55
101
|
|
|
102
|
+
# Convert absolute coordinates to percentages
|
|
56
103
|
for i in range(len(points)):
|
|
57
104
|
points[i][0] = points[i][0] / image_width * 100.0
|
|
58
105
|
points[i][1] = points[i][1] / image_height * 100.0
|
|
@@ -73,13 +120,33 @@ def create_segmentation(
|
|
|
73
120
|
def create_keypoints(
|
|
74
121
|
annotation, categories, from_name, to_name, image_height, image_width, point_width
|
|
75
122
|
):
|
|
123
|
+
"""Convert COCO keypoints annotation to Label Studio keypoint format.
|
|
124
|
+
|
|
125
|
+
COCO keypoints format: [x1,y1,v1,x2,y2,v2,...] where v is visibility flag
|
|
126
|
+
v=0: not labeled, v=1: labeled but not visible, v=2: labeled and visible
|
|
127
|
+
|
|
128
|
+
Args:
|
|
129
|
+
annotation (dict): COCO annotation containing keypoints and category_id
|
|
130
|
+
categories (dict): Mapping of category_id to category name
|
|
131
|
+
from_name (str): Control tag name from Label Studio labeling config
|
|
132
|
+
to_name (str): Object name from Label Studio labeling config
|
|
133
|
+
image_height (int): Height of the source image in pixels
|
|
134
|
+
image_width (int): Width of the source image in pixels
|
|
135
|
+
point_width (float): Width/size of keypoints in Label Studio
|
|
136
|
+
|
|
137
|
+
Returns:
|
|
138
|
+
list: List of Label Studio keypoint annotation items
|
|
139
|
+
"""
|
|
76
140
|
label = categories[int(annotation["category_id"])]
|
|
77
141
|
points = annotation["keypoints"]
|
|
78
142
|
items = []
|
|
79
143
|
|
|
144
|
+
# Process keypoints in groups of 3: x, y, visibility
|
|
80
145
|
for i in range(0, len(points), 3):
|
|
81
146
|
x, y, v = points[i : i + 3] # x, y, visibility
|
|
82
147
|
x, y, v = float(x), float(y), int(v)
|
|
148
|
+
|
|
149
|
+
# Convert absolute coordinates to percentages
|
|
83
150
|
item = {
|
|
84
151
|
"id": uuid.uuid4().hex[0:10],
|
|
85
152
|
"type": "keypointlabels",
|
|
@@ -96,7 +163,7 @@ def create_keypoints(
|
|
|
96
163
|
"original_height": image_height,
|
|
97
164
|
}
|
|
98
165
|
|
|
99
|
-
# visibility
|
|
166
|
+
# Handle visibility: if v < 2, the keypoint is hidden
|
|
100
167
|
if v < 2:
|
|
101
168
|
item["value"]["hidden"] = True
|
|
102
169
|
|
|
@@ -114,49 +181,78 @@ def convert_coco_to_ls(
|
|
|
114
181
|
use_super_categories=False,
|
|
115
182
|
point_width=1.0,
|
|
116
183
|
):
|
|
117
|
-
"""Convert COCO
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
184
|
+
"""Convert COCO dataset annotations to Label Studio JSON format.
|
|
185
|
+
|
|
186
|
+
This function processes a COCO dataset JSON file and converts all annotations
|
|
187
|
+
(bounding boxes, segmentations, keypoints) to Label Studio's format. It supports:
|
|
188
|
+
- Object detection (bounding boxes)
|
|
189
|
+
- Instance segmentation (polygons)
|
|
190
|
+
- Keypoint detection (pose estimation)
|
|
191
|
+
|
|
192
|
+
The function automatically generates a Label Studio labeling configuration
|
|
193
|
+
based on the annotation types found in the COCO dataset.
|
|
194
|
+
|
|
195
|
+
Args:
|
|
196
|
+
input_file (str): Path to input COCO JSON file
|
|
197
|
+
out_file (str): Path to output Label Studio JSON file
|
|
198
|
+
to_name (str, optional): Object name from Label Studio labeling config. Defaults to "image".
|
|
199
|
+
from_name (str, optional): Control tag name from Label Studio labeling config. Defaults to "label".
|
|
200
|
+
out_type (str, optional): Annotation type - "annotations" or "predictions". Defaults to "annotations".
|
|
201
|
+
image_root_url (str, optional): Root URL path where images will be hosted.
|
|
202
|
+
Defaults to "/data/local-files/?d=" for local storage.
|
|
203
|
+
use_super_categories (bool, optional): Use super categories from COCO if available. Defaults to False.
|
|
204
|
+
point_width (float, optional): Width/size of keypoints in pixels. Defaults to 1.0.
|
|
205
|
+
|
|
206
|
+
Example:
|
|
207
|
+
>>> convert_coco_to_ls(
|
|
208
|
+
... input_file='annotations/instances_val2017.json',
|
|
209
|
+
... out_file='label_studio_tasks.json',
|
|
210
|
+
... image_root_url='s3://my-bucket/images/',
|
|
211
|
+
... use_super_categories=True
|
|
212
|
+
... )
|
|
213
|
+
|
|
214
|
+
Note:
|
|
215
|
+
- The function will create a corresponding .label_config.xml file with the labeling configuration
|
|
216
|
+
- RLE (Run-Length Encoding) segmentations are not yet supported
|
|
217
|
+
- Keypoints are supported without skeleton connections
|
|
218
|
+
- Images must be accessible at the specified image_root_url
|
|
127
219
|
"""
|
|
128
220
|
|
|
129
221
|
tasks = {} # image_id => task
|
|
130
222
|
logger.info("Reading COCO notes and categories from %s", input_file)
|
|
131
223
|
|
|
224
|
+
# Load and parse COCO JSON file
|
|
132
225
|
with open(input_file, encoding="utf8") as f:
|
|
133
226
|
coco = json.load(f)
|
|
134
227
|
|
|
135
|
-
#
|
|
228
|
+
# Build categories => labels dict
|
|
136
229
|
new_categories = {}
|
|
137
|
-
# list to dict
|
|
230
|
+
# Convert list to dict: [...] => {category_id: category_item}
|
|
138
231
|
categories = {int(category["id"]): category for category in coco["categories"]}
|
|
139
|
-
ids = sorted(categories.keys()) #
|
|
232
|
+
ids = sorted(categories.keys()) # Sort labels by their original IDs
|
|
140
233
|
|
|
234
|
+
# Build category name mapping, optionally including super categories
|
|
141
235
|
for i in ids:
|
|
142
236
|
name = categories[i]["name"]
|
|
143
237
|
if use_super_categories and "supercategory" in categories[i]:
|
|
144
238
|
name = categories[i]["supercategory"] + ":" + name
|
|
145
239
|
new_categories[i] = name
|
|
146
240
|
|
|
147
|
-
# mapping: id => category name
|
|
241
|
+
# Final mapping: id => category name
|
|
148
242
|
categories = new_categories
|
|
149
243
|
|
|
150
|
-
# mapping: image id => image
|
|
244
|
+
# Create mapping: image id => image metadata
|
|
151
245
|
images = {item["id"]: item for item in coco["images"]}
|
|
152
246
|
|
|
153
247
|
logger.info(
|
|
154
248
|
f'Found {len(categories)} categories, {len(images)} images and {len(coco["annotations"])} annotations'
|
|
155
249
|
)
|
|
156
250
|
|
|
157
|
-
#
|
|
251
|
+
# Flags for tracking annotation types and generating appropriate labeling config
|
|
158
252
|
segmentation = bbox = keypoints = rle = False
|
|
159
253
|
segmentation_once = bbox_once = keypoints_once = rle_once = False
|
|
254
|
+
|
|
255
|
+
# Generate appropriate from_name tags for different annotation types
|
|
160
256
|
rectangles_from_name, keypoints_from_name = (
|
|
161
257
|
from_name + "_rectangles",
|
|
162
258
|
from_name + "_keypoints",
|
|
@@ -164,27 +260,30 @@ def convert_coco_to_ls(
|
|
|
164
260
|
segmentation_from_name = from_name + "polygons"
|
|
165
261
|
tags = {}
|
|
166
262
|
|
|
167
|
-
#
|
|
263
|
+
# Create initial tasks for each image
|
|
168
264
|
for image in coco["images"]:
|
|
169
265
|
image_id, image_file_name = image["id"], image["file_name"]
|
|
170
266
|
tasks[image_id] = new_task(out_type, image_root_url, image_file_name)
|
|
171
267
|
|
|
268
|
+
# Process all annotations
|
|
172
269
|
for i, annotation in enumerate(coco["annotations"]):
|
|
270
|
+
# Detect which annotation types are present
|
|
173
271
|
segmentation |= "segmentation" in annotation
|
|
174
272
|
bbox |= "bbox" in annotation
|
|
175
273
|
keypoints |= "keypoints" in annotation
|
|
176
274
|
rle |= (
|
|
177
275
|
annotation.get("iscrowd") == 1
|
|
178
|
-
) # 0 - polygons are in segmentation, otherwise
|
|
276
|
+
) # 0 - polygons are in segmentation, otherwise RLE
|
|
179
277
|
|
|
180
|
-
|
|
278
|
+
# Log warnings and build tag configuration
|
|
279
|
+
if rle and not rle_once: # RLE not supported yet
|
|
181
280
|
logger.error("RLE in segmentation is not yet supported in COCO")
|
|
182
281
|
rle_once = True
|
|
183
282
|
if keypoints and not keypoints_once:
|
|
184
283
|
logger.warning("Keypoints are partially supported without skeletons")
|
|
185
284
|
tags.update({keypoints_from_name: "KeyPointLabels"})
|
|
186
285
|
keypoints_once = True
|
|
187
|
-
if segmentation and not segmentation_once: #
|
|
286
|
+
if segmentation and not segmentation_once: # Experimental support
|
|
188
287
|
logger.warning("Segmentation in COCO is experimental")
|
|
189
288
|
tags.update({segmentation_from_name: "PolygonLabels"})
|
|
190
289
|
segmentation_once = True
|
|
@@ -192,7 +291,7 @@ def convert_coco_to_ls(
|
|
|
192
291
|
tags.update({rectangles_from_name: "RectangleLabels"})
|
|
193
292
|
bbox_once = True
|
|
194
293
|
|
|
195
|
-
#
|
|
294
|
+
# Get image metadata for coordinate conversion
|
|
196
295
|
image_id = annotation["image_id"]
|
|
197
296
|
image = images[image_id]
|
|
198
297
|
image_file_name, image_width, image_height = (
|
|
@@ -203,6 +302,7 @@ def convert_coco_to_ls(
|
|
|
203
302
|
|
|
204
303
|
task = tasks[image_id]
|
|
205
304
|
|
|
305
|
+
# Convert bounding box annotations
|
|
206
306
|
if "bbox" in annotation:
|
|
207
307
|
item = create_bbox(
|
|
208
308
|
annotation,
|
|
@@ -214,6 +314,7 @@ def convert_coco_to_ls(
|
|
|
214
314
|
)
|
|
215
315
|
task[out_type][0]["result"].append(item)
|
|
216
316
|
|
|
317
|
+
# Convert segmentation annotations (polygons)
|
|
217
318
|
if "segmentation" in annotation and len(annotation["segmentation"]):
|
|
218
319
|
for single_segmentation in annotation["segmentation"]:
|
|
219
320
|
item = create_segmentation(
|
|
@@ -227,6 +328,7 @@ def convert_coco_to_ls(
|
|
|
227
328
|
)
|
|
228
329
|
task[out_type][0]["result"].append(item)
|
|
229
330
|
|
|
331
|
+
# Convert keypoint annotations
|
|
230
332
|
if "keypoints" in annotation:
|
|
231
333
|
items = create_keypoints(
|
|
232
334
|
annotation,
|
|
@@ -241,16 +343,18 @@ def convert_coco_to_ls(
|
|
|
241
343
|
|
|
242
344
|
tasks[image_id] = task
|
|
243
345
|
|
|
244
|
-
#
|
|
346
|
+
# Generate and save labeling configuration
|
|
245
347
|
label_config_file = out_file.replace(".json", "") + ".label_config.xml"
|
|
246
348
|
generate_label_config(categories, tags, to_name, from_name, label_config_file)
|
|
247
349
|
|
|
350
|
+
# Save converted tasks to output file
|
|
248
351
|
if len(tasks) > 0:
|
|
249
352
|
tasks = [tasks[key] for key in sorted(tasks.keys())]
|
|
250
353
|
logger.info("Saving Label Studio JSON to %s", out_file)
|
|
251
354
|
with open(out_file, "w") as out:
|
|
252
355
|
json.dump(tasks, out)
|
|
253
356
|
|
|
357
|
+
# Print helpful instructions for user
|
|
254
358
|
print(
|
|
255
359
|
"\n"
|
|
256
360
|
f" 1. Create a new project in Label Studio\n"
|
|
@@ -264,6 +368,11 @@ def convert_coco_to_ls(
|
|
|
264
368
|
|
|
265
369
|
|
|
266
370
|
def add_parser(subparsers):
|
|
371
|
+
"""Add COCO converter arguments to command line parser.
|
|
372
|
+
|
|
373
|
+
Args:
|
|
374
|
+
subparsers: Argparse subparsers object to add the COCO parser to
|
|
375
|
+
"""
|
|
267
376
|
coco = subparsers.add_parser("coco")
|
|
268
377
|
|
|
269
378
|
coco.add_argument(
|
|
@@ -20,6 +20,7 @@ from .query_encoder import encode_query
|
|
|
20
20
|
from .remove_none_from_dict import remove_none_from_dict
|
|
21
21
|
from .request_options import RequestOptions
|
|
22
22
|
from .serialization import FieldMetadata, convert_and_respect_annotation_metadata
|
|
23
|
+
from .unchecked_base_model import UncheckedBaseModel, UnionMetadata, construct_type
|
|
23
24
|
|
|
24
25
|
__all__ = [
|
|
25
26
|
"ApiError",
|
|
@@ -34,8 +35,11 @@ __all__ = [
|
|
|
34
35
|
"RequestOptions",
|
|
35
36
|
"SyncClientWrapper",
|
|
36
37
|
"SyncPager",
|
|
38
|
+
"UncheckedBaseModel",
|
|
39
|
+
"UnionMetadata",
|
|
37
40
|
"UniversalBaseModel",
|
|
38
41
|
"UniversalRootModel",
|
|
42
|
+
"construct_type",
|
|
39
43
|
"convert_and_respect_annotation_metadata",
|
|
40
44
|
"convert_file_dict_to_httpx_tuples",
|
|
41
45
|
"encode_query",
|