endoreg-db 0.5.3__py3-none-any.whl → 0.6.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.
Potentially problematic release.
This version of endoreg-db might be problematic. Click here for more details.
- endoreg_db/admin.py +90 -1
- endoreg_db/urls.py +173 -0
- endoreg_db/views.py +0 -3
- endoreg_db-0.6.0.dist-info/METADATA +151 -0
- endoreg_db-0.6.0.dist-info/RECORD +11 -0
- {endoreg_db-0.5.3.dist-info → endoreg_db-0.6.0.dist-info}/WHEEL +2 -1
- endoreg_db-0.6.0.dist-info/top_level.txt +1 -0
- endoreg_db/data/__init__.py +0 -72
- endoreg_db/data/active_model/data.yaml +0 -3
- endoreg_db/data/agl_service/data.yaml +0 -19
- endoreg_db/data/case_template/rule/00_patient_lab_sample_add_default_value.yaml +0 -167
- endoreg_db/data/case_template/rule/01_patient-set-age.yaml +0 -8
- endoreg_db/data/case_template/rule/01_patient-set-gender.yaml +0 -9
- endoreg_db/data/case_template/rule/11_create_patient_lab_sample.yaml +0 -23
- endoreg_db/data/case_template/rule/12_create-patient_medication-anticoagulation.yaml +0 -19
- endoreg_db/data/case_template/rule/13_create-patient_medication_schedule-anticoagulation.yaml +0 -19
- endoreg_db/data/case_template/rule/19_create_patient.yaml +0 -17
- endoreg_db/data/case_template/rule_type/base_types.yaml +0 -35
- endoreg_db/data/case_template/rule_value/.init +0 -0
- endoreg_db/data/case_template/rule_value_type/base_types.yaml +0 -59
- endoreg_db/data/case_template/template/base.yaml +0 -8
- endoreg_db/data/case_template/template_type/pre_endoscopy.yaml +0 -3
- endoreg_db/data/case_template/tmp/_rule_value +0 -13
- endoreg_db/data/case_template/tmp/rule/01_atrial_fibrillation.yaml +0 -21
- endoreg_db/data/case_template/tmp/rule/02_create_object.yaml +0 -10
- endoreg_db/data/case_template/tmp/template/atrial_fibrillation_low_risk.yaml +0 -7
- endoreg_db/data/center/data.yaml +0 -60
- endoreg_db/data/center_resource/green_endoscopy_dashboard_CenterResource.yaml +0 -144
- endoreg_db/data/center_waste/green_endoscopy_dashboard_CenterWaste.yaml +0 -48
- endoreg_db/data/disease/cardiovascular.yaml +0 -37
- endoreg_db/data/disease/hepatology.yaml +0 -5
- endoreg_db/data/disease/misc.yaml +0 -6
- endoreg_db/data/disease/renal.yaml +0 -5
- endoreg_db/data/disease_classification/chronic_kidney_disease.yaml +0 -6
- endoreg_db/data/disease_classification/coronary_vessel_disease.yaml +0 -6
- endoreg_db/data/disease_classification_choice/chronic_kidney_disease.yaml +0 -41
- endoreg_db/data/disease_classification_choice/coronary_vessel_disease.yaml +0 -20
- endoreg_db/data/distribution/date/patient.yaml +0 -7
- endoreg_db/data/distribution/multiple_categorical/.init +0 -0
- endoreg_db/data/distribution/numeric/.init +0 -0
- endoreg_db/data/distribution/single_categorical/patient.yaml +0 -7
- endoreg_db/data/emission_factor/green_endoscopy_dashboard_EmissionFactor.yaml +0 -132
- endoreg_db/data/endoscope_type/data.yaml +0 -11
- endoreg_db/data/endoscopy_processor/data.yaml +0 -47
- endoreg_db/data/event/cardiology.yaml +0 -28
- endoreg_db/data/event/neurology.yaml +0 -14
- endoreg_db/data/event/surgery.yaml +0 -13
- endoreg_db/data/event/thrombembolism.yaml +0 -20
- endoreg_db/data/examination/examinations/data.yaml +0 -66
- endoreg_db/data/examination/time/data.yaml +0 -48
- endoreg_db/data/examination/time-type/data.yaml +0 -8
- endoreg_db/data/examination/type/data.yaml +0 -5
- endoreg_db/data/gender/data.yaml +0 -18
- endoreg_db/data/information_source/data.yaml +0 -30
- endoreg_db/data/information_source/medication.yaml +0 -6
- endoreg_db/data/lab_value/cardiac_enzymes.yaml +0 -31
- endoreg_db/data/lab_value/coagulation.yaml +0 -49
- endoreg_db/data/lab_value/electrolytes.yaml +0 -190
- endoreg_db/data/lab_value/gastrointestinal_function.yaml +0 -121
- endoreg_db/data/lab_value/hematology.yaml +0 -169
- endoreg_db/data/lab_value/hormones.yaml +0 -53
- endoreg_db/data/lab_value/lipids.yaml +0 -44
- endoreg_db/data/lab_value/misc.yaml +0 -30
- endoreg_db/data/lab_value/renal_function.yaml +0 -11
- endoreg_db/data/label/label/data.yaml +0 -62
- endoreg_db/data/label/label-set/data.yaml +0 -18
- endoreg_db/data/label/label-type/data.yaml +0 -7
- endoreg_db/data/log_type/data.yaml +0 -57
- endoreg_db/data/material/material.yaml +0 -91
- endoreg_db/data/medication/anticoagulation.yaml +0 -65
- endoreg_db/data/medication/tah.yaml +0 -70
- endoreg_db/data/medication_indication/anticoagulation.yaml +0 -120
- endoreg_db/data/medication_indication_type/data.yaml +0 -11
- endoreg_db/data/medication_indication_type/thrombembolism.yaml +0 -41
- endoreg_db/data/medication_intake_time/base.yaml +0 -31
- endoreg_db/data/medication_schedule/apixaban.yaml +0 -95
- endoreg_db/data/medication_schedule/ass.yaml +0 -12
- endoreg_db/data/medication_schedule/enoxaparin.yaml +0 -26
- endoreg_db/data/model_type/data.yaml +0 -7
- endoreg_db/data/network_device/data.yaml +0 -29
- endoreg_db/data/network_device_type/data.yaml +0 -12
- endoreg_db/data/patient_lab_sample_type/generic.yaml +0 -6
- endoreg_db/data/pdf_type/data.yaml +0 -28
- endoreg_db/data/product/green_endoscopy_dashboard_Product.yaml +0 -66
- endoreg_db/data/product_group/green_endoscopy_dashboard_ProductGroup.yaml +0 -33
- endoreg_db/data/product_material/green_endoscopy_dashboard_ProductMaterial.yaml +0 -308
- endoreg_db/data/product_weight/green_endoscopy_dashboard_ProductWeight.yaml +0 -88
- endoreg_db/data/profession/data.yaml +0 -70
- endoreg_db/data/reference_product/green_endoscopy_dashboard_ReferenceProduct.yaml +0 -55
- endoreg_db/data/report_reader_flag/ukw-examination-generic.yaml +0 -26
- endoreg_db/data/report_reader_flag/ukw-histology-generic.yaml +0 -19
- endoreg_db/data/resource/green_endoscopy_dashboard_Resource.yaml +0 -15
- endoreg_db/data/tmp/chronic_kidney_disease.yaml +0 -0
- endoreg_db/data/tmp/congestive_heart_failure.yaml +0 -0
- endoreg_db/data/transport_route/green_endoscopy_dashboard_TransportRoute.yaml +0 -12
- endoreg_db/data/unit/concentration.yaml +0 -92
- endoreg_db/data/unit/data.yaml +0 -17
- endoreg_db/data/unit/length.yaml +0 -31
- endoreg_db/data/unit/misc.yaml +0 -20
- endoreg_db/data/unit/rate.yaml +0 -6
- endoreg_db/data/unit/time.yaml +0 -13
- endoreg_db/data/unit/volume.yaml +0 -35
- endoreg_db/data/unit/weight.yaml +0 -38
- endoreg_db/data/waste/data.yaml +0 -12
- endoreg_db/forms/__init__.py +0 -3
- endoreg_db/forms/questionnaires/__init__.py +0 -1
- endoreg_db/forms/questionnaires/tto_questionnaire.py +0 -23
- endoreg_db/forms/settings/__init__.py +0 -8
- endoreg_db/forms/unit.py +0 -6
- endoreg_db/management/commands/_load_model_template.py +0 -41
- endoreg_db/management/commands/delete_all.py +0 -18
- endoreg_db/management/commands/delete_legacy_images.py +0 -19
- endoreg_db/management/commands/delete_legacy_videos.py +0 -17
- endoreg_db/management/commands/extract_legacy_video_frames.py +0 -18
- endoreg_db/management/commands/fetch_legacy_image_dataset.py +0 -32
- endoreg_db/management/commands/fix_auth_permission.py +0 -20
- endoreg_db/management/commands/import_legacy_images.py +0 -94
- endoreg_db/management/commands/import_legacy_videos.py +0 -76
- endoreg_db/management/commands/load_active_model_data.py +0 -45
- endoreg_db/management/commands/load_ai_model_data.py +0 -45
- endoreg_db/management/commands/load_base_db_data.py +0 -136
- endoreg_db/management/commands/load_center_data.py +0 -43
- endoreg_db/management/commands/load_disease_classification_choices_data.py +0 -41
- endoreg_db/management/commands/load_disease_classification_data.py +0 -41
- endoreg_db/management/commands/load_disease_data.py +0 -40
- endoreg_db/management/commands/load_distribution_data.py +0 -66
- endoreg_db/management/commands/load_endoscope_type_data.py +0 -45
- endoreg_db/management/commands/load_endoscopy_processor_data.py +0 -45
- endoreg_db/management/commands/load_event_data.py +0 -41
- endoreg_db/management/commands/load_examination_data.py +0 -75
- endoreg_db/management/commands/load_g_play_data.py +0 -113
- endoreg_db/management/commands/load_gender_data.py +0 -44
- endoreg_db/management/commands/load_green_endoscopy_wuerzburg_data.py +0 -133
- endoreg_db/management/commands/load_information_source.py +0 -45
- endoreg_db/management/commands/load_lab_value_data.py +0 -50
- endoreg_db/management/commands/load_label_data.py +0 -67
- endoreg_db/management/commands/load_logging_data.py +0 -39
- endoreg_db/management/commands/load_medication_data.py +0 -41
- endoreg_db/management/commands/load_medication_indication_data.py +0 -63
- endoreg_db/management/commands/load_medication_indication_type_data.py +0 -41
- endoreg_db/management/commands/load_medication_intake_time_data.py +0 -41
- endoreg_db/management/commands/load_medication_schedule_data.py +0 -55
- endoreg_db/management/commands/load_network_data.py +0 -57
- endoreg_db/management/commands/load_pdf_type_data.py +0 -61
- endoreg_db/management/commands/load_profession_data.py +0 -44
- endoreg_db/management/commands/load_report_reader_flag.py +0 -46
- endoreg_db/management/commands/load_unit_data.py +0 -46
- endoreg_db/management/commands/load_user_groups.py +0 -28
- endoreg_db/management/commands/register_ai_model.py +0 -64
- endoreg_db/management/commands/reset_celery_schedule.py +0 -9
- endoreg_db/migrations/0001_initial.py +0 -1567
- endoreg_db/migrations/0002_anonymizedimagelabel_anonymousimageannotation_and_more.py +0 -55
- endoreg_db/migrations/0003_anonymousimageannotation_original_image_url_and_more.py +0 -39
- endoreg_db/migrations/0004_alter_rawpdffile_file.py +0 -20
- endoreg_db/migrations/0005_uploadedfile_alter_rawpdffile_file_anonymizedfile.py +0 -40
- endoreg_db/migrations/0006_alter_rawpdffile_file.py +0 -20
- endoreg_db/migrations/0007_networkdevicelogentry_datetime_and_more.py +0 -43
- endoreg_db/migrations/0008_networkdevicelogentry_aglnet_ip_and_more.py +0 -28
- endoreg_db/migrations/0009_alter_networkdevicelogentry_vpn_service_status.py +0 -18
- endoreg_db/migrations/0010_remove_networkdevicelogentry_hostname.py +0 -17
- endoreg_db/migrations/__init__.py +0 -0
- endoreg_db/models/__init__.py +0 -73
- endoreg_db/models/ai_model/__init__.py +0 -3
- endoreg_db/models/ai_model/active_model.py +0 -9
- endoreg_db/models/ai_model/model_meta.py +0 -24
- endoreg_db/models/ai_model/model_type.py +0 -26
- endoreg_db/models/ai_model/utils.py +0 -8
- endoreg_db/models/annotation/__init__.py +0 -3
- endoreg_db/models/annotation/anonymized_image_annotation.py +0 -60
- endoreg_db/models/annotation/binary_classification_annotation_task.py +0 -80
- endoreg_db/models/annotation/image_classification.py +0 -27
- endoreg_db/models/case_template/__init__.py +0 -6
- endoreg_db/models/case_template/case_template.py +0 -81
- endoreg_db/models/case_template/case_template_rule.py +0 -276
- endoreg_db/models/case_template/case_template_rule_value.py +0 -73
- endoreg_db/models/case_template/case_template_type.py +0 -28
- endoreg_db/models/center/__init__.py +0 -4
- endoreg_db/models/center/center.py +0 -25
- endoreg_db/models/center/center_product.py +0 -34
- endoreg_db/models/center/center_resource.py +0 -19
- endoreg_db/models/center/center_waste.py +0 -11
- endoreg_db/models/data_file/__init__.py +0 -6
- endoreg_db/models/data_file/base_classes/__init__.py +0 -2
- endoreg_db/models/data_file/base_classes/abstract_frame.py +0 -51
- endoreg_db/models/data_file/base_classes/abstract_video.py +0 -201
- endoreg_db/models/data_file/frame.py +0 -45
- endoreg_db/models/data_file/import_classes/__init__.py +0 -32
- endoreg_db/models/data_file/import_classes/processing_functions/__init__.py +0 -35
- endoreg_db/models/data_file/import_classes/processing_functions/pdf.py +0 -28
- endoreg_db/models/data_file/import_classes/processing_functions/video.py +0 -260
- endoreg_db/models/data_file/import_classes/raw_pdf.py +0 -188
- endoreg_db/models/data_file/import_classes/raw_video.py +0 -343
- endoreg_db/models/data_file/metadata/__init__.py +0 -3
- endoreg_db/models/data_file/metadata/pdf_meta.py +0 -70
- endoreg_db/models/data_file/metadata/sensitive_meta.py +0 -31
- endoreg_db/models/data_file/metadata/video_meta.py +0 -133
- endoreg_db/models/data_file/report_file.py +0 -89
- endoreg_db/models/data_file/video/__init__.py +0 -7
- endoreg_db/models/data_file/video/import_meta.py +0 -25
- endoreg_db/models/data_file/video/video.py +0 -25
- endoreg_db/models/data_file/video_segment.py +0 -107
- endoreg_db/models/disease.py +0 -56
- endoreg_db/models/emission/__init__.py +0 -1
- endoreg_db/models/emission/emission_factor.py +0 -20
- endoreg_db/models/event.py +0 -22
- endoreg_db/models/examination/__init__.py +0 -4
- endoreg_db/models/examination/examination.py +0 -26
- endoreg_db/models/examination/examination_time.py +0 -27
- endoreg_db/models/examination/examination_time_type.py +0 -24
- endoreg_db/models/examination/examination_type.py +0 -18
- endoreg_db/models/hardware/__init__.py +0 -2
- endoreg_db/models/hardware/endoscope.py +0 -44
- endoreg_db/models/hardware/endoscopy_processor.py +0 -143
- endoreg_db/models/information_source.py +0 -29
- endoreg_db/models/label/__init__.py +0 -1
- endoreg_db/models/label/label.py +0 -84
- endoreg_db/models/laboratory/__init__.py +0 -1
- endoreg_db/models/laboratory/lab_value.py +0 -102
- endoreg_db/models/legacy_data/__init__.py +0 -3
- endoreg_db/models/legacy_data/image.py +0 -34
- endoreg_db/models/logging/__init__.py +0 -4
- endoreg_db/models/logging/agl_service.py +0 -19
- endoreg_db/models/logging/base.py +0 -22
- endoreg_db/models/logging/log_type.py +0 -23
- endoreg_db/models/logging/network_device.py +0 -27
- endoreg_db/models/medication/__init__.py +0 -1
- endoreg_db/models/medication/medication.py +0 -148
- endoreg_db/models/network/__init__.py +0 -3
- endoreg_db/models/network/agl_service.py +0 -38
- endoreg_db/models/network/network_device.py +0 -53
- endoreg_db/models/network/network_device_type.py +0 -23
- endoreg_db/models/other/__init__.py +0 -5
- endoreg_db/models/other/distribution.py +0 -215
- endoreg_db/models/other/material.py +0 -16
- endoreg_db/models/other/resource.py +0 -18
- endoreg_db/models/other/transport_route.py +0 -21
- endoreg_db/models/other/waste.py +0 -20
- endoreg_db/models/patient_examination/__init__.py +0 -35
- endoreg_db/models/permissions/__init__.py +0 -44
- endoreg_db/models/persons/__init__.py +0 -7
- endoreg_db/models/persons/examiner/__init__.py +0 -2
- endoreg_db/models/persons/examiner/examiner.py +0 -16
- endoreg_db/models/persons/examiner/examiner_type.py +0 -2
- endoreg_db/models/persons/first_name.py +0 -18
- endoreg_db/models/persons/gender.py +0 -22
- endoreg_db/models/persons/last_name.py +0 -20
- endoreg_db/models/persons/patient/__init__.py +0 -8
- endoreg_db/models/persons/patient/case/__init__.py +0 -0
- endoreg_db/models/persons/patient/case/case.py +0 -30
- endoreg_db/models/persons/patient/patient.py +0 -216
- endoreg_db/models/persons/patient/patient_disease.py +0 -16
- endoreg_db/models/persons/patient/patient_event.py +0 -22
- endoreg_db/models/persons/patient/patient_lab_sample.py +0 -106
- endoreg_db/models/persons/patient/patient_lab_value.py +0 -176
- endoreg_db/models/persons/patient/patient_medication.py +0 -44
- endoreg_db/models/persons/patient/patient_medication_schedule.py +0 -28
- endoreg_db/models/persons/person.py +0 -31
- endoreg_db/models/persons/portal_user_information.py +0 -27
- endoreg_db/models/prediction/__init__.py +0 -2
- endoreg_db/models/prediction/image_classification.py +0 -37
- endoreg_db/models/prediction/video_prediction_meta.py +0 -244
- endoreg_db/models/product/__init__.py +0 -5
- endoreg_db/models/product/product.py +0 -97
- endoreg_db/models/product/product_group.py +0 -19
- endoreg_db/models/product/product_material.py +0 -24
- endoreg_db/models/product/product_weight.py +0 -26
- endoreg_db/models/product/reference_product.py +0 -99
- endoreg_db/models/questionnaires/__init__.py +0 -114
- endoreg_db/models/quiz/__init__.py +0 -2
- endoreg_db/models/quiz/quiz_answer.py +0 -41
- endoreg_db/models/quiz/quiz_question.py +0 -54
- endoreg_db/models/report_reader/__init__.py +0 -2
- endoreg_db/models/report_reader/report_reader_config.py +0 -53
- endoreg_db/models/report_reader/report_reader_flag.py +0 -20
- endoreg_db/models/rules/__init__.py +0 -5
- endoreg_db/models/rules/rule.py +0 -24
- endoreg_db/models/rules/rule_applicator.py +0 -224
- endoreg_db/models/rules/rule_attribute_dtype.py +0 -19
- endoreg_db/models/rules/rule_type.py +0 -22
- endoreg_db/models/rules/ruleset.py +0 -19
- endoreg_db/models/unit.py +0 -22
- endoreg_db/queries/__init__.py +0 -5
- endoreg_db/queries/annotations/__init__.py +0 -3
- endoreg_db/queries/annotations/legacy.py +0 -158
- endoreg_db/queries/get/__init__.py +0 -6
- endoreg_db/queries/get/annotation.py +0 -0
- endoreg_db/queries/get/center.py +0 -42
- endoreg_db/queries/get/model.py +0 -13
- endoreg_db/queries/get/patient.py +0 -14
- endoreg_db/queries/get/patient_examination.py +0 -20
- endoreg_db/queries/get/prediction.py +0 -0
- endoreg_db/queries/get/report_file.py +0 -33
- endoreg_db/queries/get/video.py +0 -31
- endoreg_db/queries/get/video_import_meta.py +0 -0
- endoreg_db/queries/get/video_prediction_meta.py +0 -0
- endoreg_db/queries/sanity/__init_.py +0 -0
- endoreg_db/serializers/__init__.py +0 -10
- endoreg_db/serializers/ai_model.py +0 -19
- endoreg_db/serializers/annotation.py +0 -17
- endoreg_db/serializers/center.py +0 -11
- endoreg_db/serializers/examination.py +0 -33
- endoreg_db/serializers/frame.py +0 -13
- endoreg_db/serializers/hardware.py +0 -21
- endoreg_db/serializers/label.py +0 -22
- endoreg_db/serializers/patient.py +0 -10
- endoreg_db/serializers/prediction.py +0 -15
- endoreg_db/serializers/report_file.py +0 -7
- endoreg_db/serializers/video.py +0 -27
- endoreg_db/utils/__init__.py +0 -1
- endoreg_db/utils/cropping.py +0 -29
- endoreg_db/utils/dataloader.py +0 -92
- endoreg_db/utils/file_operations.py +0 -30
- endoreg_db/utils/hashs.py +0 -34
- endoreg_db/utils/legacy_ocr.py +0 -201
- endoreg_db/utils/ocr.py +0 -190
- endoreg_db/utils/uuid.py +0 -4
- endoreg_db/utils/video_metadata.py +0 -87
- endoreg_db-0.5.3.dist-info/METADATA +0 -28
- endoreg_db-0.5.3.dist-info/RECORD +0 -319
- {endoreg_db-0.5.3.dist-info/licenses → endoreg_db-0.6.0.dist-info}/LICENSE +0 -0
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
from ...models import LabelSet, ImageClassificationAnnotation
|
|
2
|
-
from django.db.models import Q, F
|
|
3
|
-
from django.db import models
|
|
4
|
-
from tqdm import tqdm
|
|
5
|
-
from collections import defaultdict
|
|
6
|
-
|
|
7
|
-
# def get_legacy_annotations_for_labelset(labelset_name, version=None):
|
|
8
|
-
# """
|
|
9
|
-
# Retrieve annotations for a given label set for training.
|
|
10
|
-
|
|
11
|
-
# Args:
|
|
12
|
-
# - labelset_name (str): The name of the label set.
|
|
13
|
-
# - version (int, optional): The version of the label set. If not specified, the latest version is fetched.
|
|
14
|
-
|
|
15
|
-
# Returns:
|
|
16
|
-
# - list[dict]: A list of dictionaries. Each dictionary represents an image and its annotations.
|
|
17
|
-
# Format: [{"frame": <frame_object>, "annotations": [{"label": <label_name>, "value": <value>}, ...]}, ...]
|
|
18
|
-
|
|
19
|
-
# Example:
|
|
20
|
-
# annotations_for_training = get_annotations_for_labelset("YourLabelSetName", version=2)
|
|
21
|
-
|
|
22
|
-
# """
|
|
23
|
-
|
|
24
|
-
# # Fetch the label set based on the name and optionally the version
|
|
25
|
-
# if version:
|
|
26
|
-
# labelset = LabelSet.objects.get(name=labelset_name, version=version)
|
|
27
|
-
# else:
|
|
28
|
-
# labelset = LabelSet.objects.filter(name=labelset_name).order_by('-version').first()
|
|
29
|
-
# if not labelset:
|
|
30
|
-
# raise ValueError(f"No label set found with the name: {labelset_name}")
|
|
31
|
-
|
|
32
|
-
# # Retrieve all labels in the label set
|
|
33
|
-
# labels_in_set = labelset.labels.all()
|
|
34
|
-
|
|
35
|
-
# # Get the most recent annotations for each frame/label combination
|
|
36
|
-
# annotations = ImageClassificationAnnotation.objects.filter(label__in=labels_in_set)
|
|
37
|
-
# annotations = annotations.annotate(
|
|
38
|
-
# latest_annotation=models.Window(
|
|
39
|
-
# expression=models.functions.RowNumber(),
|
|
40
|
-
# partition_by=[F('legacy_image'), F('label')],
|
|
41
|
-
# order_by=F('date_modified').desc()
|
|
42
|
-
# )
|
|
43
|
-
# ).filter(latest_annotation=1)
|
|
44
|
-
|
|
45
|
-
# # Organize the annotations by image/frame
|
|
46
|
-
# organized_annotations = []
|
|
47
|
-
|
|
48
|
-
# for annotation in tqdm(annotations):
|
|
49
|
-
# # ic(annotation)
|
|
50
|
-
# # Check if the frame is already in the organized list
|
|
51
|
-
# existing_entry = next((entry for entry in organized_annotations if entry['legacy_image'] == annotation.legacy_frame), None)
|
|
52
|
-
|
|
53
|
-
# if existing_entry:
|
|
54
|
-
# # Add this annotation to the existing frame's annotations
|
|
55
|
-
# existing_entry['annotations'].append({
|
|
56
|
-
# "label": annotation.label.name,
|
|
57
|
-
# "value": annotation.value
|
|
58
|
-
# })
|
|
59
|
-
# else:
|
|
60
|
-
# # Create a new entry for this frame
|
|
61
|
-
# organized_annotations.append({
|
|
62
|
-
# "legacy_image": annotation.legacy_image,
|
|
63
|
-
# "annotations": [{
|
|
64
|
-
# "label": annotation.label.name,
|
|
65
|
-
# "value": annotation.value
|
|
66
|
-
# }]
|
|
67
|
-
# })
|
|
68
|
-
|
|
69
|
-
# return organized_annotations
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
def get_legacy_annotations_for_labelset(labelset_name, version=None):
|
|
74
|
-
"""
|
|
75
|
-
... [rest of your docstring]
|
|
76
|
-
"""
|
|
77
|
-
|
|
78
|
-
# Fetch the label set based on the name and optionally the version
|
|
79
|
-
if version:
|
|
80
|
-
labelset = LabelSet.objects.get(name=labelset_name, version=version)
|
|
81
|
-
else:
|
|
82
|
-
labelset = LabelSet.objects.filter(name=labelset_name).order_by('-version').first()
|
|
83
|
-
if not labelset:
|
|
84
|
-
raise ValueError(f"No label set found with the name: {labelset_name}")
|
|
85
|
-
|
|
86
|
-
# Retrieve all labels in the label set
|
|
87
|
-
labels_in_set = labelset.labels.all()
|
|
88
|
-
|
|
89
|
-
# Get the most recent annotations for each frame/label combination
|
|
90
|
-
annotations = (ImageClassificationAnnotation.objects
|
|
91
|
-
.filter(label__in=labels_in_set)
|
|
92
|
-
.select_related('legacy_image', 'label') # Reduce number of queries
|
|
93
|
-
.annotate(
|
|
94
|
-
latest_annotation=models.Window(
|
|
95
|
-
expression=models.functions.RowNumber(),
|
|
96
|
-
partition_by=[F('legacy_image'), F('label')],
|
|
97
|
-
order_by=F('date_modified').desc()
|
|
98
|
-
)
|
|
99
|
-
).filter(latest_annotation=1))
|
|
100
|
-
|
|
101
|
-
# Organize the annotations by image/frame using a defaultdict
|
|
102
|
-
organized_annotations_dict = defaultdict(lambda: {
|
|
103
|
-
"legacy_image": None,
|
|
104
|
-
"annotations": []
|
|
105
|
-
})
|
|
106
|
-
|
|
107
|
-
for annotation in tqdm(annotations):
|
|
108
|
-
organized_entry = organized_annotations_dict[annotation.legacy_image.id]
|
|
109
|
-
organized_entry["legacy_image"] = annotation.legacy_image
|
|
110
|
-
organized_entry["annotations"].append({
|
|
111
|
-
"label": annotation.label.name,
|
|
112
|
-
"value": annotation.value
|
|
113
|
-
})
|
|
114
|
-
|
|
115
|
-
# Convert organized_annotations_dict to a list
|
|
116
|
-
organized_annotations = list(organized_annotations_dict.values())
|
|
117
|
-
|
|
118
|
-
return organized_annotations
|
|
119
|
-
|
|
120
|
-
def generate_legacy_dataset_output(labelset_name, version=None):
|
|
121
|
-
"""
|
|
122
|
-
Generate an output suitable for creating PyTorch datasets.
|
|
123
|
-
|
|
124
|
-
Args:
|
|
125
|
-
- labelset_name (str): The name of the label set.
|
|
126
|
-
- version (int, optional): The version of the label set. If not specified, the latest version is fetched.
|
|
127
|
-
|
|
128
|
-
Returns:
|
|
129
|
-
- list[dict]: A list of dictionaries, where each dictionary contains the file path and the labels.
|
|
130
|
-
Format: [{"path": <file_path>, "labels": [<label_1_value>, <label_2_value>, ...]}, ...]
|
|
131
|
-
- labelset[LabelSet]: The label set that was used to generate the output.
|
|
132
|
-
"""
|
|
133
|
-
|
|
134
|
-
# First, retrieve the organized annotations using the previously defined function
|
|
135
|
-
organized_annotations = get_legacy_annotations_for_labelset(labelset_name, version)
|
|
136
|
-
|
|
137
|
-
# Fetch all labels from the labelset for consistent ordering
|
|
138
|
-
labelset = LabelSet.objects.get(name=labelset_name, version=version)
|
|
139
|
-
all_labels = labelset.get_labels_in_order()
|
|
140
|
-
|
|
141
|
-
dataset_output = []
|
|
142
|
-
|
|
143
|
-
for entry in organized_annotations:
|
|
144
|
-
# Prepare a dictionary for each frame
|
|
145
|
-
frame_data = {
|
|
146
|
-
"path": entry['legacy_image'].image.path, # Assuming 'image' field stores the file path
|
|
147
|
-
"labels": [-1] * len(all_labels) # Initialize with -1 for all labels
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
# Update the labels based on the annotations
|
|
151
|
-
for annotation in entry['annotations']:
|
|
152
|
-
index = next((i for i, label in enumerate(all_labels) if label.name == annotation['label']), None)
|
|
153
|
-
if index is not None:
|
|
154
|
-
frame_data['labels'][index] = int(annotation['value'])
|
|
155
|
-
|
|
156
|
-
dataset_output.append(frame_data)
|
|
157
|
-
|
|
158
|
-
return dataset_output, labelset
|
|
File without changes
|
endoreg_db/queries/get/center.py
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
from endoreg_db.models import Center
|
|
2
|
-
from typing import Optional
|
|
3
|
-
|
|
4
|
-
def get_centers() -> Center:
|
|
5
|
-
"""
|
|
6
|
-
Returns all Center objects from the database.
|
|
7
|
-
"""
|
|
8
|
-
return Center.objects.all()
|
|
9
|
-
|
|
10
|
-
def get_center_by_name(name) -> Optional[Center]:
|
|
11
|
-
"""Retrieve a Center object by its name.
|
|
12
|
-
|
|
13
|
-
Args:
|
|
14
|
-
name (str): The name of the center to retrieve.
|
|
15
|
-
|
|
16
|
-
Returns:
|
|
17
|
-
Optional[Center]: The Center object with the given name, or None if it does not exist.
|
|
18
|
-
"""
|
|
19
|
-
return Center.objects.get(name=name)
|
|
20
|
-
|
|
21
|
-
def get_center_by_id(id) -> Optional[Center]:
|
|
22
|
-
"""Retrieve a Center object by its id.
|
|
23
|
-
|
|
24
|
-
Args:
|
|
25
|
-
id (int): The id of the center to retrieve.
|
|
26
|
-
|
|
27
|
-
Returns:
|
|
28
|
-
Optional[Center]: The Center object with the given id, or None if it does not exist.
|
|
29
|
-
"""
|
|
30
|
-
return Center.objects.get(id=id)
|
|
31
|
-
|
|
32
|
-
def get_center_by_natural_key(name: str) -> Optional[Center]:
|
|
33
|
-
"""
|
|
34
|
-
Retrieve a Center object by its natural key.
|
|
35
|
-
|
|
36
|
-
Args:
|
|
37
|
-
name: The name of the center to retrieve.
|
|
38
|
-
|
|
39
|
-
Returns:
|
|
40
|
-
The Center object with the given name, or None if it does not exist.
|
|
41
|
-
"""
|
|
42
|
-
return Center.objects.get_by_natural_key(name=name)
|
endoreg_db/queries/get/model.py
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
from endoreg_db.models import (
|
|
2
|
-
ModelMeta,
|
|
3
|
-
)
|
|
4
|
-
|
|
5
|
-
def get_latest_model_by_name(model_name):
|
|
6
|
-
"""
|
|
7
|
-
Expects model name. Fetches models by name from database, sorts by version and returns latest version.
|
|
8
|
-
"""
|
|
9
|
-
models = ModelMeta.objects.filter(name=model_name).order_by('-version')
|
|
10
|
-
if len(models) == 0:
|
|
11
|
-
return None
|
|
12
|
-
else:
|
|
13
|
-
return models[0]
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
from endoreg_db.models import Patient
|
|
2
|
-
|
|
3
|
-
def get_patients() -> Patient:
|
|
4
|
-
"""
|
|
5
|
-
Returns all Patient objects from the database.
|
|
6
|
-
"""
|
|
7
|
-
return Patient.objects.all()
|
|
8
|
-
|
|
9
|
-
def get_patients_without_dob() -> Patient:
|
|
10
|
-
"""
|
|
11
|
-
Returns all Patient objects from the database without a date of birth.
|
|
12
|
-
"""
|
|
13
|
-
return Patient.objects.filter(dob__isnull=True)
|
|
14
|
-
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
from endoreg_db.models import PatientExamination
|
|
2
|
-
from typing import Optional
|
|
3
|
-
|
|
4
|
-
def get_patient_examinations() -> PatientExamination:
|
|
5
|
-
"""
|
|
6
|
-
Returns all PatientExamination objects from the database.
|
|
7
|
-
"""
|
|
8
|
-
return PatientExamination.objects.all()
|
|
9
|
-
|
|
10
|
-
def get_patient_examinations_without_report_file() -> PatientExamination:
|
|
11
|
-
"""
|
|
12
|
-
Returns all PatientExamination objects from the database without a report_file.
|
|
13
|
-
"""
|
|
14
|
-
return PatientExamination.objects.filter(report_file__isnull=True)
|
|
15
|
-
|
|
16
|
-
def get_patient_examinations_without_video() -> PatientExamination:
|
|
17
|
-
"""
|
|
18
|
-
Returns all PatientExamination objects from the database without a video.
|
|
19
|
-
"""
|
|
20
|
-
return PatientExamination.objects.filter(video__isnull=True)
|
|
File without changes
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
from endoreg_db.models import ReportFile
|
|
2
|
-
from typing import Optional
|
|
3
|
-
|
|
4
|
-
def get_report_files() -> ReportFile:
|
|
5
|
-
"""
|
|
6
|
-
Returns all ReportFile objects from the database.
|
|
7
|
-
"""
|
|
8
|
-
return ReportFile.objects.all()
|
|
9
|
-
|
|
10
|
-
def get_report_file_by_id(id) -> Optional[ReportFile]:
|
|
11
|
-
"""Retrieve a ReportFile object by its id.
|
|
12
|
-
|
|
13
|
-
Args:
|
|
14
|
-
id (int): The id of the report_file to retrieve.
|
|
15
|
-
|
|
16
|
-
Returns:
|
|
17
|
-
Optional[ReportFile]: The ReportFile object with the given id, or None if it does not exist.
|
|
18
|
-
"""
|
|
19
|
-
return ReportFile.objects.get(id=id)
|
|
20
|
-
|
|
21
|
-
def get_report_files_without_examination() -> ReportFile:
|
|
22
|
-
"""
|
|
23
|
-
Returns all ReportFile objects from the database without an examination.
|
|
24
|
-
"""
|
|
25
|
-
return ReportFile.objects.filter(patient_examination__isnull=True)
|
|
26
|
-
|
|
27
|
-
def get_report_files_without_patient() -> ReportFile:
|
|
28
|
-
"""
|
|
29
|
-
Returns all ReportFile objects from the database without a patient.
|
|
30
|
-
"""
|
|
31
|
-
return ReportFile.objects.filter(patient__isnull=True)
|
|
32
|
-
|
|
33
|
-
|
endoreg_db/queries/get/video.py
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
from endoreg_db.models import Video, PatientExamination
|
|
2
|
-
from typing import Optional
|
|
3
|
-
|
|
4
|
-
def get_videos() -> Video:
|
|
5
|
-
"""
|
|
6
|
-
Returns all Video objects from the database.
|
|
7
|
-
"""
|
|
8
|
-
return Video.objects.all()
|
|
9
|
-
|
|
10
|
-
def get_video_by_id(id) -> Optional[Video]:
|
|
11
|
-
"""Retrieve a Video object by its id.
|
|
12
|
-
|
|
13
|
-
Args:
|
|
14
|
-
id (int): The id of the video to retrieve.
|
|
15
|
-
|
|
16
|
-
Returns:
|
|
17
|
-
Optional[Video]: The Video object with the given id, or None if it does not exist.
|
|
18
|
-
"""
|
|
19
|
-
return Video.objects.get(id=id)
|
|
20
|
-
|
|
21
|
-
def get_video_without_examination() -> Video:
|
|
22
|
-
"""
|
|
23
|
-
Returns all Video objects from the database without an examination.
|
|
24
|
-
"""
|
|
25
|
-
return Video.objects.filter(patient_examination__isnull=True)
|
|
26
|
-
|
|
27
|
-
def get_video_without_patient() -> Video:
|
|
28
|
-
"""
|
|
29
|
-
Returns all Video objects from the database without a patient.
|
|
30
|
-
"""
|
|
31
|
-
return Video.objects.filter(patient__isnull=True)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
from endoreg_db.models import ModelMeta, ModelType, ActiveModel
|
|
2
|
-
from rest_framework import serializers
|
|
3
|
-
|
|
4
|
-
class ModelMetaSerializer(serializers.ModelSerializer):
|
|
5
|
-
weights = serializers.FileField(use_url=True) # use_url=True will provide the file's URI
|
|
6
|
-
|
|
7
|
-
class Meta:
|
|
8
|
-
model = ModelMeta
|
|
9
|
-
fields = '__all__'
|
|
10
|
-
|
|
11
|
-
class ModelTypeSerializer(serializers.ModelSerializer):
|
|
12
|
-
class Meta:
|
|
13
|
-
model = ModelType
|
|
14
|
-
fields = '__all__'
|
|
15
|
-
|
|
16
|
-
class ActiveModelSerializer(serializers.ModelSerializer):
|
|
17
|
-
class Meta:
|
|
18
|
-
model = ActiveModel
|
|
19
|
-
fields = '__all__'
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
from rest_framework import serializers
|
|
2
|
-
from endoreg_db.models import LegacyBinaryClassificationAnnotationTask, BinaryClassificationAnnotationTask, ImageClassificationAnnotation
|
|
3
|
-
|
|
4
|
-
class LegacyBinaryClassificationAnnotationTaskSerializer(serializers.ModelSerializer):
|
|
5
|
-
class Meta:
|
|
6
|
-
model = LegacyBinaryClassificationAnnotationTask
|
|
7
|
-
fields = '__all__'
|
|
8
|
-
|
|
9
|
-
class BinaryClassificationAnnotationTaskSerializer(serializers.ModelSerializer):
|
|
10
|
-
class Meta:
|
|
11
|
-
model = BinaryClassificationAnnotationTask
|
|
12
|
-
fields = '__all__'
|
|
13
|
-
|
|
14
|
-
class ImageClassificationAnnotationSerializer(serializers.ModelSerializer):
|
|
15
|
-
class Meta:
|
|
16
|
-
model = ImageClassificationAnnotation
|
|
17
|
-
fields = '__all__'
|
endoreg_db/serializers/center.py
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
from rest_framework import serializers
|
|
2
|
-
from endoreg_db.models import (
|
|
3
|
-
Examination,
|
|
4
|
-
ExaminationTimeType,
|
|
5
|
-
ExaminationTime,
|
|
6
|
-
ExaminationType,
|
|
7
|
-
PatientExamination
|
|
8
|
-
)
|
|
9
|
-
|
|
10
|
-
class ExaminationTimeTypeSerializer(serializers.ModelSerializer):
|
|
11
|
-
class Meta:
|
|
12
|
-
model = ExaminationTimeType
|
|
13
|
-
fields = '__all__'
|
|
14
|
-
|
|
15
|
-
class ExaminationTimeSerializer(serializers.ModelSerializer):
|
|
16
|
-
class Meta:
|
|
17
|
-
model = ExaminationTime
|
|
18
|
-
fields = '__all__'
|
|
19
|
-
|
|
20
|
-
class ExaminationTypeSerializer(serializers.ModelSerializer):
|
|
21
|
-
class Meta:
|
|
22
|
-
model = ExaminationType
|
|
23
|
-
fields = '__all__'
|
|
24
|
-
|
|
25
|
-
class ExaminationSerializer(serializers.ModelSerializer):
|
|
26
|
-
class Meta:
|
|
27
|
-
model = Examination
|
|
28
|
-
fields = '__all__'
|
|
29
|
-
|
|
30
|
-
class PatientExaminationSerializer(serializers.ModelSerializer):
|
|
31
|
-
class Meta:
|
|
32
|
-
model = PatientExamination
|
|
33
|
-
fields = '__all__'
|
endoreg_db/serializers/frame.py
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
from rest_framework import serializers
|
|
2
|
-
from endoreg_db.models import Frame, LegacyFrame
|
|
3
|
-
|
|
4
|
-
class FrameSerializer(serializers.ModelSerializer):
|
|
5
|
-
class Meta:
|
|
6
|
-
model = Frame
|
|
7
|
-
fields = '__all__'
|
|
8
|
-
|
|
9
|
-
class LegacyFrameSerializer(serializers.ModelSerializer):
|
|
10
|
-
class Meta:
|
|
11
|
-
model = LegacyFrame
|
|
12
|
-
fields = '__all__'
|
|
13
|
-
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
from rest_framework import serializers
|
|
2
|
-
from endoreg_db.models import (
|
|
3
|
-
Endoscope,
|
|
4
|
-
EndoscopeType,
|
|
5
|
-
EndoscopyProcessor,
|
|
6
|
-
)
|
|
7
|
-
|
|
8
|
-
class EndoscopeSerializer(serializers.ModelSerializer):
|
|
9
|
-
class Meta:
|
|
10
|
-
model = Endoscope
|
|
11
|
-
fields = '__all__'
|
|
12
|
-
|
|
13
|
-
class EndoscopyProcessorSerializer(serializers.ModelSerializer):
|
|
14
|
-
class Meta:
|
|
15
|
-
model = EndoscopyProcessor
|
|
16
|
-
fields = '__all__'
|
|
17
|
-
|
|
18
|
-
class EndoscopeTypeSerializer(serializers.ModelSerializer):
|
|
19
|
-
class Meta:
|
|
20
|
-
model = EndoscopeType
|
|
21
|
-
fields = '__all__'
|
endoreg_db/serializers/label.py
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
from rest_framework import serializers
|
|
2
|
-
from endoreg_db.models import (
|
|
3
|
-
Label,
|
|
4
|
-
LabelSet,
|
|
5
|
-
LabelType,
|
|
6
|
-
)
|
|
7
|
-
|
|
8
|
-
class LabelTypeSerializer(serializers.ModelSerializer):
|
|
9
|
-
class Meta:
|
|
10
|
-
model = LabelType
|
|
11
|
-
fields = '__all__'
|
|
12
|
-
|
|
13
|
-
class LabelSetSerializer(serializers.ModelSerializer):
|
|
14
|
-
class Meta:
|
|
15
|
-
model = LabelSet
|
|
16
|
-
fields = '__all__'
|
|
17
|
-
|
|
18
|
-
class LabelSerializer(serializers.ModelSerializer):
|
|
19
|
-
class Meta:
|
|
20
|
-
model = Label
|
|
21
|
-
fields = '__all__'
|
|
22
|
-
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
from rest_framework import serializers
|
|
2
|
-
from endoreg_db.models import (
|
|
3
|
-
ImageClassificationPrediction,
|
|
4
|
-
LegacyVideoPredictionMeta
|
|
5
|
-
)
|
|
6
|
-
|
|
7
|
-
class ImageClassificationPredictionSerializer(serializers.ModelSerializer):
|
|
8
|
-
class Meta:
|
|
9
|
-
model = ImageClassificationPrediction
|
|
10
|
-
fields = '__all__'
|
|
11
|
-
|
|
12
|
-
class LegacyVideoPredictionMetaSerializer(serializers.ModelSerializer):
|
|
13
|
-
class Meta:
|
|
14
|
-
model = LegacyVideoPredictionMeta
|
|
15
|
-
fields = '__all__'
|
endoreg_db/serializers/video.py
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
from rest_framework import serializers
|
|
2
|
-
from endoreg_db.models import Video, LegacyVideo, VideoImportMeta, LegacyLabelVideoSegment, LabelVideoSegment
|
|
3
|
-
|
|
4
|
-
class VideoSerializer(serializers.ModelSerializer):
|
|
5
|
-
class Meta:
|
|
6
|
-
model = Video
|
|
7
|
-
fields = '__all__'
|
|
8
|
-
|
|
9
|
-
class LegacyVideoSerializer(serializers.ModelSerializer):
|
|
10
|
-
class Meta:
|
|
11
|
-
model = LegacyVideo
|
|
12
|
-
fields = '__all__'
|
|
13
|
-
|
|
14
|
-
class VideoImportMetaSerializer(serializers.ModelSerializer):
|
|
15
|
-
class Meta:
|
|
16
|
-
model = VideoImportMeta
|
|
17
|
-
fields = '__all__'
|
|
18
|
-
|
|
19
|
-
class LabelVideoSegmentSerializer(serializers.ModelSerializer):
|
|
20
|
-
class Meta:
|
|
21
|
-
model = LabelVideoSegment
|
|
22
|
-
fields = '__all__'
|
|
23
|
-
|
|
24
|
-
class LegacyLabelVideoSegmentSerializer(serializers.ModelSerializer):
|
|
25
|
-
class Meta:
|
|
26
|
-
model = LegacyLabelVideoSegment
|
|
27
|
-
fields = '__all__'
|
endoreg_db/utils/__init__.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
from .dataloader import load_model_data_from_yaml
|
endoreg_db/utils/cropping.py
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
from PIL import Image
|
|
2
|
-
|
|
3
|
-
def crop_and_insert(image:Image, x, y, h, w, bg_color=(255, 255, 255)):
|
|
4
|
-
"""
|
|
5
|
-
Crops a region from an inverted grayscale image and inserts it into a white image of the same size as the original.
|
|
6
|
-
|
|
7
|
-
Parameters:
|
|
8
|
-
- fp: File path or a file object of the original image.
|
|
9
|
-
- x, y: The top-left coordinates of the rectangle to be cropped.
|
|
10
|
-
- h, w: The height and width of the rectangle to be cropped.
|
|
11
|
-
|
|
12
|
-
Returns:
|
|
13
|
-
A PIL Image object containing the original image with the specified region replaced.
|
|
14
|
-
"""
|
|
15
|
-
# Load the original image
|
|
16
|
-
original_image = image
|
|
17
|
-
|
|
18
|
-
# Crop the specified region from the inverted image
|
|
19
|
-
crop_rectangle = (x, y, x + w, y + h)
|
|
20
|
-
cropped_content = original_image.crop(crop_rectangle)
|
|
21
|
-
|
|
22
|
-
# Create a new white image of the same size as the original image
|
|
23
|
-
white_background = Image.new('RGB', original_image.size, bg_color)
|
|
24
|
-
|
|
25
|
-
# Paste the cropped content onto the white image at the specified location
|
|
26
|
-
white_background.paste(cropped_content, (x, y))
|
|
27
|
-
|
|
28
|
-
# The final image can be displayed or saved as needed
|
|
29
|
-
return white_background
|