Bonjour à tous ,

J'essaie d'implémenter K-means pour segmenter une image couleur.Mais , ça ne marche pas .

En effet, j'ai utilisé les structures de données suivantes:
-3 tableaux rouge , vert , bleu pour stocker les valeurs rgb pour chaque pixel
-3 tableaux cluster_bleu, cluster_rouge, rouge_vert pour stocker les valeurs rgb pour chaque cluster
-un tableau groupe qui mappe chaque pixel i à un cluster k

Je me demande si vous pouvez suggérer quelques modifications sur mon code pour corriger le problème .

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
import cv2
import numpy
import random
 
def main():
    MAX_LARGEUR = 400
    MAX_HAUTEUR = 400
 
    K = 32 #Le fameux parametre K de l'algorithme
 
 
 
    # Charger l'image et la reduire si trop grande (sinon, on risque de passer trop de temps sur le calcul...)
    imagecolor = cv2.imread('perr.jpg')
 
    if imagecolor.shape[0] > MAX_LARGEUR or imagecolor.shape[1] > MAX_HAUTEUR:
        factor1 = float(MAX_LARGEUR) / imagecolor.shape[0]
        factor2 = float(MAX_HAUTEUR) / imagecolor.shape[1]
        factor = min(factor1, factor2)
        imagecolor = cv2.resize(imagecolor, None, fx=factor, fy=factor, interpolation=cv2.INTER_AREA)
 
 
 
 
    # Le nombre de pixels de l'image
    nb_pixels = imagecolor.shape[0] * imagecolor.shape[1]
 
 
 
    # On affiche une fenetre avec l'image
    #cv2.namedWindow("image")
    #On sort quand l'utilisateur appuie sur une touche
    #cv2.imshow("image", imagecolor)
    #key = cv2.waitKey(0)
 
 
    #Les coordonnees BRV de tous les pixels de l'image (les elements de E)
    bleu = imagecolor[:, :, 0].reshape(nb_pixels, 1)
    vert = imagecolor[:, :, 1].reshape(nb_pixels, 1)
    rouge = imagecolor[:, :, 2].reshape(nb_pixels, 1)
 
 
 
 
    #Les coordonnees BRV de chaque point-cluster (les elements de N)
    cluster_bleu = numpy.zeros(K)
    cluster_vert = numpy.zeros(K)
    cluster_rouge = numpy.zeros(K)
 
 
    #Ce tableau permet de connaitre, pour chaque pixel de l'image, a quel cluster il appartient
    #On le remplit au hasard
    groupe = numpy.zeros((nb_pixels, 1)) #groupe est un tableau de Card(E) cases, et chaque valeur est un entier entre 0 et K-1, designant 	le   cluster auquel chaque point sera rattache
    #On remplit au hasard le tableau groupe, c'est a dire que l'on attribue au hasard chaque point de l'espace a un des K clusters
    #Cependant, pour etre sur qu'au depart chaque cluster est rattache a au moins un point de l'espace, on attribue les K premiers points de  		l'espace a chaque K clusters
 
    for i in range(0,K):
        groupe[i,0]=i
 
 
    #La, on fait l'attribution du reste des points de l'espace a des clusters choisis au hasard
 
 
    for i in range(K,nb_pixels):
        groupe[i,0]=random.randint(0, K-1)
 
 
 
 
 
    condition =False;
 
 
    print 'entree execution '	
 
    def etape1(indices,i):
	s=indices.size
	rouge_s=0
	vert_s=0
	bleu_s=0
	#calcul de barycentre des points
	if s==0:
		cluster_rouge[i]=0	
		cluster_vert[i]=0
		cluster_bleu[i]=0
 
 
	if s >=1:
		for j in range(0,s):
			rouge_s=rouge_s+rouge[indices[j]]
			vert_s=vert_s+vert[indices[j]]
			bleu_s=bleu_s+bleu[indices[j]]
 
		#mise  jour des clusters 
 
		cluster_rouge[i]=rouge_s/s	
		cluster_vert[i]=vert_s/s
		cluster_bleu[i]=bleu_s/s		
 
 
 
    oldGroupe = numpy.copy(groupe)
    while(condition==False) :
 
#Etape 1 deplacer le centroid sur le barycentre des points qui lui sont associes
	for i in range(0,K):
		#les pixels qui sont associes au cluster numero i
		indices=numpy.where(groupe==i)[0]
		etape1(indices,i)
 
	#fin etape 2
 
	for i in range(0,nb_pixels):
		minimum=10000;
		dist=0;
		index=-1;
		for j in range(0,K):
			 dist=(cluster_rouge[j]-rouge[i])**2+(cluster_vert[j]-vert[i])**2+(cluster_bleu[j]-bleu[i])**2;
			 if(dist<=minimum):
				minimum=dist;
				index=j;
 
 
	#mise a jour de groupe
		groupe[i,0]=index;
 
 
	#condition d'arret
 
	condition=numpy.all(groupe==oldGroupe)
 
	oldGroupe = numpy.copy(groupe)	
 
 
 
 
 
 
    #Fin de algo, on affiche les resultats
 
    #On change le format de groupe afin de le rammener au format de l'image d'origine
 
 
 
    groupe=numpy.reshape(groupe, (imagecolor.shape[0], imagecolor.shape[1]))
 
    #On change chaque pixel de l'image selon le cluster auquel il appartient
    #Il prendre comme nouvelle valeur la position moyenne du cluster
 
 
    for i in range(0, imagecolor.shape[0]):
        for j in range(0, imagecolor.shape[1]):
            imagecolor[i,j,0] = (cluster_bleu[groupe[i,j]])
            imagecolor[i,j,1] = (cluster_vert[groupe[i,j]])
            imagecolor[i,j,2] = (cluster_rouge[groupe[i,j]])
 
 
 
 
 
    cv2.namedWindow("sortie")
 
    cv2.imshow("sortie", imagecolor)
    key = cv2.waitKey(0)
 
 
 
 
if __name__ == "__main__":
    main()