Skip to content

Commit 2e51a42

Browse files
[pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
1 parent c5759ea commit 2e51a42

2 files changed

Lines changed: 179 additions & 177 deletions

File tree

monailabel/datastore/utils/convert.py

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
try:
2929
import highdicom as hd
30+
3031
HIGHDICOM_AVAILABLE = True
3132
except ImportError:
3233
HIGHDICOM_AVAILABLE = False
@@ -92,29 +93,29 @@ def binary_to_image(reference_image, label, dtype=np.uint8, file_ext=".nii.gz"):
9293

9394
def _extract_label_info(label, label_info):
9495
"""Extract unique labels and model info from label file.
95-
96+
9697
Args:
9798
label: Path to NIfTI label file
9899
label_info: List of dictionaries containing segment information
99-
100+
100101
Returns:
101102
tuple: (unique_labels, model_name) or (None, None) if empty
102103
"""
103104
# Load label file using SimpleITK (consistent with conversion pipeline)
104105
mask = SimpleITK.ReadImage(label)
105106
label_array = SimpleITK.GetArrayFromImage(mask)
106-
107+
107108
# Extract unique non-zero labels
108109
unique_labels = np.unique(label_array).astype(np.int_)
109110
unique_labels = unique_labels[unique_labels != 0]
110-
111+
111112
info = label_info[0] if label_info and 0 < len(label_info) else {}
112113
model_name = info.get("model_name", "AIName")
113-
114+
114115
if not unique_labels.size:
115116
logger.warning("No non-zero labels found in segmentation")
116117
return None, None
117-
118+
118119
return unique_labels, model_name
119120

120121

@@ -137,15 +138,15 @@ def _highdicom_nifti_to_dicom_seg(
137138
# Input validation
138139
if label_info is None:
139140
label_info = []
140-
141+
141142
if not os.path.exists(label):
142143
logger.error(f"Label file not found: {label}")
143144
return ""
144-
145+
145146
if not os.path.exists(series_dir):
146147
logger.error(f"Series directory not found: {series_dir}")
147148
return ""
148-
149+
149150
# Extract label information
150151
unique_labels, model_name = _extract_label_info(label, label_info)
151152
if unique_labels is None:
@@ -229,7 +230,7 @@ def _highdicom_nifti_to_dicom_seg(
229230

230231
# Get consistent timestamp for all DICOM attributes
231232
dt_now = datetime.datetime.now()
232-
233+
233234
# DICOM series number is 4 digits max (0-9999)
234235
MAX_SERIES_NUMBER = 9999
235236
series_number = int(dt_now.strftime("%H%M%S")) % (MAX_SERIES_NUMBER + 1)
@@ -319,15 +320,15 @@ def _itk_nifti_to_dicom_seg(series_dir, label, label_info) -> str:
319320
# Input validation
320321
if label_info is None:
321322
label_info = []
322-
323+
323324
if not os.path.exists(label):
324325
logger.error(f"Label file not found: {label}")
325326
return ""
326-
327+
327328
if not os.path.exists(series_dir):
328329
logger.error(f"Series directory not found: {series_dir}")
329330
return ""
330-
331+
331332
# Extract label information (reuse helper function)
332333
unique_labels, model_name = _extract_label_info(label, label_info)
333334
if unique_labels is None:
@@ -344,7 +345,7 @@ def _itk_nifti_to_dicom_seg(series_dir, label, label_info) -> str:
344345

345346
# Check if custom segmentAttribute is provided
346347
segment_attr = info.get("segmentAttribute")
347-
348+
348349
if segment_attr:
349350
# Use custom attribute as-is
350351
segment_descriptions.append(segment_attr)
@@ -379,12 +380,12 @@ def _itk_nifti_to_dicom_seg(series_dir, label, label_info) -> str:
379380

380381
# Extract metadata from label_info (use first segment's metadata for study-level info)
381382
first_info = label_info[0] if label_info and len(label_info) > 0 else {}
382-
383+
383384
# Get timestamp-based series number (consistent with highdicom implementation)
384385
dt_now = datetime.datetime.now()
385386
MAX_SERIES_NUMBER = 9999
386387
series_number = int(dt_now.strftime("%H%M%S")) % (MAX_SERIES_NUMBER + 1)
387-
388+
388389
# Build ITK template with extracted or sensible default values
389390
template = {
390391
"ContentCreatorName": first_info.get("creator", "MONAI Label"),
@@ -452,7 +453,7 @@ def nifti_to_dicom_seg(
452453

453454
def _dcmqi_nifti_to_dicom_seg(label, series_dir, template) -> str:
454455
"""Convert NIfTI to DICOM SEG using dcmqi's itkimage2segimage command-line tool.
455-
456+
456457
This is a low-level wrapper around the dcmqi itkimage2segimage tool.
457458
Called by _itk_nifti_to_dicom_seg() as the actual conversion implementation.
458459
"""
@@ -524,21 +525,21 @@ def dicom_seg_to_itk_image(label, output_ext=".seg.nrrd"):
524525

525526
# Convert to SimpleITK image
526527
image = SimpleITK.GetImageFromArray(volume.array)
527-
528+
528529
# Convert spacing from highdicom to SimpleITK order
529530
# highdicom: (slice, row, column) for axes (0, 1, 2)
530531
# SimpleITK: (x, y, z) = (column, row, slice)
531532
# Therefore: reverse the spacing tuple
532533
sitk_spacing = tuple(reversed(volume.spacing))
533534
image.SetSpacing(sitk_spacing)
534-
535+
535536
# Set origin and direction if available
536-
if hasattr(volume, 'position') and volume.position is not None:
537+
if hasattr(volume, "position") and volume.position is not None:
537538
# Origin (position) is in LPS physical coordinates for voxel (0,0,0)
538539
# Both highdicom and SimpleITK use the same coordinate system, so no conversion needed
539540
image.SetOrigin(volume.position)
540-
541-
if hasattr(volume, 'direction') and volume.direction is not None:
541+
542+
if hasattr(volume, "direction") and volume.direction is not None:
542543
# Direction matrix columns need reordering
543544
# highdicom: columns are [slice_dir, row_dir, col_dir] = [z, y, x]
544545
# SimpleITK: columns must be [x_dir, y_dir, z_dir]

0 commit comments

Comments
 (0)