Problème d'édition des liens avec code::blocks

Résolu
walidoss1 Messages postés 13 Date d'inscription lundi 11 août 2008 Statut Membre Dernière intervention 13 décembre 2008 - 12 août 2008 à 00:25
SAKingdom Messages postés 3212 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

9 réponses

SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
12 août 2008 à 02:22
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++ (@++)<!--
3
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
12 août 2008 à 03:20
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++ (@++)<!--
3
gamemonde Messages postés 336 Date d'inscription samedi 9 août 2003 Statut Membre Dernière intervention 9 juillet 2011 2
12 août 2008 à 00:50
peux tu affichés les erreurs que tu recois pour facilement voir ou sont-elles
0
gamemonde Messages postés 336 Date d'inscription samedi 9 août 2003 Statut Membre Dernière intervention 9 juillet 2011 2
12 août 2008 à 00:52
/*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
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
walidoss1 Messages postés 13 Date d'inscription lundi 11 août 2008 Statut Membre Dernière intervention 13 décembre 2008
12 août 2008 à 00:54
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


 
0
walidoss1 Messages postés 13 Date d'inscription lundi 11 août 2008 Statut Membre Dernière intervention 13 décembre 2008
12 août 2008 à 01:12
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  
0
gamemonde Messages postés 336 Date d'inscription samedi 9 août 2003 Statut Membre Dernière intervention 9 juillet 2011 2
12 août 2008 à 01:58
#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!!!
0
walidoss1 Messages postés 13 Date d'inscription lundi 11 août 2008 Statut Membre Dernière intervention 13 décembre 2008
12 août 2008 à 02:16
merci bien ! j'ai essayé , mais sans succes ! meme erreurs
0
walidoss1 Messages postés 13 Date d'inscription lundi 11 août 2008 Statut Membre Dernière intervention 13 décembre 2008
12 août 2008 à 02:36
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 !
0
Rejoignez-nous