|
13 | 13 |
|
14 | 14 | from livertumor_seg_operator import LiverTumorSegOperator |
15 | 15 |
|
| 16 | +# Required for setting SegmentDescription attributes. Direct import as this is not part of App SDK package. |
| 17 | +from pydicom.sr.codedict import codes |
| 18 | + |
16 | 19 | from monai.deploy.core import Application, resource |
17 | 20 | from monai.deploy.operators.dicom_data_loader_operator import DICOMDataLoaderOperator |
18 | | -from monai.deploy.operators.dicom_seg_writer_operator import DICOMSegmentationWriterOperator |
| 21 | +from monai.deploy.operators.dicom_seg_writer_operator import DICOMSegmentationWriterOperator, SegmentDescription |
19 | 22 | from monai.deploy.operators.dicom_series_selector_operator import DICOMSeriesSelectorOperator |
20 | 23 | from monai.deploy.operators.dicom_series_to_volume_operator import DICOMSeriesToVolumeOperator |
21 | 24 | from monai.deploy.operators.publisher_operator import PublisherOperator |
@@ -46,33 +49,57 @@ def compose(self): |
46 | 49 | series_selector_op = DICOMSeriesSelectorOperator() |
47 | 50 | series_to_vol_op = DICOMSeriesToVolumeOperator() |
48 | 51 | # Model specific inference operator, supporting MONAI transforms. |
49 | | - unetr_seg_op = LiverTumorSegOperator() |
| 52 | + liver_tumor_seg_op = LiverTumorSegOperator() |
50 | 53 |
|
51 | 54 | # Create the publisher operator |
52 | 55 | publisher_op = PublisherOperator() |
53 | 56 |
|
54 | | - # Creates DICOM Seg writer with segment label name in a string list |
55 | | - dicom_seg_writer = DICOMSegmentationWriterOperator( |
56 | | - seg_labels=[ |
57 | | - "Liver", |
58 | | - "Tumor", |
59 | | - ] |
60 | | - ) |
| 57 | + # Create DICOM Seg writer providing the required segment description for each segment with |
| 58 | + # the actual algorithm and the pertinent organ/tissue. |
| 59 | + # The segment_label, algorithm_name, and algorithm_version are limited to 64 chars. |
| 60 | + # https://dicom.nema.org/medical/dicom/current/output/chtml/part05/sect_6.2.html |
| 61 | + # User can Look up SNOMED CT codes at, e.g. |
| 62 | + # https://bioportal.bioontology.org/ontologies/SNOMEDCT |
| 63 | + |
| 64 | + _algorithm_name = "3D segmentation of the liver and tumor from CT image" |
| 65 | + _algorithm_family = codes.DCM.ArtificialIntelligence |
| 66 | + _algorithm_version = "0.1.0" |
| 67 | + |
| 68 | + segment_descriptions = [ |
| 69 | + SegmentDescription( |
| 70 | + segment_label="Liver", |
| 71 | + segmented_property_category=codes.SCT.Organ, |
| 72 | + segmented_property_type=codes.SCT.Liver, |
| 73 | + algorithm_name=_algorithm_name, |
| 74 | + algorithm_family=_algorithm_family, |
| 75 | + algorithm_version=_algorithm_version, |
| 76 | + ), |
| 77 | + SegmentDescription( |
| 78 | + segment_label="Tumor", |
| 79 | + segmented_property_category=codes.SCT.Tumor, |
| 80 | + segmented_property_type=codes.SCT.Tumor, |
| 81 | + algorithm_name=_algorithm_name, |
| 82 | + algorithm_family=_algorithm_family, |
| 83 | + algorithm_version=_algorithm_version, |
| 84 | + ), |
| 85 | + ] |
| 86 | + |
| 87 | + dicom_seg_writer = DICOMSegmentationWriterOperator(segment_descriptions) |
61 | 88 | # Create the processing pipeline, by specifying the source and destination operators, and |
62 | 89 | # ensuring the output from the former matches the input of the latter, in both name and type. |
63 | 90 | self.add_flow(study_loader_op, series_selector_op, {"dicom_study_list": "dicom_study_list"}) |
64 | 91 | self.add_flow( |
65 | 92 | series_selector_op, series_to_vol_op, {"study_selected_series_list": "study_selected_series_list"} |
66 | 93 | ) |
67 | | - self.add_flow(series_to_vol_op, unetr_seg_op, {"image": "image"}) |
| 94 | + self.add_flow(series_to_vol_op, liver_tumor_seg_op, {"image": "image"}) |
68 | 95 | # Add the publishing operator to save the input and seg images for Render Server. |
69 | 96 | # Note the PublisherOperator has temp impl till a proper rendering module is created. |
70 | | - self.add_flow(unetr_seg_op, publisher_op, {"saved_images_folder": "saved_images_folder"}) |
| 97 | + self.add_flow(liver_tumor_seg_op, publisher_op, {"saved_images_folder": "saved_images_folder"}) |
71 | 98 | # Note below the dicom_seg_writer requires two inputs, each coming from a source operator. |
72 | 99 | self.add_flow( |
73 | 100 | series_selector_op, dicom_seg_writer, {"study_selected_series_list": "study_selected_series_list"} |
74 | 101 | ) |
75 | | - self.add_flow(unetr_seg_op, dicom_seg_writer, {"seg_image": "seg_image"}) |
| 102 | + self.add_flow(liver_tumor_seg_op, dicom_seg_writer, {"seg_image": "seg_image"}) |
76 | 103 |
|
77 | 104 | self._logger.debug(f"End {self.compose.__name__}") |
78 | 105 |
|
|
0 commit comments