@@ -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
180183if __name__ == "__main__" :
181- test ()
184+ test ()
0 commit comments