Skip to content

Commit 04fd450

Browse files
committed
Refactor operator imports and improve code formatting
- Updated import statements in various operator files to use parentheses for better readability. - Cleaned up whitespace and formatting inconsistencies across multiple files, enhancing overall code clarity. - Ensured consistent handling of newlines and indentation in operator implementations and test files. Signed-off-by: Victor Chang <[email protected]>
1 parent 64f9d3e commit 04fd450

38 files changed

+1962
-1595
lines changed

monai/deploy/operators/__init__.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,27 @@
4646

4747
# If needed, can choose to expose some or all of Holoscan SDK built-in operators.
4848
# from holoscan.operators import *
49-
from holoscan.operators import PingRxOp, PingTxOp, VideoStreamRecorderOp, VideoStreamReplayerOp
49+
from holoscan.operators import (
50+
PingRxOp,
51+
PingTxOp,
52+
VideoStreamRecorderOp,
53+
VideoStreamReplayerOp,
54+
)
5055

5156
from .clara_viz_operator import ClaraVizOperator
5257
from .dicom_data_loader_operator import DICOMDataLoaderOperator
5358
from .dicom_encapsulated_pdf_writer_operator import DICOMEncapsulatedPDFWriterOperator
54-
from .dicom_seg_writer_operator import DICOMSegmentationWriterOperator, SegmentDescription
59+
from .dicom_seg_writer_operator import (
60+
DICOMSegmentationWriterOperator,
61+
SegmentDescription,
62+
)
5563
from .dicom_series_selector_operator import DICOMSeriesSelectorOperator
5664
from .dicom_series_to_volume_operator import DICOMSeriesToVolumeOperator
57-
from .dicom_text_sr_writer_operator import DICOMTextSRWriterOperator, EquipmentInfo, ModelInfo
65+
from .dicom_text_sr_writer_operator import (
66+
DICOMTextSRWriterOperator,
67+
EquipmentInfo,
68+
ModelInfo,
69+
)
5870
from .image_directory_loader_operator import ImageDirectoryLoader
5971
from .inference_operator import InferenceOperator
6072
from .json_results_writer_operator import JSONResultsWriter

monai/deploy/operators/image_directory_loader_operator.py

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ class ImageDirectoryLoader(Operator):
3636
image: Image object loaded from file
3737
filename: Name of the loaded file (without extension)
3838
"""
39-
40-
SUPPORTED_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.bmp', '.tiff', '.tif']
41-
39+
40+
SUPPORTED_EXTENSIONS = [".jpg", ".jpeg", ".png", ".bmp", ".tiff", ".tif"]
41+
4242
def __init__(
4343
self,
4444
fragment: Fragment,
@@ -57,82 +57,84 @@ def __init__(
5757
self._logger = logging.getLogger("{}.{}".format(__name__, type(self).__name__))
5858
self._input_folder = Path(input_folder)
5959
self._channel_first = bool(channel_first)
60-
60+
6161
super().__init__(fragment, *args, **kwargs)
62-
62+
6363
def _find_image_files(self) -> List[Path]:
6464
"""Find all supported image files in the input directory."""
6565
image_files = []
6666
for ext in self.SUPPORTED_EXTENSIONS:
6767
image_files.extend(self._input_folder.rglob(f"*{ext}"))
6868
image_files.extend(self._input_folder.rglob(f"*{ext.upper()}"))
69-
69+
7070
# Sort files for consistent ordering
7171
image_files.sort()
7272
return image_files
73-
73+
7474
def setup(self, spec: OperatorSpec):
7575
"""Define the operator outputs."""
7676
spec.output("image")
7777
spec.output("filename")
78-
78+
7979
# Pre-initialize the image files list
8080
self._image_files = self._find_image_files()
8181
self._current_index = 0
82-
82+
8383
if not self._image_files:
8484
self._logger.warning(f"No image files found in {self._input_folder}")
8585
else:
8686
self._logger.info(f"Found {len(self._image_files)} image files to process")
87-
87+
8888
def compute(self, op_input, op_output, context):
8989
"""Load one image and emit it."""
90-
90+
9191
# Check if we have more images to process
9292
if self._current_index >= len(self._image_files):
9393
# No more images to process
9494
self._logger.info("All images have been processed")
9595
self.fragment.stop_execution()
9696
return
97-
97+
9898
# Get the current image path
9999
image_path = self._image_files[self._current_index]
100-
100+
101101
try:
102102
# Load image using PIL
103103
pil_image = PILImage.open(image_path)
104-
104+
105105
# Convert to RGB if necessary
106-
if pil_image.mode != 'RGB':
107-
pil_image = pil_image.convert('RGB')
108-
106+
if pil_image.mode != "RGB":
107+
pil_image = pil_image.convert("RGB")
108+
109109
# Convert to numpy array (HWC float32). Intensity scaling (to [0,1]) is typically handled by bundle.
110110
image_array = np.array(pil_image).astype(np.float32)
111111

112112
# Convert to channel-first when requested
113113
if self._channel_first:
114114
# PIL loads HWC; convert to CHW
115115
image_array = np.transpose(image_array, (2, 0, 1))
116-
116+
117117
# Create metadata
118118
metadata = {
119119
"filename": str(image_path),
120120
"original_shape": image_array.shape,
121121
"source_format": image_path.suffix.lower(),
122122
}
123-
123+
124124
# Create Image object
125125
image_obj = Image(image_array, metadata=metadata)
126-
126+
127127
# Emit the image and filename
128128
op_output.emit(image_obj, "image")
129129
op_output.emit(image_path.stem, "filename")
130-
131-
self._logger.info(f"Loaded and emitted image: {image_path.name} ({self._current_index + 1}/{len(self._image_files)})")
132-
130+
131+
self._logger.info(
132+
f"Loaded and emitted image: {image_path.name} ({self._current_index + 1}/{len(self._image_files)})"
133+
)
134+
133135
except Exception as e:
134136
self._logger.error(f"Failed to load image {image_path}: {e}")
135-
137+
136138
# Move to the next image
137139
self._current_index += 1
138140

@@ -141,41 +143,42 @@ def test():
141143
"""Test the ImageDirectoryLoader operator."""
142144
import tempfile
143145
from PIL import Image as PILImageCreate
144-
146+
145147
# Create a temporary directory with test images
146148
with tempfile.TemporaryDirectory() as temp_dir:
147149
temp_path = Path(temp_dir)
148-
150+
149151
# Create test images
150152
for i in range(3):
151-
img = PILImageCreate.new('RGB', (100, 100), color=(i*50, i*50, i*50))
153+
img = PILImageCreate.new("RGB", (100, 100), color=(i * 50, i * 50, i * 50))
152154
img.save(temp_path / f"test_{i}.jpg")
153-
155+
154156
# Test the operator
155157
fragment = Fragment()
156158
loader = ImageDirectoryLoader(fragment, input_folder=temp_path)
157-
159+
158160
# Simulate setup
159161
from monai.deploy.core import OperatorSpec
162+
160163
spec = OperatorSpec()
161164
loader.setup(spec)
162-
165+
163166
print(f"Found {len(loader._image_files)} test images")
164-
167+
165168
# Simulate compute calls
166169
class MockOutput:
167170
def emit(self, data, name):
168171
if name == "filename":
169172
print(f"Emitted filename: {data}")
170173
elif name == "image":
171174
print(f"Emitted image with shape: {data.asnumpy().shape}")
172-
175+
173176
mock_output = MockOutput()
174-
177+
175178
# Process all images
176179
while loader._current_index < len(loader._image_files):
177180
loader.compute(None, mock_output, None)
178181

179182

180183
if __name__ == "__main__":
181-
test()
184+
test()

monai/deploy/operators/image_overlay_writer_operator.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,9 @@ def _to_hwc_uint8(self, image) -> np.ndarray:
7878
else:
7979
arr = np.asarray(image)
8080
if arr.ndim != 3 or arr.shape[2] not in (3, 4):
81-
raise ValueError(f"Expected HWC image with 3 or 4 channels, got shape {arr.shape}")
81+
raise ValueError(
82+
f"Expected HWC image with 3 or 4 channels, got shape {arr.shape}"
83+
)
8284
# Drop alpha if present
8385
if arr.shape[2] == 4:
8486
arr = arr[..., :3]
@@ -103,15 +105,17 @@ def _to_mask_uint8(self, pred) -> np.ndarray:
103105
return arr
104106

105107
@staticmethod
106-
def _blend_overlay(img: np.ndarray, mask_u8: np.ndarray, alpha: float, color: Tuple[int, int, int]) -> np.ndarray:
108+
def _blend_overlay(
109+
img: np.ndarray, mask_u8: np.ndarray, alpha: float, color: Tuple[int, int, int]
110+
) -> np.ndarray:
107111
# img: HWC uint8, mask_u8: HW uint8
108112
mask = (mask_u8 > 0).astype(np.float32)[..., None]
109113
color_img = np.zeros_like(img, dtype=np.uint8)
110114
color_img[..., 0] = color[0]
111115
color_img[..., 1] = color[1]
112116
color_img[..., 2] = color[2]
113-
blended = (img.astype(np.float32) * (1.0 - alpha * mask) + color_img.astype(np.float32) * (alpha * mask)).astype(
114-
np.uint8
115-
)
117+
blended = (
118+
img.astype(np.float32) * (1.0 - alpha * mask)
119+
+ color_img.astype(np.float32) * (alpha * mask)
120+
).astype(np.uint8)
116121
return blended
117-

0 commit comments

Comments
 (0)