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

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 

7 

8 

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 

34 

35 def _build_metadata(self) -> ImageMetadata: 

36 return sample_RGB_metadata 

37 

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] 

41 

42 

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 

70 

71 def _build_metadata(self) -> ImageMetadata: 

72 return sample_float32_metadata 

73 

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] 

77 

78 

79def test_metadata(): 

80 expected_metadata = sample_RGB_metadata 

81 sample_RGB_server = SampleRGBServer() 

82 

83 metadata = sample_RGB_server.metadata 

84 

85 assert expected_metadata == metadata 

86 

87 sample_RGB_server.close() 

88 

89 

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() 

94 

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 ) 

99 

100 np.testing.assert_array_equal(image, expected_image) 

101 

102 sample_RGB_server.close() 

103 

104 

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() 

109 

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 ) 

114 

115 np.testing.assert_array_equal(image, expected_image) 

116 

117 sample_RGB_server.close() 

118 

119 

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() 

124 

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 ) 

132 

133 np.testing.assert_array_equal(image, expected_image) 

134 

135 sample_RGB_server.close() 

136 

137 

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() 

142 

143 image = sample_RGB_server.level_to_dask(level).compute() 

144 

145 np.testing.assert_array_equal(image, expected_image) 

146 

147 sample_RGB_server.close() 

148 

149 

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() 

154 

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 ) 

159 

160 np.testing.assert_array_equal(image, expected_image) 

161 

162 sample_RGB_server.close() 

163 

164 

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() 

169 

170 image = sample_RGB_server.level_to_dask(level).compute() 

171 

172 np.testing.assert_array_equal(image, expected_image) 

173 

174 sample_RGB_server.close() 

175 

176 

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() 

185 

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 ) 

190 

191 np.testing.assert_array_equal(image, expected_image) 

192 

193 sample_RGB_server.close() 

194 

195 

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() 

203 

204 pixels = sample_RGB_server.read_region(downsample, Region2D(x=0, y=0, width=sample_RGB_metadata.width, height=sample_RGB_metadata.height)) 

205 

206 np.testing.assert_array_equal(pixels[c, ...], expected_pixels) 

207 

208 sample_RGB_server.close() 

209 

210 

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() 

218 

219 pixels = sample_RGB_server.read_region(downsample, Region2D(x=0, y=0, width=sample_RGB_metadata.width, height=sample_RGB_metadata.height)) 

220 

221 np.testing.assert_array_equal(pixels[c, ...], expected_pixels) 

222 

223 sample_RGB_server.close() 

224 

225 

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() 

233 

234 pixels = sample_RGB_server.read_region(downsample, Region2D(x=0, y=0, width=sample_RGB_metadata.width, height=sample_RGB_metadata.height)) 

235 

236 np.testing.assert_array_equal(pixels[c, ...], expected_pixels) 

237 

238 sample_RGB_server.close() 

239 

240 

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() 

248 

249 pixels = sample_RGB_server.to_dask(downsample).compute() 

250 

251 np.testing.assert_allclose(pixels[c, ...], expected_pixels, atol=2) 

252 

253 sample_RGB_server.close() 

254 

255 

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() 

262 

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 ) 

267 

268 np.testing.assert_array_equal(image, expected_image) 

269 

270 sample_float32_server.close() 

271 

272 

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() 

279 

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 ) 

284 

285 np.testing.assert_array_equal(image, expected_image) 

286 

287 sample_float32_server.close() 

288 

289 

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() 

296 

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 ) 

306 

307 np.testing.assert_array_equal(image, expected_image) 

308 

309 sample_float32_server.close() 

310 

311 

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() 

316 

317 image = sample_float32_server.level_to_dask(level).compute() 

318 

319 np.testing.assert_array_equal(image, expected_image) 

320 

321 sample_float32_server.close() 

322 

323 

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() 

330 

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 ) 

335 

336 np.testing.assert_array_equal(image, expected_image) 

337 

338 sample_float32_server.close() 

339 

340 

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() 

345 

346 image = sample_float32_server.level_to_dask(level).compute() 

347 

348 np.testing.assert_array_equal(image, expected_image) 

349 

350 sample_float32_server.close() 

351 

352 

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() 

363 

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 ) 

368 

369 np.testing.assert_array_equal(image, expected_image) 

370 

371 sample_float32_server.close() 

372 

373 

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() 

383 

384 pixels = sample_float32_server.read_region( 

385 downsample, 

386 Region2D(0, 0, sample_float32_metadata.width, sample_float32_metadata.height, z, t) 

387 ) 

388 

389 np.testing.assert_array_equal(pixels[c, ...], expected_pixels) 

390 

391 sample_float32_server.close() 

392 

393 

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() 

403 

404 pixels = sample_float32_server.read_region( 

405 downsample, 

406 Region2D(0, 0, sample_float32_metadata.width, sample_float32_metadata.height, z, t) 

407 ) 

408 

409 np.testing.assert_array_equal(pixels[c, ...], expected_pixels) 

410 

411 sample_float32_server.close() 

412 

413 

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() 

423 

424 pixels = sample_float32_server.to_dask(downsample).compute() 

425 

426 np.testing.assert_allclose(pixels[t, c, z, ...], expected_pixels, atol=2) 

427 

428 sample_float32_server.close()