From 973e505e10e2d80aed9b46827674f771eca24a21 Mon Sep 17 00:00:00 2001 From: Daniel Elton Date: Wed, 20 Oct 2021 11:56:06 -0400 Subject: [PATCH 1/3] add needed imports for the structured report example. Add example of saving 3D ct and seg that are in NumPy arrays --- docs/usage.rst | 58 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/docs/usage.rst b/docs/usage.rst index edfd3efb..5da40db6 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -189,6 +189,8 @@ image: from pydicom.filereader import dcmread from pydicom.sr.codedict import codes from pydicom.uid import generate_uid + from highdicom.sr.content import FindingSite + from highdicom.sr.templates import Measurement, TrackingIdentifier # Path to single-frame CT image instance stored as PS3.10 file image_file = Path('/path/to/image/file') @@ -366,7 +368,7 @@ can capture more detail about how the derived information was obtained and what it represents. In this example, we use a secondary capture to store an image containing a -labelled bounding box region drawn over a CT image. +labeled bounding box region drawn over a CT image. .. code-block:: python @@ -425,7 +427,7 @@ labelled bounding box region drawn over a CT image. patient_orientation=['L', 'P'] # Create the secondary capture image. By using the `from_ref_dataset` - # constructor, all the patient and study information willl be copied from the + # constructor, all the patient and study information will be copied from the # original image dataset sc_image = hd.sc.SCImage.from_ref_dataset( ref_dataset=image_dataset, @@ -446,6 +448,58 @@ labelled bounding box region drawn over a CT image. # Save the file sc_image.save_as('sc_output.dcm') +To save a 3D image, simply loop over the 2D slices. Here is an example for a CT +scan that is in a NumPy array called "ct_to_save" where we do not have the original +DICOM files on hand. We want to overlay a segmentation that is stored in a NumPy array +called "seg_out". + +.. code-block:: python + import highdicom as hd + import numpy as np + import os + + sz = ct_to_save.shape[2] + SID = hd.UID() + SIUID = hd.UID() + + for iz in range(sz): + this_slice = ct_to_save[:,:,iz] + + # Window the image to a soft tissue window (center 40, width 400) + # and rescale to the range 0 to 255 + lower = -160 + upper = 240 + windowed_image = np.clip(this_slice, lower, upper) + windowed_image = (windowed_image - lower) * 255 / (upper - lower) + + # Create RGB channels + pixel_array = np.tile(windowed_image[:, :, np.newaxis], [1, 1, 3]) + + alpha = 0.1 #transparency level + + pixel_array[:,:,0] = 255*(1-alpha)*seg_out[:,:,iz] + alpha*pixel_array[:,:,0] + pixel_array[:,:,1] = alpha*pixel_array[:,:,1] + pixel_array[:,:,2] = alpha*pixel_array[:,:,2] + + patient_orientation=['L','P'] + + # Create the secondary capture image. + sc_image = hd.sc.SCImage( + pixel_array=pixel_array.astype(np.uint8), + photometric_interpretation=hd.PhotometricInterpretationValues.RGB, + bits_allocated=8, + coordinate_system=hd.CoordinateSystemNames.PATIENT, + study_instance_uid=SIUID, + series_instance_uid=SID, + sop_instance_uid=hd.UID(), + series_number=100, + instance_number=iz, + manufacturer='Manufacturer', + pixel_spacing=px, + patient_orientation=patient_orientation, + ) + + sc_image.save_as(os.path.join("output", 'sc_output_'+str(iz)+'.dcm')) .. .. _creation-legacy: From e97276175e219a9474b052ec88d5113e40661cbe Mon Sep 17 00:00:00 2001 From: Daniel Elton Date: Wed, 20 Oct 2021 14:07:50 -0400 Subject: [PATCH 2/3] fix .rst to get code block to render --- docs/usage.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/usage.rst b/docs/usage.rst index 5da40db6..2a206fd8 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -454,6 +454,7 @@ DICOM files on hand. We want to overlay a segmentation that is stored in a NumPy called "seg_out". .. code-block:: python + import highdicom as hd import numpy as np import os From 08e43eaec54d9ca58c4739926f50e3e12da399c1 Mon Sep 17 00:00:00 2001 From: Daniel Elton Date: Thu, 21 Oct 2021 18:36:40 -0400 Subject: [PATCH 3/3] incorporate Chris's edits / fixes --- docs/usage.rst | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/docs/usage.rst b/docs/usage.rst index 2a206fd8..02a279b1 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -448,10 +448,12 @@ labeled bounding box region drawn over a CT image. # Save the file sc_image.save_as('sc_output.dcm') -To save a 3D image, simply loop over the 2D slices. Here is an example for a CT -scan that is in a NumPy array called "ct_to_save" where we do not have the original -DICOM files on hand. We want to overlay a segmentation that is stored in a NumPy array -called "seg_out". + +To save a 3D image as a series of output slices, simply loop over the 2D +slices and ensure that the individual output instances share a common series +instance UID. Here is an example for a CT scan that is in a NumPy array called +"ct_to_save" where we do not have the original DICOM files on hand. We want to +overlay a segmentation that is stored in a NumPy array called "seg_out". .. code-block:: python @@ -459,12 +461,13 @@ called "seg_out". import numpy as np import os + pixel_spacing = 1 sz = ct_to_save.shape[2] - SID = hd.UID() - SIUID = hd.UID() + series_instance_uid = hd.UID() + study_instance_uid = hd.UID() for iz in range(sz): - this_slice = ct_to_save[:,:,iz] + this_slice = ct_to_save[:, :, iz] # Window the image to a soft tissue window (center 40, width 400) # and rescale to the range 0 to 255 @@ -476,31 +479,32 @@ called "seg_out". # Create RGB channels pixel_array = np.tile(windowed_image[:, :, np.newaxis], [1, 1, 3]) - alpha = 0.1 #transparency level + # transparency level + alpha = 0.1 - pixel_array[:,:,0] = 255*(1-alpha)*seg_out[:,:,iz] + alpha*pixel_array[:,:,0] - pixel_array[:,:,1] = alpha*pixel_array[:,:,1] - pixel_array[:,:,2] = alpha*pixel_array[:,:,2] + pixel_array[:, :, 0] = 255 * (1 - alpha) * seg_out[:, :, iz] + alpha * pixel_array[:, :, 0] + pixel_array[:, :, 1] = alpha * pixel_array[:, :, 1] + pixel_array[:, :, 2] = alpha * pixel_array[:, :, 2] - patient_orientation=['L','P'] + patient_orientation = ['L', 'P'] - # Create the secondary capture image. + # Create the secondary capture image sc_image = hd.sc.SCImage( pixel_array=pixel_array.astype(np.uint8), photometric_interpretation=hd.PhotometricInterpretationValues.RGB, bits_allocated=8, coordinate_system=hd.CoordinateSystemNames.PATIENT, - study_instance_uid=SIUID, - series_instance_uid=SID, + study_instance_uid=study_instance_uid, + series_instance_uid=series_instance_uid, sop_instance_uid=hd.UID(), series_number=100, - instance_number=iz, + instance_number=iz + 1, manufacturer='Manufacturer', - pixel_spacing=px, + pixel_spacing=pixel_spacing, patient_orientation=patient_orientation, - ) + ) - sc_image.save_as(os.path.join("output", 'sc_output_'+str(iz)+'.dcm')) + sc_image.save_as(os.path.join("output", 'sc_output_' + str(iz) + '.dcm')) .. .. _creation-legacy: