Coverage for /scratch/builds/bob/bob.med.tb/miniconda/conda-bld/bob.med.tb_1674079587905/_test_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placeho/lib/python3.10/site-packages/bob/med/tb/data/transforms.py: 100%

38 statements  

« prev     ^ index     » next       coverage.py v7.0.5, created at 2023-01-18 22:14 +0000

1#!/usr/bin/env python 

2# -*- coding: utf-8 -*- 

3 

4"""Image transformations for our pipelines 

5 

6Differences between methods here and those from 

7:py:mod:`torchvision.transforms` is that these support multiple simultaneous 

8image inputs, which are required to feed segmentation networks (e.g. image and 

9labels or masks). We also take care of data augmentations, in which random 

10flipping and rotation needs to be applied across all input images, but color 

11jittering, for example, only on the input image. 

12""" 

13 

14import random 

15 

16import numpy 

17import PIL.Image 

18from scipy.ndimage import gaussian_filter, map_coordinates 

19 

20class SingleAutoLevel16to8: 

21 """Converts a 16-bit image to 8-bit representation using "auto-level" 

22 

23 This transform assumes that the input image is gray-scaled. 

24 

25 To auto-level, we calculate the maximum and the minimum of the image, and 

26 consider such a range should be mapped to the [0,255] range of the 

27 destination image. 

28 

29 """ 

30 

31 def __call__(self, img): 

32 imin, imax = img.getextrema() 

33 irange = imax - imin 

34 return PIL.Image.fromarray( 

35 numpy.round( 

36 255.0 * (numpy.array(img).astype(float) - imin) / irange 

37 ).astype("uint8"), 

38 ).convert("L") 

39 

40 

41class RemoveBlackBorders: 

42 """Remove black borders of CXR""" 

43 def __init__(self, threshold=0): 

44 self.threshold = threshold 

45 

46 def __call__(self, img): 

47 img = numpy.asarray(img) 

48 mask = numpy.asarray(img) > self.threshold 

49 return PIL.Image.fromarray( 

50 img[numpy.ix_(mask.any(1), mask.any(0))] 

51 ) 

52 

53class ElasticDeformation: 

54 """Elastic deformation of 2D image slightly adapted from [SIMARD-2003]_. 

55 .. [SIMARD-2003] Simard, Steinkraus and Platt, "Best Practices for 

56 Convolutional Neural Networks applied to Visual Document Analysis", in 

57 Proc. of the International Conference on Document Analysis and 

58 Recognition, 2003. 

59 Source: https://gist.github.com/oeway/2e3b989e0343f0884388ed7ed82eb3b0 

60 """ 

61 def __init__(self, alpha=1000, sigma=30, spline_order=1, mode='nearest', random_state=numpy.random, p=1): 

62 self.alpha = alpha 

63 self.sigma = sigma 

64 self.spline_order = spline_order 

65 self.mode = mode 

66 self.random_state = random_state 

67 self.p = p 

68 

69 def __call__(self, img): 

70 

71 if random.random() < self.p: 

72 

73 img = numpy.asarray(img) 

74 

75 assert img.ndim == 2 

76 

77 shape = img.shape 

78 

79 dx = gaussian_filter((self.random_state.rand(*shape) * 2 - 1), 

80 self.sigma, mode="constant", cval=0) * self.alpha 

81 dy = gaussian_filter((self.random_state.rand(*shape) * 2 - 1), 

82 self.sigma, mode="constant", cval=0) * self.alpha 

83 

84 x, y = numpy.meshgrid(numpy.arange(shape[0]), numpy.arange(shape[1]), indexing='ij') 

85 indices = [numpy.reshape(x + dx, (-1, 1)), numpy.reshape(y + dy, (-1, 1))] 

86 result = numpy.empty_like(img) 

87 result[:, :] = map_coordinates( 

88 img[:, :], indices, order=self.spline_order, mode=self.mode).reshape(shape) 

89 return PIL.Image.fromarray(result) 

90 else: 

91 return img