Voilà,j'ai essayé d'implementer l'algorithme des kmeans mais j'ai trouvé quelques difficultés surtout a propos de l'utilisation de quelques fonctions prédifinies (getGvalue(), distance()...) toute façon vous trouveriez tout au long du code les problémes que j'ai trouvé traduits par les points d'intérrogation a la fin.Et en plus il reste la procedure d'affichage de l'image segmentée que j'ai pas pu ecrire.
les étapes de l'algorithme des kmeans sont:
1. initialisation des noyaux.
2. mise à jour des clusters.
3. réévaluation des noyaux.
4. itérer les étapes 2. et 3. jusqu'à stabilisation des noyaux.
vous trouveriez dans ce qui suit le code source que j'ai pu elaborer pour l'algorithme des k means (segmentation non supervisée) commenté.
Merci pour votre aide.
//le code source:
// Le fichier KMeans.h
// KMeanClass :
class KMeanClass{
// Les attributs:
//Pixels associés à ce centre
vector<int> pixel;
//Declaration d'un vecteur oldIndex contenant les centres des classes
vector<int>oldIndex;
// Déclaration les méthodes:
public:
// Ajoute la valeur du pixel(niveau gris)au vecteur pixel
void addPixel(int);
// Calcule la moyenne pour les pixels contenus ds le vecteur pixel
void computeMean();
// retourne la 1ere valeur du vecteur 'oldIndex'
int getNiveauGris1();
// retourne les valeurs restantes du vecteur oldIndex
int getNiveauGris2();
};
class KMean{
// Les attributs:
//nbre de centres chiosis par hasard
int k;
//vecteur de classe 'KMeanclass'
vector<KMeanClass> center;
// Déclaration les méthodes:
public:
/// Execute l'algorithme
void doKMean();
//
//
};
//le fichier kmeans.cpp
// ajoute les valeurs en niveau de gris aux vecteurs 'pixel' des différentes classes center[i]
void KMeanClass::addPixel(int p){
pixel.push_back(p);
}
// retourne la 1ere valeur du vecteur oldIndex[i]
void KMeanClass::getNiveauGris1(){
return oldIndex[0];
// retourne le reste des valeurs du vecteur oldIndex[i]
void KMeanClass::getNiveauGris1(){
return oldIndex[j];
}
// la methode doKMean() permet d'initialiser d'abord le vecteur oldIndex en des centres aleatoirement choisis et affecter par la suite chaque pixel(valeur
//en niveau de gris) de l'image au centre oldIndex[] correspondant
//apres calcul des moyennes on parcourt de nouveau l'image et on reaffecte les valeurs des pixels aux nouveaux centres recalculés
void KMean::doKMean()
{
// initialisation
// initialiser librement le nbre de classes
K=?
// Choisir aleatoirement K pixels comme centres initiaux de classes* ici
on a imposé que les pixels choisis sont ceux de la diagonale*
//declaration d'un veceur qui va contenir les valeur en niveu de gris de centres
vector<int> oldIndex;
for(int i = 0; i < K; i++)
{ j=0;
// recuperer la valeur en niveux de gris d'un pixel??????
oldIndex[i]= GetGValue(Image1->Canvas->Pixels[j][i]);??????????????????????
}
// Construire les classes initiales
do{
for(j=1;j<Image1->Width;j++)
{
for(i=1;i<Image1->Height;i++)
{
int p = GetGValue(Image1->Canvas->Pixels[j][i]);????????????????????
// Index du nouveau centre;
int ndx = 0;
// Trouver la Distance minimale
float dMin = p.distance(center[0].getNiveauGris1());???????????????????????
// Parcourt de chaque centre
for(int j = 1; j < k; j++)
{
float d = p.distance(center[j].getNiveauGris2());???????????????????????????????
if(d < dMin)
{
// La distance est plus petite
dMin = d;
ndx = j;
}
}
// Ajouter la valeur de niv gris recuperee au vecteur 'pixel' de la classe center[ndx]
center[ndx].addPixel(p);
}
}
// On calcule maintenant la moyenne de chaque vecteur 'pixel' des K classes center
bool booleen=false;
for(int i = 0; i < K; i++)
{
int nouvelle_moyenne = center[i].computeMean();
// On teste est ce que l'ancien centre change
if(nouvelle_moyenne!= oldIdex[i])
{
booleen = true;
oldIdex[i]=nouvelle_moyenne ;
}
}
}While(booleen);
}
// on ecrit maintenant la méthode qui calcule la nouvelle moyenne
void KMeanClass::computeMean(){
}
// On parcourt tous les points du centre
// on recupere la taille du vecteur pixel de center[i]
int sz = pixel.size();
// Niveau de gris
// Somme courante
float v = 0.0;
// on parcourt le vecteur du center[i]
for(int i = 1; i < sz; i++)
{
int c = pixel[i];
v += c;
}
// Moyenne
v / =sz;
}
// Recherche dans la classe de la couleur existante la plus
// proche de la moyenne pour eviter une moyenne décimale(avec virgule)
if(sz > 0){
// On calcule la distance entre le 1er pixel du vecteur 'pixel' et la moyenne calculée
float dst = v.distance(pixel[0]);????????????????????????????????????
int ndx = 0;
for(int i = 1; i < sz; i++){
int c = pixel[i];
//on calcule la distance entre la moyenne et la valeur du pixel suivant dans le vector 'pixel'
float d = v.distance(c);??????????????????????????????????????
if(d < dst){
dst = d;
ndx = i;
}
}
v = pixel[ndx];
}
// On vide le vecteur 'pixel' si l'ancien centre est different du nouveau
if(v!= oldIdex[i])
{ pixel.clear();}