Problème d'édition des liens avec code::blocks [Résolu]

Messages postés
13
Date d'inscription
lundi 11 août 2008
Statut
Membre
Dernière intervention
13 décembre 2008
- - Dernière réponse : SAKingdom
Messages postés
3213
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
- 12 août 2008 à 03:20
Salut tout le monde !  je suis nouveau ici et j'espère trouver de l'aide :) alors je suis entrain d'implémenter l'algorithme "kmeans" avec opencv , j'ai bien intégrer la bibliothèque opencv sur code::blocks , au début j'ai écrit un seul fichier .cpp qui contient le main , quand le fichier commence a s'encombrer j'ai décomposé le fichier en 3 fichiers ,j'ai crée un nouveau projet et j'ai essayé d'exécuter , là je suis dans la merde !

voici le code :

//main.cpp

#include "main.h"



using namespace std;



int main()
{



    /*initialisation des images*/
    img=cvLoadImage("C:\A.bmp");
    img_nvg=cvCreateImage(cvGetSize(img), img->depth, 1);
    img_inv=cvCloneImage(img_nvg);





    //Création des fenêtres dans lesquelles nous afficherons les images
    cvNamedWindow("img",CV_WINDOW_AUTOSIZE);
    cvNamedWindow("nvg",CV_WINDOW_AUTOSIZE);
    cvNamedWindow("inv",CV_WINDOW_AUTOSIZE);




    //On vérifie l'origine de l'image chargée
    //Si elle n'est pas en haut à gauche, il faut la corriger
    int flip=0;
    if(img->origin!=IPL_ORIGIN_TL)
    {
        flip=CV_CVTIMG_FLIP;
    }


    //Conversion en niveaux de gris
    cvConvertImage(img, img_nvg, flip);




    /*initialisation des centres de classes*/
    scalaire=cvGet2D(img_nvg,0,0);
    class1=scalaire.val[0];
    scalaire=cvGet2D(img_nvg,100,200);
    class2=scalaire.val[0];


    cout<<class2 ;
    res=(img_nvg->width)*(img_nvg->height);
    matrice=allouer_matrice(2,res);
    cout << res << endl ;
    cout << img_nvg->width << "x" << img_nvg->height << endl;


 


    matrice_diff(matrice,img_nvg->width,img_nvg->height,class1,class2);


    new_centroid(matrice,img_nvg->width,img_nvg->height,class1,class2);


    creat_new_image(matrice,img_nvg->width,img_nvg->height,class1,class2);


    cout << class1 << endl << class2 << endl << endl;




    //Affichage des images


    cvShowImage("inv", img_inv);
    cvShowImage("img", img);
    cvShowImage("nvg", img_nvg);


    //On attend que l'utilisateur aie appuyé sur une touche pour continuer
    cvWaitKey(0);


    //déallocation de la mémoire allouée pour la matrice
    deallouer_matrice(matrice);


    //Destruction des fenêtres et désallocation des images.
    cvDestroyWindow("img");
    cvDestroyWindow("nvg");
    cvDestroyWindow("inv");


    cvReleaseImage(&img);
    cvReleaseImage(&img_nvg);
    cvReleaseImage(&img_inv);


    return 0;
}

//kmeans.cpp

#include "main.h"


using namespace std;


/*allocation dynamique de la matrice*/
double** allouer_matrice(int l,int c)
{
 double** pp;
 int i;


 if(!(pp=new double* [l]))
 {
        cout<< "echec de l'allocation mémoire";
  exit(1);
 }


 for(i=0;i<l;i++)
 if (!(*(pp+i)=new double [c]))
 {
        cout << "echec de l'allocation mémoire" ;
  exit(2);
 }




 return pp;
}




/*déallocation de la mémoire allouée par la matrice*/
void deallouer_matrice(double** pp)
{
 int i;
 for(i=0;i<2;i++)
  delete [] *(pp+i);


 delete [] pp;
}




/*matrice de difference*/
void matrice_diff(double** tab,int l,int c,double& c1,double& c2)
{
    long k=0;


    for(int x=0; x<l; x++)
    {
        for(int y=0; y<c; y++)
        {


            //On récupère le pixel (x,y) de l'image en niveaux de gris.
            scalaire=cvGet2D(img_nvg, y, x);


            //matrice des differences
            tab[0][k]=fabs(c1-scalaire.val[0]);
            tab[1][k]=fabs(c2-scalaire.val[0]);


            if (tab[0][k]<tab[1][k])
            {
               tab[0][k]=1;
               tab[1][k]=0;
            }
            else
            {
                tab[0][k]=0;
                tab[1][k]=1;
            }


            k++;
        }
    }
}




/*nouveaux centres de classes*/
void new_centroid(double** tab,int l,int c,double& c1,double& c2)
{
    long nb1=0;
    long nb2=0;
    long k=0;
    double som1=0;
    double som2=0;


    for(int x=0; x<l; x++)
    {
        for(int y=0; y<c; y++)
        {
            //On récupère le pixel (x,y) de l'image en niveaux de gris.
            scalaire=cvGet2D(img_nvg, y, x);
            if (tab[0][k]==1)
            {
               som1=som1+scalaire.val[0];
               nb1++;
            }
            else
            {
                som2=som2+scalaire.val[0];
                nb2++;
            }
            k++;
        }
    }


    c1=som1/nb1;
    c2=som2/nb2;
}




/*creation du nouveau image*/
void creat_new_image(double** tab,int l,int c,double& c1,double& c2)
{
    int k=0;


    for(int x=0; x<l; x++)
    {
        for(int y=0; y<c; y++)
        {
                scalaire=cvGet2D(img_nvg, y, x);
                if (tab[0][k]==1)
                scalaire.val[0]=c1;
                else
                scalaire.val[0]=c2;
                cvSet2D(img_inv, y, x, scalaire);
                k++;
        }
    }
}




//main.h

#include <cv.h>
#include <highgui.h>
#include <math.h>
#include
#include <stdlib.h>




/*Déclaration des images*/
IplImage *img=0;
IplImage *img_nvg=0;
IplImage *img_inv=0;


/*declaration des variables globeaux*/
double class1=0;
double class2=0;
long res=0;
double** matrice;
CvScalar scalaire;




/*prototypes des fonctions*/
double** allouer_matrice(int l,int c);
void deallouer_matrice(double** pp);
void matrice_diff(double** tab,int l,int c,double& c1,double& c2);
void new_centroid(double** tab,int l,int c,double& c1,double& c2);
void creat_new_image(double** tab,int l,int c,double& c1,double& c2);

je vous rappelle que le code tourne parfaitement en un seul fichier !
merci d'avance
Afficher la suite 

9 réponses

Meilleure réponse
Messages postés
3213
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
12
3
Merci
C'est que tu déclares des variables dans un header. Ces variables seront donc redéclarées dans chaque fichier source où tu incluras ton header.

Déclare tes variables en globale dans main.cpp:

//main.cpp
/*Déclaration des images*/
IplImage *img=0;
IplImage *img_nvg=0;
IplImage *img_inv=0;/*declaration des variables globeaux*/
double class1=0;
double class2=0;
long res=0;
double** matrice;
CvScalar scalaire;

puis dans ton main.h, remplace tes déclarations par:

// main.h
/*Déclaration des images*/
extern IplImage *img;
extern IplImage *img_nvg;
extern IplImage *img_inv;/*declaration des variables globeaux*/
extern double class1;
extern double class2;
extern long res;
extern double** matrice;
extern CvScalar scalaire;

C++ (@++)<!--

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 205 internautes nous ont dit merci ce mois-ci

Commenter la réponse de SAKingdom
Messages postés
3213
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
12
3
Merci
Sauf exceptions, un header ne peut contenir quelque chose qui a une déclaration (tel une fonction ou une variable), car sitôt que ton header est inclut plus d'un fichier, tes variables (et fonctions) sont redéclarées dans chacun d'eux.

En ajoutant le mot clé extern devant le nom de ta variable, on indique qu'elle se trouve dans un autre fichier. La variables n'est donc pas redéclarée et c'est l'éditeur de liens qui se chargera de "faire le lien" vers la variable.

Pour une fonction, on déclare le prototype. Même principe.

C++ (@++)<!--

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 205 internautes nous ont dit merci ce mois-ci

Commenter la réponse de SAKingdom
Messages postés
338
Date d'inscription
samedi 9 août 2003
Statut
Membre
Dernière intervention
9 juillet 2011
2
0
Merci
peux tu affichés les erreurs que tu recois pour facilement voir ou sont-elles
Commenter la réponse de gamemonde
Messages postés
338
Date d'inscription
samedi 9 août 2003
Statut
Membre
Dernière intervention
9 juillet 2011
2
0
Merci
/*Déclaration des images*/
IplImage *img=0;
IplImage *img_nvg=0;
IplImage *img_inv=0;

ca peux-tu êtres du genre declarations deja fais dans le fichier *.obj
tu dois mettre la protection anti inclusion multible

#ifndef MAIN_H
#define MAIN_H
..... ton code
#endif
Commenter la réponse de gamemonde
Messages postés
13
Date d'inscription
lundi 11 août 2008
Statut
Membre
Dernière intervention
13 décembre 2008
0
Merci
oui biensure , en tout cas merci !

Linking console executable: bin\Release\kmeans.exe

obj\Release\kmeans.o(.bss+0x0):kmeans.cpp: multiple definition of `scalaire'

obj\Release\main.o(.bss+0x0):main.cpp: first defined here

obj\Release\kmeans.o(.bss+0x20):kmeans.cpp: multiple definition of `matrice'

obj\Release\main.o(.bss+0x20):main.cpp: first defined here

obj\Release\kmeans.o(.bss+0x24):kmeans.cpp: multiple definition of `res'

obj\Release\main.o(.bss+0x24):main.cpp: first defined here

obj\Release\kmeans.o(.bss+0x28):kmeans.cpp: multiple definition of `class2'

obj\Release\main.o(.bss+0x28):main.cpp: first defined here

obj\Release\kmeans.o(.bss+0x30):kmeans.cpp: multiple definition of `class1'

obj\Release\main.o(.bss+0x30):main.cpp: first defined here

obj\Release\kmeans.o(.bss+0x38):kmeans.cpp: multiple definition of `img_inv'

obj\Release\main.o(.bss+0x38):main.cpp: first defined here

obj\Release\kmeans.o(.bss+0x3c):kmeans.cpp: multiple definition of `img_nvg'

obj\Release\main.o(.bss+0x3c):main.cpp: first defined here

obj\Release\kmeans.o(.bss+0x40):kmeans.cpp: multiple definition of `img'

obj\Release\main.o(.bss+0x40):main.cpp: first defined here

collect2: ld returned 1 exit status


 
Commenter la réponse de walidoss1
Messages postés
13
Date d'inscription
lundi 11 août 2008
Statut
Membre
Dernière intervention
13 décembre 2008
0
Merci
voila les erreurs , ça vous dit quelque chose ?
j'ai essayé la protection anti inclusion multiple mais  ... prière de m'aider si vous pouvez , je suis bloqué , je ne plus avancer dans mon projet  

merci en tout cas  
Commenter la réponse de walidoss1
Messages postés
338
Date d'inscription
samedi 9 août 2003
Statut
Membre
Dernière intervention
9 juillet 2011
2
0
Merci
#ifndef MAIN_H
#define MAIN_H

//main.h

#include <cv.h>
#include <highgui.h>
#include <math.h>
#include
#include <stdlib.h>

/*Déclaration des images*/
IplImage *img=0;
IplImage *img_nvg=0;
IplImage *img_inv=0;

/*declaration des variables globeaux*/
double class1=0;
double class2=0;
long res=0;
double** matrice;
CvScalar scalaire;

/*prototypes des fonctions*/
double** allouer_matrice(int l,int c);
void deallouer_matrice(double** pp);
void matrice_diff(double** tab,int l,int c,double& c1,double& c2);
void new_centroid(double** tab,int l,int c,double& c1,double& c2);
void creat_new_image(double** tab,int l,int c,double& c1,double& c2);

#endif

essai cela!!!
Commenter la réponse de gamemonde
Messages postés
13
Date d'inscription
lundi 11 août 2008
Statut
Membre
Dernière intervention
13 décembre 2008
0
Merci
merci bien ! j'ai essayé , mais sans succes ! meme erreurs
Commenter la réponse de walidoss1
Messages postés
13
Date d'inscription
lundi 11 août 2008
Statut
Membre
Dernière intervention
13 décembre 2008
0
Merci
un grand merci !! c fantastique !! ca tourne ! waaw !
pffff ! maintenant je peux dormir :)
en fait j'ai pa bien assimiler ! mais pourquoi le header doit contenir les declarations des variables.
où je peux trouver des liens a propos de l'edition des liens ?
merci encore !
Commenter la réponse de walidoss1