endoreg-db 0.3.4__py3-none-any.whl → 0.3.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (350) hide show
  1. endoreg_db/admin.py +3 -3
  2. endoreg_db/apps.py +6 -6
  3. endoreg_db/data/__init__.py +65 -16
  4. endoreg_db/data/active_model/data.yaml +2 -2
  5. endoreg_db/data/case_template/rule/00_patient_lab_sample_add_default_value.yaml +167 -0
  6. endoreg_db/data/case_template/rule/01_patient-set-age.yaml +8 -0
  7. endoreg_db/data/case_template/rule/01_patient-set-gender.yaml +9 -0
  8. endoreg_db/data/case_template/rule/11_create_patient_lab_sample.yaml +23 -0
  9. endoreg_db/data/case_template/rule/12_create-patient_medication-anticoagulation.yaml +19 -0
  10. endoreg_db/data/case_template/rule/13_create-patient_medication_schedule-anticoagulation.yaml +19 -0
  11. endoreg_db/data/case_template/rule/19_create_patient.yaml +17 -0
  12. endoreg_db/data/case_template/rule_type/base_types.yaml +35 -0
  13. endoreg_db/data/case_template/rule_value_type/base_types.yaml +59 -0
  14. endoreg_db/data/case_template/template/base.yaml +8 -0
  15. endoreg_db/data/case_template/template_type/pre_endoscopy.yaml +3 -0
  16. endoreg_db/data/case_template/tmp/_rule_value +13 -0
  17. endoreg_db/data/case_template/tmp/rule/01_atrial_fibrillation.yaml +21 -0
  18. endoreg_db/data/case_template/tmp/rule/02_create_object.yaml +10 -0
  19. endoreg_db/data/case_template/tmp/template/atrial_fibrillation_low_risk.yaml +7 -0
  20. endoreg_db/data/center/data.yaml +60 -52
  21. endoreg_db/data/center_resource/green_endoscopy_dashboard_CenterResource.yaml +144 -0
  22. endoreg_db/data/center_waste/green_endoscopy_dashboard_CenterWaste.yaml +48 -0
  23. endoreg_db/data/disease/cardiovascular.yaml +37 -0
  24. endoreg_db/data/disease/hepatology.yaml +5 -0
  25. endoreg_db/data/disease/misc.yaml +6 -0
  26. endoreg_db/data/disease/renal.yaml +5 -0
  27. endoreg_db/data/disease_classification/chronic_kidney_disease.yaml +6 -0
  28. endoreg_db/data/disease_classification/coronary_vessel_disease.yaml +6 -0
  29. endoreg_db/data/disease_classification_choice/chronic_kidney_disease.yaml +41 -0
  30. endoreg_db/data/disease_classification_choice/coronary_vessel_disease.yaml +20 -0
  31. endoreg_db/data/distribution/date/patient.yaml +7 -0
  32. endoreg_db/data/distribution/single_categorical/patient.yaml +7 -0
  33. endoreg_db/data/emission_factor/green_endoscopy_dashboard_EmissionFactor.yaml +132 -0
  34. endoreg_db/data/endoscope_type/data.yaml +10 -10
  35. endoreg_db/data/endoscopy_processor/data.yaml +45 -45
  36. endoreg_db/data/event/cardiology.yaml +28 -0
  37. endoreg_db/data/event/neurology.yaml +14 -0
  38. endoreg_db/data/event/surgery.yaml +13 -0
  39. endoreg_db/data/event/thrombembolism.yaml +20 -0
  40. endoreg_db/data/examination/examinations/data.yaml +65 -16
  41. endoreg_db/data/examination/time/data.yaml +47 -47
  42. endoreg_db/data/examination/time-type/data.yaml +7 -7
  43. endoreg_db/data/examination/type/data.yaml +5 -5
  44. endoreg_db/data/gender/data.yaml +18 -0
  45. endoreg_db/data/information_source/data.yaml +30 -30
  46. endoreg_db/data/information_source/medication.yaml +6 -0
  47. endoreg_db/data/lab_value/cardiac_enzymes.yaml +31 -0
  48. endoreg_db/data/lab_value/coagulation.yaml +49 -0
  49. endoreg_db/data/lab_value/electrolytes.yaml +190 -0
  50. endoreg_db/data/lab_value/gastrointestinal_function.yaml +121 -0
  51. endoreg_db/data/lab_value/hematology.yaml +169 -0
  52. endoreg_db/data/lab_value/hormones.yaml +53 -0
  53. endoreg_db/data/lab_value/lipids.yaml +44 -0
  54. endoreg_db/data/lab_value/misc.yaml +30 -0
  55. endoreg_db/data/lab_value/renal_function.yaml +11 -0
  56. endoreg_db/data/label/label/data.yaml +62 -62
  57. endoreg_db/data/label/label-set/data.yaml +17 -17
  58. endoreg_db/data/label/label-type/data.yaml +6 -6
  59. endoreg_db/data/material/material.yaml +91 -0
  60. endoreg_db/data/medication/anticoagulation.yaml +65 -0
  61. endoreg_db/data/medication/tah.yaml +70 -0
  62. endoreg_db/data/medication_indication/anticoagulation.yaml +120 -0
  63. endoreg_db/data/medication_indication_type/data.yaml +11 -0
  64. endoreg_db/data/medication_indication_type/thrombembolism.yaml +41 -0
  65. endoreg_db/data/medication_intake_time/base.yaml +31 -0
  66. endoreg_db/data/medication_schedule/apixaban.yaml +95 -0
  67. endoreg_db/data/medication_schedule/ass.yaml +12 -0
  68. endoreg_db/data/medication_schedule/enoxaparin.yaml +26 -0
  69. endoreg_db/data/model_type/data.yaml +6 -6
  70. endoreg_db/data/patient_lab_sample_type/generic.yaml +6 -0
  71. endoreg_db/data/pdf_type/data.yaml +28 -28
  72. endoreg_db/data/product/green_endoscopy_dashboard_Product.yaml +66 -0
  73. endoreg_db/data/product_group/green_endoscopy_dashboard_ProductGroup.yaml +33 -0
  74. endoreg_db/data/product_material/green_endoscopy_dashboard_ProductMaterial.yaml +308 -0
  75. endoreg_db/data/product_weight/green_endoscopy_dashboard_ProductWeight.yaml +88 -0
  76. endoreg_db/data/profession/data.yaml +70 -70
  77. endoreg_db/data/reference_product/green_endoscopy_dashboard_ReferenceProduct.yaml +55 -0
  78. endoreg_db/data/report_reader_flag/ukw-examination-generic.yaml +26 -26
  79. endoreg_db/data/report_reader_flag/ukw-histology-generic.yaml +19 -19
  80. endoreg_db/data/resource/green_endoscopy_dashboard_Resource.yaml +15 -0
  81. endoreg_db/data/tmp/chronic_kidney_disease.yaml +0 -0
  82. endoreg_db/data/tmp/congestive_heart_failure.yaml +0 -0
  83. endoreg_db/data/transport_route/green_endoscopy_dashboard_TransportRoute.yaml +12 -0
  84. endoreg_db/data/unit/concentration.yaml +92 -0
  85. endoreg_db/data/unit/data.yaml +17 -17
  86. endoreg_db/data/unit/length.yaml +30 -30
  87. endoreg_db/data/unit/misc.yaml +20 -0
  88. endoreg_db/data/unit/rate.yaml +6 -0
  89. endoreg_db/data/unit/time.yaml +13 -0
  90. endoreg_db/data/unit/volume.yaml +35 -26
  91. endoreg_db/data/unit/weight.yaml +37 -30
  92. endoreg_db/data/waste/data.yaml +12 -0
  93. endoreg_db/forms/__init__.py +2 -2
  94. endoreg_db/forms/questionnaires/tto_questionnaire.py +23 -23
  95. endoreg_db/forms/settings/__init__.py +8 -8
  96. endoreg_db/forms/unit.py +5 -5
  97. endoreg_db/management/commands/_load_model_template.py +40 -40
  98. endoreg_db/management/commands/delete_all.py +18 -18
  99. endoreg_db/management/commands/delete_legacy_images.py +19 -19
  100. endoreg_db/management/commands/delete_legacy_videos.py +16 -16
  101. endoreg_db/management/commands/extract_legacy_video_frames.py +18 -18
  102. endoreg_db/management/commands/fetch_legacy_image_dataset.py +32 -32
  103. endoreg_db/management/commands/fix_auth_permission.py +20 -20
  104. endoreg_db/management/commands/import_legacy_images.py +94 -94
  105. endoreg_db/management/commands/import_legacy_videos.py +76 -76
  106. endoreg_db/management/commands/load_active_model_data.py +44 -44
  107. endoreg_db/management/commands/load_ai_model_data.py +44 -44
  108. endoreg_db/management/commands/load_base_db_data.py +128 -71
  109. endoreg_db/management/commands/load_center_data.py +42 -42
  110. endoreg_db/management/commands/load_disease_classification_choices_data.py +41 -0
  111. endoreg_db/management/commands/load_disease_classification_data.py +41 -0
  112. endoreg_db/management/commands/load_disease_data.py +40 -0
  113. endoreg_db/management/commands/load_distribution_data.py +66 -0
  114. endoreg_db/management/commands/load_endoscope_type_data.py +44 -44
  115. endoreg_db/management/commands/load_endoscopy_processor_data.py +44 -44
  116. endoreg_db/management/commands/load_event_data.py +41 -0
  117. endoreg_db/management/commands/load_examination_data.py +74 -74
  118. endoreg_db/management/commands/load_g_play_data.py +113 -0
  119. endoreg_db/management/commands/load_gender_data.py +44 -0
  120. endoreg_db/management/commands/load_green_endoscopy_wuerzburg_data.py +133 -0
  121. endoreg_db/management/commands/load_information_source.py +44 -44
  122. endoreg_db/management/commands/load_lab_value_data.py +50 -0
  123. endoreg_db/management/commands/load_label_data.py +66 -66
  124. endoreg_db/management/commands/load_medication_data.py +41 -0
  125. endoreg_db/management/commands/load_medication_indication_data.py +63 -0
  126. endoreg_db/management/commands/load_medication_indication_type_data.py +41 -0
  127. endoreg_db/management/commands/load_medication_intake_time_data.py +41 -0
  128. endoreg_db/management/commands/load_medication_schedule_data.py +55 -0
  129. endoreg_db/management/commands/load_pdf_type_data.py +60 -60
  130. endoreg_db/management/commands/load_profession_data.py +43 -43
  131. endoreg_db/management/commands/load_report_reader_flag.py +45 -45
  132. endoreg_db/management/commands/load_unit_data.py +45 -45
  133. endoreg_db/management/commands/load_user_groups.py +28 -28
  134. endoreg_db/management/commands/register_ai_model.py +65 -65
  135. endoreg_db/management/commands/reset_celery_schedule.py +9 -9
  136. endoreg_db/migrations/0001_initial.py +582 -582
  137. endoreg_db/migrations/0002_rawvideofile.py +26 -26
  138. endoreg_db/migrations/0003_rawvideofile_frames_required.py +18 -18
  139. endoreg_db/migrations/0004_rename_hash_rawvideofile_video_hash.py +18 -18
  140. endoreg_db/migrations/0005_ffmpegmeta_remove_videoimportmeta_center_and_more.py +56 -56
  141. endoreg_db/migrations/0006_rawvideofile_center_alter_videometa_processor.py +25 -25
  142. endoreg_db/migrations/0007_rawvideofile_processor.py +19 -19
  143. endoreg_db/migrations/0008_rename_frames_required_rawvideofile_state_frames_required.py +18 -18
  144. endoreg_db/migrations/0009_sensitivemeta_rawvideofile_sensitive_meta.py +31 -31
  145. endoreg_db/migrations/0010_rename_endoscope_serial_number_sensitivemeta_endoscope_sn.py +18 -18
  146. endoreg_db/migrations/0011_rawvideofile_state_sensitive_data_retrieved.py +18 -18
  147. endoreg_db/migrations/0012_rawvideofile_prediction_dir_and_more.py +109 -109
  148. endoreg_db/migrations/0013_rawpdffile.py +31 -31
  149. endoreg_db/migrations/0014_pdftype_alter_rawpdffile_file_pdfmeta.py +38 -38
  150. endoreg_db/migrations/0015_rename_report_processed_rawpdffile_state_report_processed_and_more.py +31 -31
  151. endoreg_db/migrations/0016_rawpdffile_state_report_processing_required.py +18 -18
  152. endoreg_db/migrations/0017_firstname_lastname_center_first_names_and_more.py +37 -37
  153. endoreg_db/migrations/0018_reportreaderflag_reportreaderconfig.py +37 -37
  154. endoreg_db/migrations/0019_pdftype_cut_off_above_lines_and_more.py +42 -42
  155. endoreg_db/migrations/0020_rename_endoscopy_info_line_pdftype_endoscope_info_line.py +18 -18
  156. endoreg_db/migrations/0021_alter_pdftype_endoscope_info_line.py +19 -19
  157. endoreg_db/migrations/0022_alter_pdftype_endoscope_info_line.py +19 -19
  158. endoreg_db/migrations/0023_ttoquestionnaire_alter_pdftype_endoscope_info_line.py +59 -59
  159. endoreg_db/migrations/0024_remove_ttoquestionnaire_infections_and_more.py +27 -27
  160. endoreg_db/migrations/0025_event_alter_rawpdffile_file_patientevent.py +42 -0
  161. endoreg_db/migrations/0026_disease_diseaseclassification_and_more.py +166 -0
  162. endoreg_db/migrations/0027_labvalue_abbreviation_labvalue_default_normal_range_and_more.py +38 -0
  163. endoreg_db/migrations/0028_alter_unit_abbreviation.py +18 -0
  164. endoreg_db/migrations/0029_medicationintaketime_and_more.py +75 -0
  165. endoreg_db/migrations/0030_medicationindicationtype_and_more.py +101 -0
  166. endoreg_db/migrations/0031_rename_adapt_to_liver_function_medication_adapt_to_age_and_more.py +38 -0
  167. endoreg_db/migrations/0032_alter_medicationschedule_therapy_duration_d.py +18 -0
  168. endoreg_db/migrations/0033_medicationindication_sources.py +18 -0
  169. endoreg_db/migrations/0034_alter_rawpdffile_file.py +20 -0
  170. endoreg_db/migrations/0035_alter_medicationindication_sources.py +18 -0
  171. endoreg_db/migrations/0036_alter_rawpdffile_file.py +20 -0
  172. endoreg_db/migrations/0037_alter_medicationindication_sources.py +18 -0
  173. endoreg_db/migrations/0038_emissionfactor_material_product_productgroup_and_more.py +164 -0
  174. endoreg_db/migrations/0039_referenceproduct_name.py +19 -0
  175. endoreg_db/migrations/0040_quizanswertype_quizquestiontype_quizquestion_and_more.py +50 -0
  176. endoreg_db/migrations/0041_gender_patientmedication_medication_indication_and_more.py +40 -0
  177. endoreg_db/migrations/0042_casetemplateruletype_casetemplaterulevalue_and_more.py +74 -0
  178. endoreg_db/migrations/0043_casetemplatetype_name_de_casetemplatetype_name_en.py +23 -0
  179. endoreg_db/migrations/0044_casetemplateruletype_name_de_and_more.py +23 -0
  180. endoreg_db/migrations/0045_casetemplaterulevalue_value_type.py +19 -0
  181. endoreg_db/migrations/0046_casetemplaterulevalue_target_field.py +18 -0
  182. endoreg_db/migrations/0047_casetemplaterule_target_model.py +18 -0
  183. endoreg_db/migrations/0048_remove_casetemplaterule_chained_rules_and_more.py +22 -0
  184. endoreg_db/migrations/0049_remove_casetemplaterule_rule_values.py +17 -0
  185. endoreg_db/migrations/0050_casetemplaterule_rule_values.py +18 -0
  186. endoreg_db/migrations/0051_remove_casetemplaterule_calling_rules_and_more.py +27 -0
  187. endoreg_db/migrations/0052_rename_case_template_type_casetemplate_template_type.py +18 -0
  188. endoreg_db/migrations/0053_patientlabsampletype_patientlabsample_and_more.py +38 -0
  189. endoreg_db/migrations/0054_multiplecategoricalvaluedistribution_and_more.py +69 -0
  190. endoreg_db/migrations/0055_remove_casetemplaterule_rule_values_and_more.py +59 -0
  191. endoreg_db/migrations/0056_datevaluedistribution_and_more.py +32 -0
  192. endoreg_db/migrations/0057_remove_datevaluedistribution_max_date_and_more.py +72 -0
  193. endoreg_db/migrations/0058_datevaluedistribution_description_and_more.py +28 -0
  194. endoreg_db/migrations/0059_casetemplaterule_rule_values.py +18 -0
  195. endoreg_db/migrations/0060_labvalue__default_date_value_distribution_and_more.py +44 -0
  196. endoreg_db/migrations/0061_remove_patientlabvalue_date_patientlabvalue_datetime.py +24 -0
  197. endoreg_db/migrations/0062_labvalue_numeric_precision.py +18 -0
  198. endoreg_db/migrations/0063_alter_labvalue_numeric_precision.py +18 -0
  199. endoreg_db/migrations/0064_casetemplaterule_extra_parameters_and_more.py +23 -0
  200. endoreg_db/migrations/0065_rename__date_value_distribution_casetemplaterule_date_value_distribution_and_more.py +58 -0
  201. endoreg_db/migrations/0066_alter_patientlabvalue_patient_and_more.py +29 -0
  202. endoreg_db/migrations/0067_alter_medicationindication_indication_type.py +19 -0
  203. endoreg_db/models/__init__.py +74 -57
  204. endoreg_db/models/ai_model/__init__.py +3 -3
  205. endoreg_db/models/ai_model/active_model.py +9 -9
  206. endoreg_db/models/ai_model/model_meta.py +24 -24
  207. endoreg_db/models/ai_model/model_type.py +25 -25
  208. endoreg_db/models/ai_model/utils.py +8 -8
  209. endoreg_db/models/annotation/__init__.py +1 -1
  210. endoreg_db/models/annotation/binary_classification_annotation_task.py +80 -80
  211. endoreg_db/models/annotation/image_classification.py +26 -26
  212. endoreg_db/models/case_template/__init__.py +6 -0
  213. endoreg_db/models/case_template/case_template.py +81 -0
  214. endoreg_db/models/case_template/case_template_rule.py +276 -0
  215. endoreg_db/models/case_template/case_template_rule_value.py +73 -0
  216. endoreg_db/models/case_template/case_template_type.py +28 -0
  217. endoreg_db/models/center/__init__.py +4 -0
  218. endoreg_db/models/{center.py → center/center.py} +24 -24
  219. endoreg_db/models/center/center_product.py +34 -0
  220. endoreg_db/models/center/center_resource.py +19 -0
  221. endoreg_db/models/center/center_waste.py +11 -0
  222. endoreg_db/models/data_file/__init__.py +5 -5
  223. endoreg_db/models/data_file/base_classes/__init__.py +2 -2
  224. endoreg_db/models/data_file/base_classes/abstract_frame.py +50 -50
  225. endoreg_db/models/data_file/base_classes/abstract_video.py +200 -200
  226. endoreg_db/models/data_file/frame.py +45 -45
  227. endoreg_db/models/data_file/import_classes/__init__.py +31 -31
  228. endoreg_db/models/data_file/import_classes/processing_functions/__init__.py +34 -34
  229. endoreg_db/models/data_file/import_classes/processing_functions/pdf.py +28 -28
  230. endoreg_db/models/data_file/import_classes/processing_functions/video.py +260 -260
  231. endoreg_db/models/data_file/import_classes/raw_pdf.py +188 -185
  232. endoreg_db/models/data_file/import_classes/raw_video.py +343 -343
  233. endoreg_db/models/data_file/metadata/__init__.py +3 -3
  234. endoreg_db/models/data_file/metadata/pdf_meta.py +70 -70
  235. endoreg_db/models/data_file/metadata/sensitive_meta.py +31 -31
  236. endoreg_db/models/data_file/metadata/video_meta.py +132 -131
  237. endoreg_db/models/data_file/report_file.py +89 -89
  238. endoreg_db/models/data_file/video/__init__.py +6 -6
  239. endoreg_db/models/data_file/video/import_meta.py +25 -25
  240. endoreg_db/models/data_file/video/video.py +25 -25
  241. endoreg_db/models/data_file/video_segment.py +107 -107
  242. endoreg_db/models/disease.py +56 -0
  243. endoreg_db/models/emission/__init__.py +1 -0
  244. endoreg_db/models/emission/emission_factor.py +20 -0
  245. endoreg_db/models/event.py +22 -0
  246. endoreg_db/models/examination/__init__.py +3 -3
  247. endoreg_db/models/examination/examination.py +26 -26
  248. endoreg_db/models/examination/examination_time.py +27 -27
  249. endoreg_db/models/examination/examination_time_type.py +24 -24
  250. endoreg_db/models/examination/examination_type.py +18 -18
  251. endoreg_db/models/hardware/__init__.py +1 -1
  252. endoreg_db/models/hardware/endoscope.py +44 -44
  253. endoreg_db/models/hardware/endoscopy_processor.py +143 -143
  254. endoreg_db/models/information_source.py +29 -22
  255. endoreg_db/models/label/label.py +84 -84
  256. endoreg_db/models/laboratory/__init__.py +1 -0
  257. endoreg_db/models/laboratory/lab_value.py +102 -0
  258. endoreg_db/models/legacy_data/__init__.py +3 -3
  259. endoreg_db/models/legacy_data/image.py +34 -34
  260. endoreg_db/models/medication/__init__.py +1 -0
  261. endoreg_db/models/medication/medication.py +148 -0
  262. endoreg_db/models/other/__init__.py +5 -0
  263. endoreg_db/models/other/distribution.py +215 -0
  264. endoreg_db/models/other/material.py +16 -0
  265. endoreg_db/models/other/resource.py +18 -0
  266. endoreg_db/models/other/transport_route.py +21 -0
  267. endoreg_db/models/other/waste.py +20 -0
  268. endoreg_db/models/patient_examination/__init__.py +35 -35
  269. endoreg_db/models/permissions/__init__.py +44 -44
  270. endoreg_db/models/persons/__init__.py +7 -6
  271. endoreg_db/models/persons/examiner/__init__.py +1 -1
  272. endoreg_db/models/persons/examiner/examiner.py +15 -15
  273. endoreg_db/models/persons/examiner/examiner_type.py +1 -1
  274. endoreg_db/models/persons/first_name.py +17 -17
  275. endoreg_db/models/persons/gender.py +22 -0
  276. endoreg_db/models/persons/last_name.py +19 -19
  277. endoreg_db/models/persons/patient/__init__.py +8 -0
  278. endoreg_db/models/persons/patient/case/__init__.py +0 -0
  279. endoreg_db/models/persons/patient/case/case.py +30 -0
  280. endoreg_db/models/persons/patient/patient.py +216 -0
  281. endoreg_db/models/persons/patient/patient_disease.py +16 -0
  282. endoreg_db/models/persons/patient/patient_event.py +22 -0
  283. endoreg_db/models/persons/patient/patient_lab_sample.py +106 -0
  284. endoreg_db/models/persons/patient/patient_lab_value.py +176 -0
  285. endoreg_db/models/persons/patient/patient_medication.py +44 -0
  286. endoreg_db/models/persons/patient/patient_medication_schedule.py +28 -0
  287. endoreg_db/models/persons/person.py +31 -34
  288. endoreg_db/models/persons/portal_user_information.py +27 -29
  289. endoreg_db/models/prediction/__init__.py +1 -1
  290. endoreg_db/models/prediction/image_classification.py +37 -37
  291. endoreg_db/models/prediction/video_prediction_meta.py +244 -244
  292. endoreg_db/models/product/__init__.py +5 -0
  293. endoreg_db/models/product/product.py +97 -0
  294. endoreg_db/models/product/product_group.py +19 -0
  295. endoreg_db/models/product/product_material.py +24 -0
  296. endoreg_db/models/product/product_weight.py +26 -0
  297. endoreg_db/models/product/reference_product.py +99 -0
  298. endoreg_db/models/questionnaires/__init__.py +114 -114
  299. endoreg_db/models/quiz/__init__.py +2 -0
  300. endoreg_db/models/quiz/quiz_answer.py +41 -0
  301. endoreg_db/models/quiz/quiz_question.py +54 -0
  302. endoreg_db/models/report_reader/__init__.py +1 -1
  303. endoreg_db/models/report_reader/report_reader_config.py +53 -53
  304. endoreg_db/models/report_reader/report_reader_flag.py +19 -19
  305. endoreg_db/models/rules/__init__.py +5 -0
  306. endoreg_db/models/rules/rule.py +24 -0
  307. endoreg_db/models/rules/rule_applicator.py +224 -0
  308. endoreg_db/models/rules/rule_attribute_dtype.py +19 -0
  309. endoreg_db/models/rules/rule_type.py +22 -0
  310. endoreg_db/models/rules/ruleset.py +19 -0
  311. endoreg_db/models/unit.py +21 -19
  312. endoreg_db/queries/__init__.py +4 -4
  313. endoreg_db/queries/annotations/__init__.py +2 -2
  314. endoreg_db/queries/annotations/legacy.py +159 -159
  315. endoreg_db/queries/get/__init__.py +5 -5
  316. endoreg_db/queries/get/center.py +42 -42
  317. endoreg_db/queries/get/model.py +13 -13
  318. endoreg_db/queries/get/patient.py +14 -14
  319. endoreg_db/queries/get/patient_examination.py +20 -20
  320. endoreg_db/queries/get/report_file.py +33 -33
  321. endoreg_db/queries/get/video.py +31 -31
  322. endoreg_db/serializers/__init__.py +9 -9
  323. endoreg_db/serializers/ai_model.py +18 -18
  324. endoreg_db/serializers/annotation.py +17 -17
  325. endoreg_db/serializers/center.py +11 -11
  326. endoreg_db/serializers/examination.py +32 -32
  327. endoreg_db/serializers/frame.py +13 -13
  328. endoreg_db/serializers/hardware.py +20 -20
  329. endoreg_db/serializers/label.py +22 -22
  330. endoreg_db/serializers/patient.py +10 -10
  331. endoreg_db/serializers/prediction.py +15 -15
  332. endoreg_db/serializers/report_file.py +7 -7
  333. endoreg_db/serializers/video.py +27 -27
  334. endoreg_db/tests.py +3 -3
  335. endoreg_db/utils/cropping.py +28 -28
  336. endoreg_db/utils/dataloader.py +92 -185
  337. endoreg_db/utils/file_operations.py +30 -30
  338. endoreg_db/utils/hashs.py +33 -33
  339. endoreg_db/utils/legacy_ocr.py +201 -201
  340. endoreg_db/utils/ocr.py +197 -197
  341. endoreg_db/utils/uuid.py +4 -4
  342. endoreg_db/utils/video_metadata.py +87 -87
  343. endoreg_db/views.py +3 -3
  344. {endoreg_db-0.3.4.dist-info → endoreg_db-0.3.6.dist-info}/LICENSE +674 -674
  345. {endoreg_db-0.3.4.dist-info → endoreg_db-0.3.6.dist-info}/METADATA +2 -2
  346. endoreg_db-0.3.6.dist-info/RECORD +357 -0
  347. {endoreg_db-0.3.4.dist-info → endoreg_db-0.3.6.dist-info}/WHEEL +1 -1
  348. endoreg_db/models/persons/patient.py +0 -58
  349. endoreg_db/models.py +0 -3
  350. endoreg_db-0.3.4.dist-info/RECORD +0 -185
endoreg_db/utils/ocr.py CHANGED
@@ -1,197 +1,197 @@
1
- import pytesseract
2
- from PIL import Image, ImageOps, ImageFilter
3
- import os
4
- from collections import Counter
5
- from tempfile import TemporaryDirectory
6
- import re
7
- from datetime import datetime
8
- from typing import Dict, List
9
- from icecream import ic
10
- import numpy as np
11
- from endoreg_db.utils.cropping import crop_and_insert
12
-
13
-
14
-
15
- N_FRAMES_MEAN_OCR = 2
16
-
17
- # Helper function to process date strings
18
- def process_date_text(date_text):
19
- """
20
- Processes a string of text that represents a date and returns a datetime.date object.
21
-
22
- Args:
23
- date_text (str): A string of text that represents a date.
24
-
25
- Returns:
26
- datetime.date: A datetime.date object representing the parsed date, or None if the text cannot be parsed.
27
- """
28
- try:
29
- # Remove any non-digit characters
30
- date_text_clean = re.sub(r'\D', '', date_text)
31
- # Reformat to 'ddmmyyyy' if necessary
32
- if len(date_text_clean) == 8:
33
- return datetime.strptime(date_text_clean, "%d%m%Y").date()
34
- elif len(date_text_clean) == 14:
35
- return datetime.strptime(date_text_clean, "%d%m%Y%H%M%S").date()
36
- except ValueError:
37
- # Return None if the text cannot be parsed into a date
38
- # set date to 1/1/1900
39
- return datetime.strptime("01011900", "%d%m%Y").date()
40
-
41
- # Helper function to process patient names
42
- def process_name_text(name_text):
43
- """
44
- Remove all numbers, punctuation, and whitespace from a string of text and return the result.
45
- """
46
- name = re.sub(r'[0-9!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~\s]+', '', name_text).strip()
47
- # capitalize first letter of each word
48
- name = ' '.join([word.capitalize() for word in name.split()])
49
- return name
50
-
51
-
52
- # Helper function to process endoscope type text
53
- def process_general_text(endoscope_text):
54
- """
55
- This function takes in a string of text from an endoscope and returns a cleaned version of the text.
56
- """
57
- return ' '.join(endoscope_text.split())
58
-
59
- def roi_values_valid(roi):
60
- """
61
- Check if all values in an ROI dictionary are valid (>=0).
62
- """
63
- return all([value >= 0 for value in roi.values()])
64
-
65
- # Function to extract text from ROIs
66
- def extract_text_from_rois(image_path, processor):
67
- """
68
- Extracts text from regions of interest (ROIs) in an image using OCR.
69
-
70
- Args:
71
- image_path (str): The path to the image file.
72
- processor (EndoscopyProcessor): An instance of the EndoscopyProcessor class.
73
-
74
- Returns:
75
- dict: A dictionary containing the extracted text for each ROI.
76
- """
77
- # Read the image using Pillow
78
- image = Image.open(image_path)
79
- image_dimensions = image.size # (width, height)
80
-
81
- ####### Adjust Image #######
82
- # Convert to grayscale
83
- gray = image.convert('L')
84
-
85
- # Invert colors for white text on black background
86
- inverted = ImageOps.invert(gray)
87
-
88
- # Initialize the dictionary to hold the extracted text
89
- extracted_texts = {}
90
-
91
- # Define your ROIs and their corresponding post-processing functions in tuples
92
- rois_with_postprocessing = [
93
- ('examination_date', processor.get_roi_examination_date, process_date_text),
94
- ("patient_first_name", processor.get_roi_patient_first_name, process_name_text),
95
- ('patient_last_name', processor.get_roi_patient_last_name, process_name_text),
96
- ('patient_dob', processor.get_roi_patient_dob, process_date_text),
97
- ('endoscope_type', processor.get_roi_endoscope_type, process_general_text),
98
- ('endoscope_sn', processor.get_roi_endoscopy_sn, process_general_text),
99
- ]
100
-
101
- # Extract and post-process text for each ROI
102
- for roi_name, roi_function, post_process in rois_with_postprocessing:
103
- # Get the ROI dictionary
104
- roi = roi_function()
105
-
106
- # Check if the ROI has values
107
-
108
- if roi_values_valid(roi):
109
- x, y, w, h = roi['x'], roi['y'], roi['width'], roi['height']
110
-
111
- # Get white image with original shape and just the roi remaining
112
- roi_image = crop_and_insert(inverted, x,y,h,w)
113
-
114
- # OCR configuration: Recognize white text on black background without corrections
115
- config = '--psm 10 -c tessedit_char_whitelist=0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-üöäÜÖÄß'
116
-
117
- # Use pytesseract to do OCR on the preprocessed ROI
118
- text = pytesseract.image_to_string(roi_image, config=config).strip()
119
-
120
- # Post-process extracted text
121
- processed_text = post_process(text)
122
-
123
- extracted_texts[roi_name] = processed_text
124
-
125
- else:
126
- ic(roi_name)
127
- ic(roi)
128
- ic("No values for this ROI")
129
-
130
- return extracted_texts
131
-
132
- def get_most_frequent_values(rois_texts: Dict[str, List[str]]) -> Dict[str, str]:
133
- """
134
- Given a dictionary of ROIs and their corresponding texts, returns a dictionary of the most frequent text for each ROI.
135
-
136
- Args:
137
- rois_texts: A dictionary where the keys are the names of the ROIs and the values are lists of texts.
138
-
139
- Returns:
140
- A dictionary where the keys are the names of the ROIs and the values are the most frequent text for each ROI.
141
- """
142
- most_frequent = {}
143
- for key in rois_texts.keys():
144
- counter = Counter([text for text in rois_texts[key] if text])
145
- ic(key)
146
- ic(counter)
147
- most_frequent[key], _ = counter.most_common(1)[0] if counter else (None, None)
148
- return most_frequent
149
-
150
- def process_video(video_path, processor):
151
- """
152
- Processes a video file by extracting text from regions of interest (ROIs) in each frame.
153
-
154
- Args:
155
- video_path (str): The path to the video file to process.
156
- processor (OCRProcessor): An instance of the OCRProcessor class that defines the ROIs to extract text from.
157
-
158
- Returns:
159
- dict: A dictionary containing the most frequent text values extracted from each ROI.
160
- """
161
- # Create a temporary directory to store frames
162
- with TemporaryDirectory() as temp_dir:
163
- ic(temp_dir)
164
- # Capture the video
165
- video = cv2.VideoCapture(video_path)
166
- success, frame_number = True, 0
167
- rois_texts = {roi_name: [] for roi_name in processor.get_rois().keys()}
168
- frames_for_mean_extraction = 0
169
-
170
- while success:
171
- success, frame = video.read()
172
-
173
- # Check if this is the 200th frame
174
- if frame_number % 1000 == 0 and success:
175
- frame_path = os.path.join(temp_dir, f"frame_{frame_number}.jpg")
176
- cv2.imwrite(frame_path, frame) # Save the frame as a JPEG file
177
- # cv2.imwrite(f"_tmp/frame_{frame_number}.jpg", frame)
178
-
179
- # Extract text from ROIs
180
- extracted_texts = extract_text_from_rois(frame_path, processor)
181
- ic(extracted_texts)
182
-
183
- # Store the extracted text from each ROI
184
- for key, text in extracted_texts.items():
185
- rois_texts[key].append(text)
186
- frames_for_mean_extraction += 1
187
-
188
- frame_number += 1
189
-
190
- if frames_for_mean_extraction >= N_FRAMES_MEAN_OCR: break
191
-
192
- # Release the video capture object
193
- video.release()
194
-
195
- # Get the most frequent values for each ROI
196
- return get_most_frequent_values(rois_texts)
197
-
1
+ import pytesseract
2
+ from PIL import Image, ImageOps, ImageFilter
3
+ import os
4
+ from collections import Counter
5
+ from tempfile import TemporaryDirectory
6
+ import re
7
+ from datetime import datetime
8
+ from typing import Dict, List
9
+ from icecream import ic
10
+ import numpy as np
11
+ from endoreg_db.utils.cropping import crop_and_insert
12
+
13
+
14
+
15
+ N_FRAMES_MEAN_OCR = 2
16
+
17
+ # Helper function to process date strings
18
+ def process_date_text(date_text):
19
+ """
20
+ Processes a string of text that represents a date and returns a datetime.date object.
21
+
22
+ Args:
23
+ date_text (str): A string of text that represents a date.
24
+
25
+ Returns:
26
+ datetime.date: A datetime.date object representing the parsed date, or None if the text cannot be parsed.
27
+ """
28
+ try:
29
+ # Remove any non-digit characters
30
+ date_text_clean = re.sub(r'\D', '', date_text)
31
+ # Reformat to 'ddmmyyyy' if necessary
32
+ if len(date_text_clean) == 8:
33
+ return datetime.strptime(date_text_clean, "%d%m%Y").date()
34
+ elif len(date_text_clean) == 14:
35
+ return datetime.strptime(date_text_clean, "%d%m%Y%H%M%S").date()
36
+ except ValueError:
37
+ # Return None if the text cannot be parsed into a date
38
+ # set date to 1/1/1900
39
+ return datetime.strptime("01011900", "%d%m%Y").date()
40
+
41
+ # Helper function to process patient names
42
+ def process_name_text(name_text):
43
+ """
44
+ Remove all numbers, punctuation, and whitespace from a string of text and return the result.
45
+ """
46
+ name = re.sub(r'[0-9!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~\s]+', '', name_text).strip()
47
+ # capitalize first letter of each word
48
+ name = ' '.join([word.capitalize() for word in name.split()])
49
+ return name
50
+
51
+
52
+ # Helper function to process endoscope type text
53
+ def process_general_text(endoscope_text):
54
+ """
55
+ This function takes in a string of text from an endoscope and returns a cleaned version of the text.
56
+ """
57
+ return ' '.join(endoscope_text.split())
58
+
59
+ def roi_values_valid(roi):
60
+ """
61
+ Check if all values in an ROI dictionary are valid (>=0).
62
+ """
63
+ return all([value >= 0 for value in roi.values()])
64
+
65
+ # Function to extract text from ROIs
66
+ def extract_text_from_rois(image_path, processor):
67
+ """
68
+ Extracts text from regions of interest (ROIs) in an image using OCR.
69
+
70
+ Args:
71
+ image_path (str): The path to the image file.
72
+ processor (EndoscopyProcessor): An instance of the EndoscopyProcessor class.
73
+
74
+ Returns:
75
+ dict: A dictionary containing the extracted text for each ROI.
76
+ """
77
+ # Read the image using Pillow
78
+ image = Image.open(image_path)
79
+ image_dimensions = image.size # (width, height)
80
+
81
+ ####### Adjust Image #######
82
+ # Convert to grayscale
83
+ gray = image.convert('L')
84
+
85
+ # Invert colors for white text on black background
86
+ inverted = ImageOps.invert(gray)
87
+
88
+ # Initialize the dictionary to hold the extracted text
89
+ extracted_texts = {}
90
+
91
+ # Define your ROIs and their corresponding post-processing functions in tuples
92
+ rois_with_postprocessing = [
93
+ ('examination_date', processor.get_roi_examination_date, process_date_text),
94
+ ("patient_first_name", processor.get_roi_patient_first_name, process_name_text),
95
+ ('patient_last_name', processor.get_roi_patient_last_name, process_name_text),
96
+ ('patient_dob', processor.get_roi_patient_dob, process_date_text),
97
+ ('endoscope_type', processor.get_roi_endoscope_type, process_general_text),
98
+ ('endoscope_sn', processor.get_roi_endoscopy_sn, process_general_text),
99
+ ]
100
+
101
+ # Extract and post-process text for each ROI
102
+ for roi_name, roi_function, post_process in rois_with_postprocessing:
103
+ # Get the ROI dictionary
104
+ roi = roi_function()
105
+
106
+ # Check if the ROI has values
107
+
108
+ if roi_values_valid(roi):
109
+ x, y, w, h = roi['x'], roi['y'], roi['width'], roi['height']
110
+
111
+ # Get white image with original shape and just the roi remaining
112
+ roi_image = crop_and_insert(inverted, x,y,h,w)
113
+
114
+ # OCR configuration: Recognize white text on black background without corrections
115
+ config = '--psm 10 -c tessedit_char_whitelist=0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-üöäÜÖÄß'
116
+
117
+ # Use pytesseract to do OCR on the preprocessed ROI
118
+ text = pytesseract.image_to_string(roi_image, config=config).strip()
119
+
120
+ # Post-process extracted text
121
+ processed_text = post_process(text)
122
+
123
+ extracted_texts[roi_name] = processed_text
124
+
125
+ else:
126
+ ic(roi_name)
127
+ ic(roi)
128
+ ic("No values for this ROI")
129
+
130
+ return extracted_texts
131
+
132
+ def get_most_frequent_values(rois_texts: Dict[str, List[str]]) -> Dict[str, str]:
133
+ """
134
+ Given a dictionary of ROIs and their corresponding texts, returns a dictionary of the most frequent text for each ROI.
135
+
136
+ Args:
137
+ rois_texts: A dictionary where the keys are the names of the ROIs and the values are lists of texts.
138
+
139
+ Returns:
140
+ A dictionary where the keys are the names of the ROIs and the values are the most frequent text for each ROI.
141
+ """
142
+ most_frequent = {}
143
+ for key in rois_texts.keys():
144
+ counter = Counter([text for text in rois_texts[key] if text])
145
+ ic(key)
146
+ ic(counter)
147
+ most_frequent[key], _ = counter.most_common(1)[0] if counter else (None, None)
148
+ return most_frequent
149
+
150
+ def process_video(video_path, processor):
151
+ """
152
+ Processes a video file by extracting text from regions of interest (ROIs) in each frame.
153
+
154
+ Args:
155
+ video_path (str): The path to the video file to process.
156
+ processor (OCRProcessor): An instance of the OCRProcessor class that defines the ROIs to extract text from.
157
+
158
+ Returns:
159
+ dict: A dictionary containing the most frequent text values extracted from each ROI.
160
+ """
161
+ # Create a temporary directory to store frames
162
+ with TemporaryDirectory() as temp_dir:
163
+ ic(temp_dir)
164
+ # Capture the video
165
+ video = cv2.VideoCapture(video_path)
166
+ success, frame_number = True, 0
167
+ rois_texts = {roi_name: [] for roi_name in processor.get_rois().keys()}
168
+ frames_for_mean_extraction = 0
169
+
170
+ while success:
171
+ success, frame = video.read()
172
+
173
+ # Check if this is the 200th frame
174
+ if frame_number % 1000 == 0 and success:
175
+ frame_path = os.path.join(temp_dir, f"frame_{frame_number}.jpg")
176
+ cv2.imwrite(frame_path, frame) # Save the frame as a JPEG file
177
+ # cv2.imwrite(f"_tmp/frame_{frame_number}.jpg", frame)
178
+
179
+ # Extract text from ROIs
180
+ extracted_texts = extract_text_from_rois(frame_path, processor)
181
+ ic(extracted_texts)
182
+
183
+ # Store the extracted text from each ROI
184
+ for key, text in extracted_texts.items():
185
+ rois_texts[key].append(text)
186
+ frames_for_mean_extraction += 1
187
+
188
+ frame_number += 1
189
+
190
+ if frames_for_mean_extraction >= N_FRAMES_MEAN_OCR: break
191
+
192
+ # Release the video capture object
193
+ video.release()
194
+
195
+ # Get the most frequent values for each ROI
196
+ return get_most_frequent_values(rois_texts)
197
+
endoreg_db/utils/uuid.py CHANGED
@@ -1,4 +1,4 @@
1
- import uuid
2
-
3
- def get_uuid():
4
- return uuid.uuid4()
1
+ import uuid
2
+
3
+ def get_uuid():
4
+ return uuid.uuid4()
@@ -1,87 +1,87 @@
1
- # import cv2
2
- from pathlib import Path
3
- import datetime
4
-
5
- def _extract_metadata_from_filename(filepath:Path, time_format = None): # deprecated
6
- """
7
- Extracts metadata from a video filename.
8
-
9
- Args:
10
- filepath (Path): The path to the video file.
11
- time_format (str, optional): The format of the date in the filename. Defaults to None.
12
-
13
- Returns:
14
- dict: A dictionary containing the extracted metadata.
15
-
16
- Example return value:
17
- {
18
- 'examination_date': '2021-03-03',
19
- 'patient_last_name': 'Doe',
20
- 'patient_first_name': 'John',
21
- 'patient_dob': '1990-01-01'
22
- }
23
- """
24
- # get filename without suffix
25
- filename = filepath.stem
26
-
27
- if not time_format:
28
- time_format = "%d.%m.%Y"
29
-
30
- _info = [_.strip() for _ in filename.split("_")]
31
-
32
- if len(_info) == 4:
33
- examination_date, last_name, first_name, birthdate = _info
34
-
35
- else:
36
- examination_date, last_name, first_name, birthdate = None, None, None, None
37
-
38
- metadata = {}
39
- metadata['examination_date'] = examination_date
40
- metadata['patient_last_name'] = last_name
41
- metadata['patient_first_name'] = first_name
42
- metadata['patient_dob'] = birthdate
43
-
44
- try:
45
- metadata['examination_date'] = datetime.datetime.strptime(examination_date, time_format).date()
46
- metadata['examination_date'] = metadata['examination_date'].strftime("%Y-%m-%d")
47
- except:
48
- metadata['examination_date'] = None
49
-
50
- try:
51
- metadata['patient_dob'] = datetime.datetime.strptime(birthdate, time_format).date()
52
- metadata['patient_dob'] = metadata['patient_dob'].strftime("%Y-%m-%d")
53
- except:
54
- metadata['patient_dob'] = None
55
-
56
- return metadata
57
-
58
- def _get_video_metadata(file_path): # Deprecated
59
- """
60
- Returns the framerate, dimensions, and duration of a video file.
61
-
62
- Parameters:
63
- file_path (str): The path to the video file.
64
-
65
- Returns:
66
- tuple: A tuple containing the framerate (float), dimensions (tuple of ints), and duration (float) of the video.
67
- """
68
- # Open the video file
69
- video = cv2.VideoCapture(file_path)
70
-
71
- # Get the video framerate
72
- fps = video.get(cv2.CAP_PROP_FPS)
73
-
74
- # Get the video dimensions
75
- width = int(video.get(cv2.CAP_PROP_FRAME_WIDTH))
76
- height = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT))
77
- dimensions = (width, height)
78
-
79
- # Get the video duration
80
- frame_count = int(video.get(cv2.CAP_PROP_FRAME_COUNT))
81
- duration = frame_count / fps
82
-
83
- # Release the video file
84
- video.release()
85
-
86
- # Return the metadata
87
- return fps, dimensions, duration
1
+ # import cv2
2
+ from pathlib import Path
3
+ import datetime
4
+
5
+ def _extract_metadata_from_filename(filepath:Path, time_format = None): # deprecated
6
+ """
7
+ Extracts metadata from a video filename.
8
+
9
+ Args:
10
+ filepath (Path): The path to the video file.
11
+ time_format (str, optional): The format of the date in the filename. Defaults to None.
12
+
13
+ Returns:
14
+ dict: A dictionary containing the extracted metadata.
15
+
16
+ Example return value:
17
+ {
18
+ 'examination_date': '2021-03-03',
19
+ 'patient_last_name': 'Doe',
20
+ 'patient_first_name': 'John',
21
+ 'patient_dob': '1990-01-01'
22
+ }
23
+ """
24
+ # get filename without suffix
25
+ filename = filepath.stem
26
+
27
+ if not time_format:
28
+ time_format = "%d.%m.%Y"
29
+
30
+ _info = [_.strip() for _ in filename.split("_")]
31
+
32
+ if len(_info) == 4:
33
+ examination_date, last_name, first_name, birthdate = _info
34
+
35
+ else:
36
+ examination_date, last_name, first_name, birthdate = None, None, None, None
37
+
38
+ metadata = {}
39
+ metadata['examination_date'] = examination_date
40
+ metadata['patient_last_name'] = last_name
41
+ metadata['patient_first_name'] = first_name
42
+ metadata['patient_dob'] = birthdate
43
+
44
+ try:
45
+ metadata['examination_date'] = datetime.datetime.strptime(examination_date, time_format).date()
46
+ metadata['examination_date'] = metadata['examination_date'].strftime("%Y-%m-%d")
47
+ except:
48
+ metadata['examination_date'] = None
49
+
50
+ try:
51
+ metadata['patient_dob'] = datetime.datetime.strptime(birthdate, time_format).date()
52
+ metadata['patient_dob'] = metadata['patient_dob'].strftime("%Y-%m-%d")
53
+ except:
54
+ metadata['patient_dob'] = None
55
+
56
+ return metadata
57
+
58
+ def _get_video_metadata(file_path): # Deprecated
59
+ """
60
+ Returns the framerate, dimensions, and duration of a video file.
61
+
62
+ Parameters:
63
+ file_path (str): The path to the video file.
64
+
65
+ Returns:
66
+ tuple: A tuple containing the framerate (float), dimensions (tuple of ints), and duration (float) of the video.
67
+ """
68
+ # Open the video file
69
+ video = cv2.VideoCapture(file_path)
70
+
71
+ # Get the video framerate
72
+ fps = video.get(cv2.CAP_PROP_FPS)
73
+
74
+ # Get the video dimensions
75
+ width = int(video.get(cv2.CAP_PROP_FRAME_WIDTH))
76
+ height = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT))
77
+ dimensions = (width, height)
78
+
79
+ # Get the video duration
80
+ frame_count = int(video.get(cv2.CAP_PROP_FRAME_COUNT))
81
+ duration = frame_count / fps
82
+
83
+ # Release the video file
84
+ video.release()
85
+
86
+ # Return the metadata
87
+ return fps, dimensions, duration
endoreg_db/views.py CHANGED
@@ -1,3 +1,3 @@
1
- from django.shortcuts import render
2
-
3
- # Create your views here.
1
+ from django.shortcuts import render
2
+
3
+ # Create your views here.