Skip to content

Commit cb5ad53

Browse files
WillButAgainwill tepe
and
will tepe
authored
Fix DICOMSeriesToVolumeOperator casting bug (#529)
* fix casting, add check Signed-off-by: will tepe <will.tepe@cchmc.org> * code review changes Signed-off-by: will tepe <will.tepe@cchmc.org> * fix fir slope as well --------- Signed-off-by: will tepe <will.tepe@cchmc.org> Co-authored-by: will tepe <will.tepe@cchmc.org>
1 parent 0844f17 commit cb5ad53

File tree

1 file changed

+24
-5
lines changed

1 file changed

+24
-5
lines changed

monai/deploy/operators/dicom_series_to_volume_operator.py

+24-5
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,8 @@ def generate_voxel_data(self, series):
112112
# with the NumPy array returned from the ITK GetArrayViewFromImage on the image
113113
# loaded from the same DICOM series.
114114
vol_data = np.stack([s.get_pixel_array() for s in slices], axis=0)
115-
vol_data = vol_data.astype(np.int16)
115+
if slices[0][0x0028,0x0103].value == 1:
116+
vol_data = vol_data.astype(np.uint16)
116117

117118
# For now we support monochrome image only, for which DICOM Photometric Interpretation
118119
# (0028,0004) has defined terms, MONOCHROME1 and MONOCHROME2, with the former being:
@@ -154,11 +155,29 @@ def generate_voxel_data(self, series):
154155
except KeyError:
155156
slope = 1
156157

158+
159+
# check if vol_data, intercept, and slope can be cast to uint16 without data loss
160+
if np.can_cast(vol_data, np.uint16, casting='safe') and np.can_cast(intercept, np.uint16, casting='safe') and np.can_cast(slope, np.uint16, casting='safe'):
161+
logging.info(f"Casting to uint16")
162+
vol_data = np.array(vol_data, dtype=np.uint16)
163+
intercept = np.uint16(intercept)
164+
slope = np.uint16(slope)
165+
elif np.can_cast(vol_data, np.float32, casting='safe') and np.can_cast(intercept, np.float32, casting='safe') and np.can_cast(slope, np.float32, casting='safe'):
166+
logging.info(f"Casting to float32")
167+
vol_data = np.array(vol_data, dtype=np.float32)
168+
intercept = np.float32(intercept)
169+
slope = np.float32(slope)
170+
elif np.can_cast(vol_data, np.float64, casting='safe') and np.can_cast(intercept, np.float64, casting='safe') and np.can_cast(slope, np.float64, casting='safe'):
171+
logging.info(f"Casting to float64")
172+
vol_data = np.array(vol_data, dtype=np.float64)
173+
intercept = np.float64(intercept)
174+
slope = np.float64(slope)
175+
157176
if slope != 1:
158-
vol_data = slope * vol_data.astype(np.float64)
159-
vol_data = vol_data.astype(np.int16)
160-
vol_data += np.int16(intercept)
161-
return np.array(vol_data, dtype=np.int16)
177+
vol_data = slope * vol_data
178+
179+
vol_data += intercept
180+
return vol_data
162181

163182
def create_volumetric_image(self, vox_data, metadata):
164183
"""Creates an instance of 3D image.

0 commit comments

Comments
 (0)