Coverage for qubalab/images/utils.py: 93%

27 statements  

« prev     ^ index     » next       coverage.py v7.6.10, created at 2025-01-31 11:24 +0000

1import numpy as np 

2import imageio 

3import base64 

4from .metadata.image_shape import ImageShape 

5 

6 

7def bytes_to_image(uri: {str, bytes}, is_rgb: bool, shape: ImageShape = None) -> np.ndarray: 

8 """ 

9 Read the provided bytes (or URI pointing to a binary file) and convert them to a numpy array 

10 representing an image. 

11 

12 :param uri: an URI pointing to a binary file, or an array of bytes. This must 

13 represent a 2-dimensionnal or 3-dimensionnal (with a channel axis) image 

14 :param is_rgb: whether the expected image should have the RGB format 

15 :param shape: the shape of the image to open. This will be used to reorder axes. 

16 Can be None to not reorder axes 

17 :returns: a numpy array representing the input image. If shape is defined, this function 

18 will try to set its dimensions to (c, y, x), but this may not always be the case if two 

19 dimensions have the same number of elements 

20 """ 

21 if is_rgb: 

22 image = imageio.v3.imread(uri) 

23 else: 

24 image = imageio.volread(uri, format="tiff") 

25 

26 if shape is None: 

27 return image 

28 else: 

29 return _reorder_axes(image, shape) 

30 

31 

32def base64_to_image(data: str, is_rgb: bool, shape: ImageShape = None) -> np.ndarray: 

33 """ 

34 Read the provided string with the Base64 format and convert it to a numpy array 

35 representing an image. 

36 

37 :param uri: a text with the Base64 format. This must represent a 2-dimensionnal 

38 or 3-dimensionnal (with a channel axis) image 

39 :param is_rgb: whether the expected image should have the RGB format 

40 :param shape: the shape of the image to open. This will be used to reorder axes. 

41 Can be None to not reorder axes 

42 :returns: a numpy array representing the input image. If shape is defined, this function 

43 will try to set its dimensions to (c, y, x), but this may not always be the case if two 

44 dimensions have the same number of elements 

45 """ 

46 return bytes_to_image(base64.b64decode(data), is_rgb, shape) 

47 

48 

49def _reorder_axes(image: np.ndarray, shape: ImageShape): 

50 """ 

51 Reorder the axes of the provided image to (c, y, x). 

52 

53 :param image: the image to reorder 

54 :param shape: the desired shape of the image 

55 :param shape: the shape of the image to open. This will be used to reorder axes 

56 :returns: a numpy array representing the input image. This function will try to set 

57 its dimensions to (c, y, x), but this may not be the case if two 

58 dimensions have the same number of elements 

59 """ 

60 x_axis = -1 

61 y_axis = -1 

62 c_axis = -1 

63 for axis, number_of_elements_on_axis in enumerate(image.shape): 

64 if c_axis == -1 and number_of_elements_on_axis == shape.c: 

65 c_axis = axis 

66 elif y_axis == -1 and number_of_elements_on_axis == shape.y: 

67 y_axis = axis 

68 elif x_axis == -1 and number_of_elements_on_axis == shape.x: 

69 x_axis = axis 

70 

71 if x_axis != -1 and y_axis != -1 and c_axis != -1: 

72 return np.moveaxis(image, [c_axis, y_axis, x_axis], [0, 1, 2]).copy() 

73 else: 

74 return image