@@ -250,9 +250,11 @@ class BioFormatsBackend(SlideBackend):
250
250
251
251
Args:
252
252
filename (str): path to image file on disk
253
+ dtype (numpy.dtype): data type of image. If ``None``, will use BioFormats to infer the data type from the
254
+ image's OME metadata. Defaults to ``None``.
253
255
"""
254
256
255
- def __init__ (self , filename ):
257
+ def __init__ (self , filename , dtype = None ):
256
258
self .filename = filename
257
259
# init java virtual machine
258
260
javabridge .start_vm (class_path = bioformats .JARS , max_heap_size = "50G" )
@@ -287,6 +289,37 @@ def __init__(self, filename):
287
289
self .shape_list = sizeSeries # shape on all levels
288
290
self .metadata = bioformats .get_omexml_metadata (self .filename )
289
291
292
+ if dtype :
293
+ assert isinstance (
294
+ dtype , np .dtype
295
+ ), f"dtype is of type { type (dtype )} . Must be a np.dtype"
296
+ self .pixel_dtype = dtype
297
+ else :
298
+ # infer pixel data type from metadata
299
+ # map from ome pixel datatypes to numpy types. Based on:
300
+ # https://github.com/CellProfiler/python-bioformats/blob/c03fb0988caf686251707adc4332d0aff9f02941/bioformats/omexml.py#L77-L87
301
+ # but specifying that float = float32 (np.float defaults to float64)
302
+ pixel_dtype_map = {
303
+ bioformats .omexml .PT_INT8 : np .dtype ("int8" ),
304
+ bioformats .omexml .PT_INT16 : np .dtype ("int16" ),
305
+ bioformats .omexml .PT_INT32 : np .dtype ("int32" ),
306
+ bioformats .omexml .PT_UINT8 : np .dtype ("uint8" ),
307
+ bioformats .omexml .PT_UINT16 : np .dtype ("uint16" ),
308
+ bioformats .omexml .PT_UINT32 : np .dtype ("uint32" ),
309
+ bioformats .omexml .PT_FLOAT : np .dtype ("float32" ),
310
+ bioformats .omexml .PT_BIT : np .dtype ("bool" ),
311
+ bioformats .omexml .PT_DOUBLE : np .dtype ("float64" ),
312
+ }
313
+ ome_pixeltype = (
314
+ bioformats .OMEXML (self .metadata ).image ().Pixels .get_PixelType ()
315
+ )
316
+ try :
317
+ self .pixel_dtype = pixel_dtype_map [ome_pixeltype ]
318
+ except :
319
+ raise Exception (
320
+ f"pixel type '{ ome_pixeltype } ' detected from OME metadata not recognized."
321
+ )
322
+
290
323
def __repr__ (self ):
291
324
return f"BioFormatsBackend('{ self .filename } ')"
292
325
@@ -423,8 +456,12 @@ def extract_region(self, location, size, level=0, series_as_channels=False):
423
456
else :
424
457
array [:, :, z , level , t ] = slicearray
425
458
426
- array = array .astype (np .uint8 )
427
- return array
459
+ # scale array before converting: https://github.com/Dana-Farber-AIOS/pathml/issues/271
460
+ # first scale to [0-1]
461
+ array_scaled = array / (2 ** (8 * self .pixel_dtype .itemsize ))
462
+ # then scale to [0-255] and convert to 8 bit
463
+ array_scaled = array_scaled * 2 ** 8
464
+ return array_scaled .astype (np .uint8 )
428
465
429
466
def get_thumbnail (self , size = None ):
430
467
"""
0 commit comments