diff --git a/conf/testing.py b/conf/testing.py index f2df5040d83ede67bd06bb1c114e2e02bc0a0772..3c52b95cd108adb3cfd83cc6800a17b85d887d0a 100644 --- a/conf/testing.py +++ b/conf/testing.py @@ -10,6 +10,7 @@ czifile = { 'h': 1274, 'c': 5, 'z': 1, + 'um_per_pixel': 1/3.9881, } filename = 'rgb.png' diff --git a/model_server/accessors.py b/model_server/accessors.py index b6e5da1f65a136b6317584cb83193439785eb50c..caec8ddf5085f5b43174e27c1462dddcee2ac350 100644 --- a/model_server/accessors.py +++ b/model_server/accessors.py @@ -37,13 +37,19 @@ class GenericImageDataAccessor(ABC): if self._data.dtype == 'bool': return True elif self._data.dtype == 'uint8': - return np.all(np.unique(self._data) == [0, 255]) + unique = np.unique(self._data) + if unique.shape[0] == 2 and np.all(unique == [0, 255]): + return True return False def get_one_channel_data (self, channel: int): c = int(channel) return InMemoryDataAccessor(self.data[:, :, c:(c+1), :]) + @property + def pixel_scale_in_micrometers(self): + return None + @property def dtype(self): return self.data.dtype @@ -163,12 +169,23 @@ class CziImageFileAccessor(GenericImageFileAccessor): [cf.axes.index(ch) for ch in idx], [0, 1, 2, 3] ) - self._data = self.conform_data(yxcz.reshape(yxcz.shape[0:4])) def __del__(self): self.czifile.close() + @property + def pixel_scale_in_micrometers(self): + meta_sc_str = self.czifile.metadata(raw=False)['ImageDocument']['Metadata']['ImageScaling']['ImagePixelSize'] + meta_mags = self.czifile.metadata(raw=False)['ImageDocument']['Metadata']['ImageScaling']['ScalingComponent'] + sc_xy = list(map( + float, + meta_sc_str.split(',') + )) + assert sc_xy[0] == sc_xy[1] + mags = [float(m['Magnification']) for m in meta_mags] + return sc_xy[0] / np.product(mags) + def write_accessor_data_to_file(fpath: Path, accessor: GenericImageDataAccessor, mkdir=True) -> bool: if mkdir: diff --git a/tests/test_accessors.py b/tests/test_accessors.py index f7a4341dc04d42aff05ed6f01f0113578590684a..1a465dfb556086ca9cc3ff88941c09052680d1ac 100644 --- a/tests/test_accessors.py +++ b/tests/test_accessors.py @@ -110,4 +110,8 @@ class TestCziImageFileAccess(unittest.TestCase): def test_read_zstack_mono_mask(self): acc = generate_file_accessor(monozstackmask['path']) - self.assertTrue(acc.is_mask()) \ No newline at end of file + self.assertTrue(acc.is_mask()) + + def test_read_in_pixel_scale_from_czi(self): + cf = CziImageFileAccessor(czifile['path']) + self.assertAlmostEqual(cf.pixel_scale_in_micrometers, czifile['um_per_pixel'], places=3) \ No newline at end of file