Coverage for src/mlstatpy/image/detection_segment/detection_segment_bord.py: 91%

35 statements  

« prev     ^ index     » next       coverage.py v6.4.1, created at 2022-06-13 20:42 +0200

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

2""" 

3@file 

4@brief Ce module définit un segment qui va parcourir l'image, 

5en plus d'être un segment, cette classe inclut la dimension de l'image, 

6et une fonction repérant sur ce segment les gradients presque 

7orthogonaux à l'image. 

8""" 

9import copy 

10import numpy 

11from .geometrie import Segment, Point 

12 

13 

14class SegmentBord_Commun(Segment): 

15 """ 

16 Définit un segment allant d'un bord a un autre de l'image, 

17 la méthode importante est @see me decoupe_gradient. 

18 

19 dim est la dimension de l'image""" 

20 

21 # voir la remarque dans la classe Point a propos de __slots__ 

22 __slots__ = ("dim",) 

23 

24 def __init__(self, dim): 

25 """constructeur, definit la definition de l'image""" 

26 Segment.__init__(self, Point(0, 0), Point(0, 0)) 

27 self.dim = dim 

28 

29 def copy(self): 

30 """ 

31 Copie l'instance. 

32 """ 

33 return copy.deepcopy(self) 

34 

35 def __str__(self): 

36 """permet d'afficher le segment""" 

37 s = Segment.__str__(self) 

38 s += " -- dim -- " + self.dim.__str__() 

39 return s 

40 

41 def decoupe_gradient(self, gradient, cos_angle, ligne_gradient, seuil_norme): 

42 """ 

43 Pour un segment donne joignant deux bords de l'image, 

44 cette fonction récupère le gradient et construit une liste 

45 contenant des informations pour un pixel sur deux du segment, 

46 

47 * norme* : mémorise la norme du gradient en ce point de l'image 

48 * *pos* : mémorise la position du pixel 

49 * *aligne* : est vrai si le gradient est presque orthogonale au segment, 

50 ce resultat est relié au paramètre proba_bin, 

51 deux vecteurs sont proches en terme de direction, 

52 s'ils font partie du secteur angulaire défini par *proba_bin*. 

53 

54 Le parcours du segment commence à son origine ``self.a``, 

55 et on ajoute à chaque itération deux fois le vecteur normal 

56 jusqu'à sortir du cadre de l'image, 

57 les informations sont stockées dans ``ligne_gradient`` qui a une liste 

58 d'informations préalablement créée au debut du programme 

59 de facon à gagner du temps. 

60 """ 

61 n = self.directeur() 

62 nor = self.normal().as_array() 

63 n.scalairek(2.0) 

64 p = copy.copy(self.a) 

65 a = p.arrondi() 

66 

67 i = 0 

68 while a.x >= 0 and a.y >= 0 and a.x < self.dim.x and a.y < self.dim.y: 

69 # on recupere l'élément dans ligne ou doivent être 

70 # stockées les informations (ligne_gradient) 

71 t = ligne_gradient.info_ligne[i] 

72 

73 # on recupere le gradient de l'image au pixel a 

74 g = gradient[a.y, a.x] 

75 

76 # on calcul sa norme 

77 t.norme = (g[0] ** 2 + g[1]**2) ** 0.5 

78 

79 # on place les coordonnees du pixel dans t 

80 t.pos.x = p.x 

81 t.pos.y = p.y 

82 

83 # si la norme est positive, le gradient à une direction 

84 # on regarde s'il est dans le meme secteur angulaire (proba_bin) 

85 # que le vecteur normal au segment (nor) 

86 if t.norme > seuil_norme: 

87 t.aligne = numpy.dot(g, nor) > cos_angle * t.norme 

88 else: 

89 t.aligne = False 

90 

91 # on passe au pixel suivant 

92 p += n 

93 a = p.arrondi() # calcul de l'arrondi 

94 i += 1 

95 

96 # on indique a ligne_gradient le nombre de pixel pris en compte 

97 # ensuite, on decidera si ce segment est effectivement un segment de l'image 

98 ligne_gradient.nb = i