Coverage for tests/images/test_image_server.py: 97%
210 statements
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-31 11:24 +0000
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-31 11:24 +0000
1import numpy as np
2from PIL import Image
3from qubalab.images.image_server import ImageMetadata, ImageServer
4from qubalab.images.metadata.image_shape import ImageShape
5from qubalab.images.metadata.pixel_calibration import PixelCalibration, PixelLength
6from qubalab.images.region_2d import Region2D
9sample_RGB_metadata = ImageMetadata(
10 "/path/to/img.tiff",
11 "Image name",
12 (
13 ImageShape(64, 50, c=3),
14 ImageShape(32, 25, c=3),
15 ImageShape(16, 12, c=3)
16 ),
17 PixelCalibration(
18 PixelLength.create_microns(2.5),
19 PixelLength.create_microns(2.5)
20 ),
21 True,
22 np.uint8
23)
24sample_RGB_pixels = [[[[
25 x / shape.x * 255 if c == 0 else (y / shape.y * 255 if c == 1 else 0)
26 for x in range(shape.x)]
27 for y in range(shape.y)]
28 for c in range(shape.c)]
29 for shape in sample_RGB_metadata.shapes
30]
31class SampleRGBServer(ImageServer):
32 def close(self):
33 pass
35 def _build_metadata(self) -> ImageMetadata:
36 return sample_RGB_metadata
38 def _read_block(self, level: int, region: Region2D) -> np.ndarray:
39 image = np.array(sample_RGB_pixels[level], dtype=sample_RGB_metadata.dtype)
40 return image[:, region.y:region.y+region.height, region.x:region.x+region.width]
43sample_float32_metadata = ImageMetadata(
44 "/path/to/img.tiff",
45 "Image name",
46 (
47 ImageShape(64, 50, t=5, z=2, c=3),
48 ImageShape(32, 25, t=5, z=2, c=3),
49 ImageShape(16, 12, t=5, z=2, c=3)
50 ),
51 PixelCalibration(
52 PixelLength.create_microns(2.5),
53 PixelLength.create_microns(2.5)
54 ),
55 False,
56 np.float32
57)
58sample_float32_pixels = [[[[[[
59 x/shape.x + y/shape.y + z/shape.z + c/shape.c + t/shape.t
60 for x in range(shape.x)]
61 for y in range(shape.y)]
62 for z in range(shape.z)]
63 for c in range(shape.c)]
64 for t in range(shape.t)]
65 for shape in sample_float32_metadata.shapes
66]
67class SampleFloat32Server(ImageServer):
68 def close(self):
69 pass
71 def _build_metadata(self) -> ImageMetadata:
72 return sample_float32_metadata
74 def _read_block(self, level: int, region: Region2D) -> np.ndarray:
75 image = np.array(sample_float32_pixels[level], dtype=sample_float32_metadata.dtype)
76 return image[region.t, :, region.z, region.y:region.y+region.height, region.x:region.x+region.width]
79def test_metadata():
80 expected_metadata = sample_RGB_metadata
81 sample_RGB_server = SampleRGBServer()
83 metadata = sample_RGB_server.metadata
85 assert expected_metadata == metadata
87 sample_RGB_server.close()
90def test_full_resolution_RGB_image_with_region():
91 level = 0
92 expected_image = np.array(sample_RGB_pixels[level], dtype=sample_RGB_metadata.dtype)
93 sample_RGB_server = SampleRGBServer()
95 image = sample_RGB_server.read_region(
96 sample_RGB_metadata.downsamples[level],
97 Region2D(x=0, y=0, width=sample_RGB_metadata.width, height=sample_RGB_metadata.height)
98 )
100 np.testing.assert_array_equal(image, expected_image)
102 sample_RGB_server.close()
105def test_full_resolution_RGB_image_with_region_tuple():
106 level = 0
107 expected_image = np.array(sample_RGB_pixels[level], dtype=sample_RGB_metadata.dtype)
108 sample_RGB_server = SampleRGBServer()
110 image = sample_RGB_server.read_region(
111 sample_RGB_metadata.downsamples[level],
112 (0, 0, sample_RGB_metadata.width, sample_RGB_metadata.height)
113 )
115 np.testing.assert_array_equal(image, expected_image)
117 sample_RGB_server.close()
120def test_full_resolution_RGB_image_with_tuple():
121 level = 0
122 expected_image = np.array(sample_RGB_pixels[level], dtype=sample_RGB_metadata.dtype)
123 sample_RGB_server = SampleRGBServer()
125 image = sample_RGB_server.read_region(
126 sample_RGB_metadata.downsamples[level],
127 x=0,
128 y=0,
129 width=sample_RGB_metadata.width,
130 height=sample_RGB_metadata.height
131 )
133 np.testing.assert_array_equal(image, expected_image)
135 sample_RGB_server.close()
138def test_full_resolution_RGB_image_with_dask():
139 level = 0
140 expected_image = np.array(sample_RGB_pixels[level], dtype=sample_RGB_metadata.dtype)
141 sample_RGB_server = SampleRGBServer()
143 image = sample_RGB_server.level_to_dask(level).compute()
145 np.testing.assert_array_equal(image, expected_image)
147 sample_RGB_server.close()
150def test_lowest_resolution_RGB_image():
151 level = sample_RGB_metadata.n_resolutions - 1
152 expected_image = np.array(sample_RGB_pixels[level], dtype=sample_RGB_metadata.dtype)
153 sample_RGB_server = SampleRGBServer()
155 image = sample_RGB_server.read_region(
156 sample_RGB_metadata.downsamples[level],
157 Region2D(x=0, y=0, width=sample_RGB_metadata.width, height=sample_RGB_metadata.height)
158 )
160 np.testing.assert_array_equal(image, expected_image)
162 sample_RGB_server.close()
165def test_lowest_resolution_RGB_image_with_dask():
166 level = sample_RGB_metadata.n_resolutions - 1
167 expected_image = np.array(sample_RGB_pixels[level], dtype=sample_RGB_metadata.dtype)
168 sample_RGB_server = SampleRGBServer()
170 image = sample_RGB_server.level_to_dask(level).compute()
172 np.testing.assert_array_equal(image, expected_image)
174 sample_RGB_server.close()
177def test_tile_of_full_resolution_RGB_image():
178 level = 0
179 xFrom = int(sample_RGB_metadata.width/4)
180 xTo = int(3*sample_RGB_metadata.width/4)
181 yFrom = int(sample_RGB_metadata.height/4)
182 yTo = int(3*sample_RGB_metadata.height/4)
183 expected_image = np.array(sample_RGB_pixels[level], dtype=sample_RGB_metadata.dtype)[:, yFrom:yTo+1, xFrom:xTo+1]
184 sample_RGB_server = SampleRGBServer()
186 image = sample_RGB_server.read_region(
187 sample_RGB_metadata.downsamples[level],
188 Region2D(x=xFrom, y=yFrom, width=xTo-xFrom+1, height=yTo-yFrom+1)
189 )
191 np.testing.assert_array_equal(image, expected_image)
193 sample_RGB_server.close()
196def test_downsampled_RGB_image():
197 downsample = 1.5
198 c = 0
199 expected_pixels = Image \
200 .fromarray(np.array(sample_RGB_pixels[0], sample_RGB_metadata.dtype)[c, ...]) \
201 .resize((round(sample_RGB_metadata.width / downsample), round(sample_RGB_metadata.height / downsample)))
202 sample_RGB_server = SampleRGBServer()
204 pixels = sample_RGB_server.read_region(downsample, Region2D(x=0, y=0, width=sample_RGB_metadata.width, height=sample_RGB_metadata.height))
206 np.testing.assert_array_equal(pixels[c, ...], expected_pixels)
208 sample_RGB_server.close()
211def test_scaled_RGB_image():
212 downsample = 0.5
213 c = 0
214 expected_pixels = Image \
215 .fromarray(np.array(sample_RGB_pixels[0], sample_RGB_metadata.dtype)[c, ...]) \
216 .resize((round(sample_RGB_metadata.width / downsample), round(sample_RGB_metadata.height / downsample)))
217 sample_RGB_server = SampleRGBServer()
219 pixels = sample_RGB_server.read_region(downsample, Region2D(x=0, y=0, width=sample_RGB_metadata.width, height=sample_RGB_metadata.height))
221 np.testing.assert_array_equal(pixels[c, ...], expected_pixels)
223 sample_RGB_server.close()
226def test_downsampled_RGB_image_with_dask():
227 downsample = 1.5
228 c = 0
229 expected_pixels = Image \
230 .fromarray(np.array(sample_RGB_pixels[0], sample_RGB_metadata.dtype)[c, ...]) \
231 .resize((round(sample_RGB_metadata.width / downsample), round(sample_RGB_metadata.height / downsample)))
232 sample_RGB_server = SampleRGBServer()
234 pixels = sample_RGB_server.read_region(downsample, Region2D(x=0, y=0, width=sample_RGB_metadata.width, height=sample_RGB_metadata.height))
236 np.testing.assert_array_equal(pixels[c, ...], expected_pixels)
238 sample_RGB_server.close()
241def test_downsampled_RGB_image_with_dask():
242 downsample = 1.5
243 c = 0
244 expected_pixels = Image \
245 .fromarray(np.array(sample_RGB_pixels[0], sample_RGB_metadata.dtype)[c, ...]) \
246 .resize((round(sample_RGB_metadata.width / downsample), round(sample_RGB_metadata.height / downsample)))
247 sample_RGB_server = SampleRGBServer()
249 pixels = sample_RGB_server.to_dask(downsample).compute()
251 np.testing.assert_allclose(pixels[c, ...], expected_pixels, atol=2)
253 sample_RGB_server.close()
256def test_full_resolution_float32_image_with_region():
257 level = 0
258 z = int(sample_float32_metadata.shapes[level].z / 2)
259 t = int(sample_float32_metadata.shapes[level].t / 2)
260 expected_image = np.array(sample_float32_pixels[level], dtype=sample_float32_metadata.dtype)[t, :, z, ...]
261 sample_float32_server = SampleFloat32Server()
263 image = sample_float32_server.read_region(
264 sample_float32_metadata.downsamples[level],
265 Region2D(x=0, y=0, width=sample_float32_metadata.width, height=sample_float32_metadata.height, z=z, t=t)
266 )
268 np.testing.assert_array_equal(image, expected_image)
270 sample_float32_server.close()
273def test_full_resolution_float32_image_with_region_tuple():
274 level = 0
275 z = int(sample_float32_metadata.shapes[level].z / 2)
276 t = int(sample_float32_metadata.shapes[level].t / 2)
277 expected_image = np.array(sample_float32_pixels[level], dtype=sample_float32_metadata.dtype)[t, :, z, ...]
278 sample_float32_server = SampleFloat32Server()
280 image = sample_float32_server.read_region(
281 sample_float32_metadata.downsamples[level],
282 (0, 0, sample_float32_metadata.width, sample_float32_metadata.height, z, t)
283 )
285 np.testing.assert_array_equal(image, expected_image)
287 sample_float32_server.close()
290def test_full_resolution_float32_image_with_tuple():
291 level = 0
292 z = int(sample_float32_metadata.shapes[level].z / 2)
293 t = int(sample_float32_metadata.shapes[level].t / 2)
294 expected_image = np.array(sample_float32_pixels[level], dtype=sample_float32_metadata.dtype)[t, :, z, ...]
295 sample_float32_server = SampleFloat32Server()
297 image = sample_float32_server.read_region(
298 sample_float32_metadata.downsamples[level],
299 x=0,
300 y=0,
301 width=sample_float32_metadata.width,
302 height=sample_float32_metadata.height,
303 z=z,
304 t=t
305 )
307 np.testing.assert_array_equal(image, expected_image)
309 sample_float32_server.close()
312def test_full_resolution_float32_image_with_dask():
313 level = 0
314 expected_image = np.array(sample_float32_pixels[level], dtype=sample_float32_metadata.dtype)
315 sample_float32_server = SampleFloat32Server()
317 image = sample_float32_server.level_to_dask(level).compute()
319 np.testing.assert_array_equal(image, expected_image)
321 sample_float32_server.close()
324def test_lowest_resolution_float32_image():
325 level = sample_float32_metadata.n_resolutions - 1
326 z = int(sample_float32_metadata.shapes[level].z / 2)
327 t = int(sample_float32_metadata.shapes[level].t / 2)
328 expected_image = np.array(sample_float32_pixels[level], dtype=sample_float32_metadata.dtype)[t, :, z, ...]
329 sample_float32_server = SampleFloat32Server()
331 image = sample_float32_server.read_region(
332 sample_float32_metadata.downsamples[level],
333 Region2D(x=0, y=0, width=sample_float32_metadata.width, height=sample_float32_metadata.height, z=z, t=t)
334 )
336 np.testing.assert_array_equal(image, expected_image)
338 sample_float32_server.close()
341def test_lowest_resolution_float32_image_with_dask():
342 level = sample_float32_metadata.n_resolutions - 1
343 expected_image = np.array(sample_float32_pixels[level], dtype=sample_float32_metadata.dtype)
344 sample_float32_server = SampleFloat32Server()
346 image = sample_float32_server.level_to_dask(level).compute()
348 np.testing.assert_array_equal(image, expected_image)
350 sample_float32_server.close()
353def test_tile_of_full_resolution_float32_image():
354 level = 0
355 z = int(sample_float32_metadata.shapes[level].z / 2)
356 t = int(sample_float32_metadata.shapes[level].t / 2)
357 xFrom = int(sample_float32_metadata.width/4)
358 xTo = int(3*sample_float32_metadata.width/4)
359 yFrom = int(sample_float32_metadata.height/4)
360 yTo = int(3*sample_float32_metadata.height/4)
361 expected_image = np.array(sample_float32_pixels[level], dtype=sample_float32_metadata.dtype)[t, :, z, yFrom:yTo+1, xFrom:xTo+1]
362 sample_float32_server = SampleFloat32Server()
364 image = sample_float32_server.read_region(
365 sample_float32_metadata.downsamples[level],
366 Region2D(x=xFrom, y=yFrom, width=xTo-xFrom+1, height=yTo-yFrom+1, z=z, t=t)
367 )
369 np.testing.assert_array_equal(image, expected_image)
371 sample_float32_server.close()
374def test_downsampled_float32_image():
375 downsample = 1.5
376 z = 0
377 c = 0
378 t = 0
379 expected_pixels = Image \
380 .fromarray(np.array(sample_float32_pixels[0], sample_float32_metadata.dtype)[t, c, z, ...]) \
381 .resize((round(sample_float32_metadata.width / downsample), round(sample_float32_metadata.height / downsample)))
382 sample_float32_server = SampleFloat32Server()
384 pixels = sample_float32_server.read_region(
385 downsample,
386 Region2D(0, 0, sample_float32_metadata.width, sample_float32_metadata.height, z, t)
387 )
389 np.testing.assert_array_equal(pixels[c, ...], expected_pixels)
391 sample_float32_server.close()
394def test_scaled_float32_image():
395 downsample = 0.5
396 z = 0
397 c = 0
398 t = 0
399 expected_pixels = Image \
400 .fromarray(np.array(sample_float32_pixels[0], sample_float32_metadata.dtype)[t, c, z, ...]) \
401 .resize((round(sample_float32_metadata.width / downsample), round(sample_float32_metadata.height / downsample)))
402 sample_float32_server = SampleFloat32Server()
404 pixels = sample_float32_server.read_region(
405 downsample,
406 Region2D(0, 0, sample_float32_metadata.width, sample_float32_metadata.height, z, t)
407 )
409 np.testing.assert_array_equal(pixels[c, ...], expected_pixels)
411 sample_float32_server.close()
414def test_downsampled_float32_image_with_dask():
415 downsample = 1.5
416 z = 0
417 c = 0
418 t = 0
419 expected_pixels = Image \
420 .fromarray(np.array(sample_float32_pixels[0], sample_float32_metadata.dtype)[t, c, z, ...]) \
421 .resize((round(sample_float32_metadata.width / downsample), round(sample_float32_metadata.height / downsample)))
422 sample_float32_server = SampleFloat32Server()
424 pixels = sample_float32_server.to_dask(downsample).compute()
426 np.testing.assert_allclose(pixels[t, c, z, ...], expected_pixels, atol=2)
428 sample_float32_server.close()