Coverage for src/mlstatpy/image/detection_segment/random_image.py: 100%

47 statements  

« prev     ^ index     » next       coverage.py v7.1.0, created at 2023-02-27 05:59 +0100

1# -*- coding: utf-8 -*- 

2""" 

3@file 

4@brief Génère des images aléatoires. 

5""" 

6import math 

7import numpy 

8import numpy.random as nprnd # pylint: disable=E1101 

9 

10 

11def random_noise_image(size, ratio=0.1): 

12 """ 

13 Construit une image blanche de taille *size*, 

14 noircit aléatoirement *ratio x nb pixels* 

15 pixels. 

16 

17 @param size taille de l'image 

18 @param ratio proportion de pixels à noircir 

19 @return :epkg:`numpy:array` 

20 """ 

21 img = numpy.zeros((size[1], size[0]), dtype=numpy.float32) 

22 nb = int(ratio * size[0] * size[1]) 

23 xr = nprnd.randint(0, size[0] - 1, nb) 

24 yr = nprnd.randint(0, size[1] - 1, nb) 

25 img[yr, xr] = 1 

26 return img 

27 

28 

29def random_segment_image(image, lmin=0.1, lmax=1., noise=0.01, density=1.): 

30 """ 

31 Ajoute un segment aléatoire à une image. 

32 Génère des points le long d'un segment aléatoire. 

33 

34 @param image :epkg:`numpy:array` (modifié par la fonction) 

35 @param lmin taille minimal du segment 

36 @param lmax taille maximam du segment 

37 @param density nombre de pixel à tirer le long de l'axe 

38 @param noise bruit 

39 @return dictionary with *size, angle, x1, y1, x2, y2, nbpoints* 

40 """ 

41 def move_coordinate(x1, y1, x2, y2, X, Y): 

42 if x2 < 0: 

43 x1 -= x2 

44 x2 = 0 

45 x1 = min(max(x1, 0), X - 1) 

46 x2 = min(max(x2, 0), X - 1) 

47 y1 = min(max(y1, 0), Y - 1) 

48 y2 = min(max(y2, 0), Y - 1) 

49 size = int(((x1 - x2)**2 + (y1 - y2) ** 2) ** 0.5) 

50 return x1, y1, x2, y2, size 

51 

52 mind = min(image.shape) 

53 lmin = int(mind * lmin) 

54 lmax = int(mind * lmax) 

55 size = nprnd.randint(lmin, lmax) 

56 angle = nprnd.random() * math.pi # pylint: disable=E1101 

57 x1 = nprnd.randint( 

58 image.shape[1] - int(size * abs(math.cos(angle)) - 1)) 

59 y1 = nprnd.randint(image.shape[0] - int(size * math.sin(angle) - 1)) 

60 x2 = x1 + size * math.cos(angle) 

61 y2 = y1 + size * math.sin(angle) 

62 x1, y1, x2, y2, size = move_coordinate( 

63 x1, y1, x2, y2, image.shape[1], image.shape[0]) 

64 t = nprnd.randint(0, size, int(size * density)) 

65 xs = t * math.cos(angle) + x1 

66 ys = t * math.sin(angle) + x2 

67 noise = nprnd.randn( # pylint: disable=E1101 

68 xs.shape[0] * 2).reshape(xs.shape[0], 2) * noise * mind 

69 xs += noise[:, 0] 

70 ys += noise[:, 1] 

71 xs = numpy.maximum(xs, numpy.zeros(xs.shape[0])) # pylint: disable=E1111 

72 ys = numpy.maximum(ys, numpy.zeros( 

73 xs.shape[0])) # pylint: disable=E1111,E1101,E1136 

74 xs = numpy.minimum(xs, numpy.zeros( # pylint: disable=E1101,E1136 

75 xs.shape[0]) + image.shape[1] - 1) # pylint: disable=E1111,E1101,E1136 

76 ys = numpy.minimum(ys, numpy.zeros( # pylint: disable=E1101,E1136 

77 xs.shape[0]) + image.shape[0] - 1) # pylint: disable=E1111,E1101,E1136 

78 xs = xs.astype(numpy.int32) # pylint: disable=E1101 

79 ys = ys.astype(numpy.int32) # pylint: disable=E1101 

80 image[ys, xs] = 1 

81 res = dict(size=size, angle=angle, x1=x1, y1=y1, x2=x2, y2=y2, 

82 nbpoints=xs.shape[0]) # pylint: disable=E1136 

83 return res