IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Introduction d'un buffer circulaire dans un code deja existant


Sujet :

C

  1. #1
    Membre chevronné
    Homme Profil pro
    Cadre informatique
    Inscrit en
    Avril 2013
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Cadre informatique

    Informations forums :
    Inscription : Avril 2013
    Messages : 183
    Par défaut Introduction d'un buffer circulaire dans un code deja existant
    Bonjour à tous,

    Je dois faire un programme pour mes études qui recoit un flux d'images d'une caméra. Je dois les traiter pour trouver centre de gravité, modelisation d'une ellipse et l'angle d'orientation du corps.
    Voila le code deja fait, tout marche meme si c'est pas tres optimisé (je suis ouvert a toutes suggestions bien sur ^^)
    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
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include "header.h"
     
    #define MIN(a,b) ( (a)<(b) ? (a):(b) ) //Macro pour le calcul du minimum de 2 nombres
    #define MAX(a,b) ( (a)>(b) ? (a):(b) ) //Macro pour le calcul du maximum de 2 nombres
     
    // Image definié en 16:9e pour tests
    #define M 9 //Nombre de lignes de l'image
    #define N 16 //Nombre de colonnes de l'image
    // Valeur arbitraire pour les couleurs de l'image (noir et blanc)
    // A remplacer par les valeurs données par le groupe 1
    #define val_noir 0
    #define val_blanc 1
     
    // Toutes les variables pour chaque image
    typedef struct
    {
        int t[M][N]; //Image stockée
        int gX, gY;  //Coordonnées du centre de gravité
        int gAxe[2], pAxe[2];  //Coordonnées des points a et b dans l'ellipse
        float theta; //Angle d'inclinaison du corps
    } Image;
     
    // Fonction de calcul du Plus Grand Commun Diviseur de 2 nombres
    int PGCD(int a, int b)
    {
        while(b!=0)
        {
            if( a>=0 && b>=0 )
            {
                int c=a%b;
                a=b;
                b=c;
            }
            else
            {
                if(a<0) a=-a;
                if(b<0) b=-b;
            }
        }
        return a;
    }
     
    // Fonction de calcul de Tout les Communs Diviseurs à partir du PGCD
    void TCD(int *t, int val)
    {
        int i=2, k=1;
        while( i<=val )
        {
            if( !(val%i) )
            {
                t[k]=i;
                k++;
            }
            i++;
        }
        t[0]=k-1;
    }
     
    // Fonction de calcul du centre de gravité par la
    // methode des moments geometriques
    void pointG(Image *img)
    {
        int i, j;
        int m00=0, m10=0, m01=0;
        for (i=0; i<M; i++)
        {
            for (j=0; j<N; j++)
            {
                if(img->t[i][j] == val_blanc)
                {
                    m00++;
                    m10+=i;
                    m01+=j;
                }
            }
        }
        img->gX=(int)( m10/m00 );
        img->gY=(int)( m01/m00 );
    }
     
    /*
    // Fonctin de calcul du centre de gravité par une
    // methode personnelle
    void pointG(Image *img)
    {
        int i, j;
        int Xmin=M, Xmax=0, Ymin=N, Ymax=0;
     
        for (i=0; i<M; i++)
        {
            for (j=0; j<N; j++)
            {
                if(img->t[i][j] == val_blanc)
                {
                    Xmin=MIN(Xmin, i);
                    Ymin=MIN(Ymin, j);
                    Xmax=MAX(Xmax, i);
                    Ymax=MAX(Ymax, j);
                }
            }
        }
        img->gX=(int)( (Xmin+Xmax)/2 );
        img->gY=(int)( (Ymin+Ymax)/2 );
    }
    */
    // Fonction de calcul du grand axe de l'ellipse via la plus grande
    // distance par rapport au centre de gravité
    void grandAxe(Image *img)
    {
        int i, j;
        float dist=0, tmp=0;
        for (i=0; i<=img->gX; i++)
        {
            for (j=0; j<N; j++)
            {
                if(img->t[i][j] == val_blanc)
                {
                    tmp=sqrt( pow(abs(i-img->gX), 2) + pow(abs(j-img->gY), 2) );
                    if( tmp>dist )
                    {
                        dist=tmp;
                        img->gAxe[0]=i;
                        img->gAxe[1]=j;
                    }
                }
            }
        }
    }
     
    // Fonction de calcul du petit axe de l'ellipse via le calcul des TCD
    // et de la perpendicularité des 2 axes
    void petitAxe(Image *img)
    {
        int i, tmpI, tmpJ;
        int tcd[ PGCD( (img->gAxe[0] - img->gX) , (img->gAxe[1] - img->gY) ) ];
     
        TCD(tcd, PGCD( (img->gAxe[0] - img->gX) , (img->gAxe[1] - img->gY) ));
     
        if( tcd[0]==0 || tcd[0]==1 )
        {
            img->pAxe[0]=img->gX;
            img->pAxe[1]=img->gY;
        }
        else
        {
            for(i=1; i<=tcd[0]; i++)
            {
                tmpI = (int)(img->gAxe[0]/tcd[i]);
                tmpJ = (int)(img->gAxe[1]/tcd[i]);
                if( img->t[tmpI][tmpJ] == val_blanc )
                {
                    img->pAxe[0]=img->gX - tmpI;
                    img->pAxe[1]=img->gY - tmpJ;
                }
            }
        }
    }
     
    // Fonction de calcul de théta, angle entre l'axe des ordonnées et
    // l'orientation du grand axe de l'ellipse
    void valTheta(Image* img)
    {
        int i, j;
        float num=0, den1=0, den2=0;
        for(i=0; i<M; i++)
        {
            for(j=0; j<N; j++)
            {
                if( img->t[i][j] == val_blanc )
                {
                    num += i*j;
                    den1 += pow(i,2);
                    den2 += pow(j,2);
                }
            }
        }
        img->theta=(180*atan(2*num/(den1-den2)))/M_PI;
        if(img->theta < 0) img->theta = -img->theta;
    }
     
    // A voir pour les taches
    int main(int argc, char *argv[])
    {
        Image image={  {0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,
                        0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,
                        0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,
                        0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,
                        0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,
                        0,0,1,0,0,1,1,1,1,0,0,0,0,0,0,0,
                        0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,
                        0,0,0,1,1,0,0,0,0,1,0,0,0,0,0,0,
                        0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0},
                        {0},{0},{0,0},{0,0},{0} };
       o int i, j;
        for(i=0; i<M; i++)
        {
            for(j=0; j<N; j++)
            {
                printf("%d ", image.t[i][j]);
            }
            printf("\n");
        }
     
        pointG(&image);
        grandAxe(&image);
        petitAxe(&image);
        valTheta(&image);
     
        printf("\nCoordonnees de G: %d-%d\n", image.gX, image.gY);
        printf("\nCoordonnees de a: %d-%d\n", image.gAxe[0], image.gAxe[1]);
        printf("\nCoordonnees de b: %d-%d\n", image.pAxe[0], image.pAxe[1]);
        printf("\nValeur de l'angle theta: %f\n", image.theta);
     
        return 0;
    }
    Et voici le code que j'ai trouvé sur ce site mais j'ai du mal a l'integrer.
    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
     
    #include <stdio.h>
    #include <stdlib.h>
     
    typedef struct
    {
    	void *buffer; // mon buffer
    	void *buffer_end; // fin de mon buffer
    	size_t capacity; // max d'items dans le buffer
    	size_t count; // nbre actuel d'items dans le buffer
    	size_t sz; // taille de chaque item dans le buffer
    	void *head; // pointeur vers le début (head)
    	void *tail; // pointeur vers la fin (tail)
    } c_buff;
     
    void cb_init(c_buff *cb, size_t capacity, size_t sz)
    {
    	cb->buffer = malloc(capacity * sz);
    	if(cb->buffer == NULL)
    		// handle error
    	cb->buffer_end = (char *)cb->buffer + capacity * sz;
    	cb->capacity = capacity;
    	cb->count=0;
    	cb->sz = sz;
    	cb->head = cb->buffer;
    	cb->tail = cb->buffer;
    }
     
    void cb_free(c_buff *cb)
    {
    	free(cb->buffer)
    	// on free tous les autres champs pour etre safe
    }
     
    void cb_push_back(c_buff *cb, const void *item)
    {
    	if(cb->count == cb->capacity)
    		// handle error
    	memcpy(cb->head, item, cb->sz);
    	cb->head = (char *)cb->head + cb->sz;
    	if(cb->head == cb->buffer_end)
    		cb->head = cb->buffer
    	(cb->count)++;
    }
     
    void cb_pop_front(c_buff *cb, void *item)
    {
    	if(cb->count == 0)
    		// handle error
    	memcpy(item, cb->tail, cb->sz);
    	cb->tail = (char *)cb->tail + cb->sz;
    	if(cb->tail == cb->buffer_end)
    		cb->tail = cb->buffer;
    	(cb->count)++;
    }
    Si vous pouviez m'aider, je vous en serai reconnaissant et il faut que je vous dise, je suis un néophyte en C ^^

  2. #2
    Membre chevronné
    Homme Profil pro
    Cadre informatique
    Inscrit en
    Avril 2013
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Cadre informatique

    Informations forums :
    Inscription : Avril 2013
    Messages : 183
    Par défaut
    Peut etre devrais je tout integrer dans un seul et unique programme?
    Pour le moment j'avais prevu de modifier le buffer circulaire pour coller a mon programme mais je sais pas trop par ou commencer...

  3. #3
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    Bonsoir,

    Bon en lisant en diagonale je dirais qu'il y a une erreur dans le code que tu as récupéré car à vue de nez il n'y a que des (cb->count)++ et jamais aucun (cb->count)-- (certainement à changer en ligne 54).

    Mis-à-part ça, l'utilisation semble assez classique au détail près qu'il te manque le header qui pourrait être :
    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
    #ifndef c_buff_h__
    #define c_buff_h__
     
    typedef struct
    {
    	void *buffer; // mon buffer
    	void *buffer_end; // fin de mon buffer
    	size_t capacity; // max d'items dans le buffer
    	size_t count; // nbre actuel d'items dans le buffer
    	size_t sz; // taille de chaque item dans le buffer
    	void *head; // pointeur vers le début (head)
    	void *tail; // pointeur vers la fin (tail)
    } c_buff;
     
    void cb_init(c_buff *cb, size_t capacity, size_t sz);
    void cb_free(c_buff *cb);
    void cb_push_back(c_buff *cb, const void *item);
    void cb_pop_front(c_buff *cb, void *item);
     
    #endif /* c_buff_h__ */
    Dans le source il faudra en lignes 38 et 49 ajouter ta gestion des erreurs (resp. buffer overflow et buffer underflow) ... ça se réduit souvent à un fprintf sur stderr et un exit(EXIT_FAILURE).

    Pour l'utiliser par exemple comme buffer circulaire avec le type Image :
    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
    #include "c_buff.h"
     
    ...
     
    int main()
    {
      c_buff buffer;
      Image une_image;
     
      // on initialiser le buffer pour qu'il puisse contenir au maximum
      // 10 images
      cb_init(&buffer, 10, sizeof(Image));
     
      // Pour copier une image dans le buffer
      cb_push_back(&buffer, &une_image);
     
      // Pour copier l'image de tête du buffer dans ta variable
      cb_pop_front(&buffer, &une_image);
     
      // Une fois que tu n'as plus besoin de ton buffer
      cb_free(&buffer);
     
      ...
     
      return 0;
    }
    Je pense que l'idéal pour toi serait de réécrire le code du buffer circulaire (ce n'est ni très long ni trop difficile) et éventuellement de le partager ici


    EDIT: En cherchant dans les sources ici j'ai trouvé l'implémentation de Diogène qui est de bien meilleure qualité : Buffer Circulaire.

  4. #4
    Membre chevronné
    Homme Profil pro
    Cadre informatique
    Inscrit en
    Avril 2013
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Cadre informatique

    Informations forums :
    Inscription : Avril 2013
    Messages : 183
    Par défaut
    Merci beaucoup, je vais voir ce que je peux faire et je repost ici des que j'aurais avancé.
    Merci!!!!

  5. #5
    Membre chevronné
    Homme Profil pro
    Cadre informatique
    Inscrit en
    Avril 2013
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Cadre informatique

    Informations forums :
    Inscription : Avril 2013
    Messages : 183
    Par défaut
    Juste comme ça, quel est l'interet du size_t?

  6. #6
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    size_t est un typedef d'un type entier non signé. Il est utilisé dès qu'on a besoin de représenter une taille en octet. Suivant ta plateforme les tailles maximum peuvent varier, par exemple il est courant qu'un système 32bits ne puisse pas gérer des tailles supérieures à 2^32-1, alors que cette taille est de 2^64-1 octets pour les systèmes 64bits. Le typedef différera donc suivant la plateforme utilisée. Mais tu as la garantie que size_t est suffisamment large pour contenir n'importe quelle taille gérable par l'os (bon c'est une approximation mais c'est relativement exact). C'est également le type renvoyé par l'opérateur sizeof.
    Tu vas me dire que si on ne connaît pas vraiment la taille de size_t on pourrait avoir du mal à l'afficher par exemple avec un printf ... c'est pas faux Néanmoins tu as à ta disposition le modificateur z qui permet de prévenir le printf que l'entier qui est donné en paramètre doit être considéré comme un size_t ; par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include <stdio.h>
     
    int main()
    {
      size_t sz=15000;
     
      printf("%zu\n", sz);
     
      return 0;
    }
    La version signée de size_t est ssize_t.

  7. #7
    Membre chevronné
    Homme Profil pro
    Cadre informatique
    Inscrit en
    Avril 2013
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Cadre informatique

    Informations forums :
    Inscription : Avril 2013
    Messages : 183
    Par défaut
    Petit UP pour dire que j'avance, j'avance... à reculons mais je bosse.

    Je pense que je vais envoyer mon code d'ici ce week end. Parce que je galère

  8. #8
    Membre chevronné
    Homme Profil pro
    Cadre informatique
    Inscrit en
    Avril 2013
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Cadre informatique

    Informations forums :
    Inscription : Avril 2013
    Messages : 183
    Par défaut
    Salut tout le monde,

    J'ai un gros souci, j'ai essayer de réécrire ce buffer circulaire à ma façon ^^
    Mais j'ai un souci pour la suite...

    J'arrive pas a entrer mon Image dans le buffer. Pourtant, j'ai pas l'impression de me planter tant que sa...

    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
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
     
    #define MIN(a,b) ( (a)<(b) ? (a):(b) ) //Macro pour le calcul du minimum de 2 nombres
    #define MAX(a,b) ( (a)>(b) ? (a):(b) ) //Macro pour le calcul du maximum de 2 nombres
     
    // Image definié en 16:9e pour tests
    #define M 9 //Nombre de lignes de l'image
    #define N 16 //Nombre de colonnes de l'image
    // Valeur arbitraire pour les couleurs de l'image (noir et blanc)
    // A remplacer par les valeurs données par le groupe 1
    #define val_noir 0
    #define val_blanc 1
    // Valeur arbitraire pour le nombre d'images traitees en une seule
    // fois par la Cmotion
    #define taille_buffer 20
     
    // Toutes les variables pour chaque image
    typedef struct
    {
        int t[M][N]; //Image stockée
        int gX, gY;  //Coordonnées du centre de gravité
        int gAxe[2], pAxe[2];  //Coordonnées des points a et b dans l'ellipse
        float theta; //Angle d'inclinaison du corps
    } Image;
     
    // Toutes les variables pour le buffer circulaire
    typedef struct
    {
    	Image *buffer; // Mon buffer
    	Image *buffer_debut; // Pointeur vers le premier element
    	Image *courant; // Pointeur vers l'élément courant
    	Image *buffer_fin; // Pointeur vers le dernier element
    	int buffer_plein;
    } c_buff;
     
    // Fonction de calcul du Plus Grand Commun Diviseur de 2 nombres
    int PGCD(int a, int b)
    {
        while(b!=0)
        {
            if( a>=0 && b>=0 )
            {
                int c=a%b;
                a=b;
                b=c;
            }
            else
            {
                if(a<0) a=-a;
                if(b<0) b=-b;
            }
        }
        return a;
    }
     
    // Fonction de calcul de Tout les Communs Diviseurs à partir du PGCD
    void TCD(int *t, int val)
    {
        int i=2, k=1;
        while( i<=val )
        {
            if( !(val%i) )
            {
                t[k]=i;
                k++;
            }
            i++;
        }
        t[0]=k-1;
    }
     
    // Fonction de calcul du centre de gravité par la
    // methode des moments geometriques
    void pointG(Image *img)
    {
        int i, j;
        int m00=0, m10=0, m01=0;
        for (i=0; i<M; i++)
        {
            for (j=0; j<N; j++)
            {
                if(img->t[i][j] == val_blanc)
                {
                    m00++;
                    m10+=i;
                    m01+=j;
                }
            }
        }
        img->gX=(int)( m10/m00 );
        img->gY=(int)( m01/m00 );
    }
     
    /*
    // Fonctin de calcul du centre de gravité par une
    // methode personnelle
    void pointG(Image *img)
    {
        int i, j;
        int Xmin=M, Xmax=0, Ymin=N, Ymax=0;
     
        for (i=0; i<M; i++)
        {
            for (j=0; j<N; j++)
            {
                if(img->t[i][j] == val_blanc)
                {
                    Xmin=MIN(Xmin, i);
                    Ymin=MIN(Ymin, j);
                    Xmax=MAX(Xmax, i);
                    Ymax=MAX(Ymax, j);
                }
            }
        }
        img->gX=(int)( (Xmin+Xmax)/2 );
        img->gY=(int)( (Ymin+Ymax)/2 );
    }
    */
    // Fonction de calcul du grand axe de l'ellipse via la plus grande
    // distance par rapport au centre de gravité
    void grandAxe(Image *img)
    {
        int i, j;
        float dist=0, tmp=0;
        for (i=0; i<=img->gX; i++)
        {
            for (j=0; j<N; j++)
            {
                if(img->t[i][j] == val_blanc)
                {
                    tmp=sqrt( pow(abs(i-img->gX), 2) + pow(abs(j-img->gY), 2) );
                    if( tmp>dist )
                    {
                        dist=tmp;
                        img->gAxe[0]=i;
                        img->gAxe[1]=j;
                    }
                }
            }
        }
    }
     
    // Fonction de calcul du petit axe de l'ellipse via le calcul des TCD
    // et de la perpendicularité des 2 axes
    void petitAxe(Image *img)
    {
        int i, tmpI, tmpJ;
        int tcd[ PGCD( (img->gAxe[0] - img->gX) , (img->gAxe[1] - img->gY) ) ];
     
        TCD(tcd, PGCD( (img->gAxe[0] - img->gX) , (img->gAxe[1] - img->gY) ));
     
        if( tcd[0]==0 || tcd[0]==1 )
        {
            img->pAxe[0]=img->gX;
            img->pAxe[1]=img->gY;
        }
        else
        {
            for(i=1; i<=tcd[0]; i++)
            {
                tmpI = (int)(img->gAxe[0]/tcd[i]);
                tmpJ = (int)(img->gAxe[1]/tcd[i]);
                if( img->t[tmpI][tmpJ] == val_blanc )
                {
                    img->pAxe[0]=img->gX - tmpI;
                    img->pAxe[1]=img->gY - tmpJ;
                }
            }
        }
    }
     
    // Fonction de calcul de théta, angle entre l'axe des ordonnées et
    // l'orientation du grand axe de l'ellipse
    void valTheta(Image* img)
    {
        int i, j;
        float num=0, den1=0, den2=0;
        for(i=0; i<M; i++)
        {
            for(j=0; j<N; j++)
            {
                if( img->t[i][j] == val_blanc )
                {
                    num += i*j;
                    den1 += pow(i,2);
                    den2 += pow(j,2);
                }
            }
        }
        img->theta=(180*atan(2*num/(den1-den2)))/M_PI;
        if(img->theta < 0) img->theta = -img->theta;
    }
     
     
    // Fonction d'initialisation du buffer circulaire
    void cb_init(c_buff *cb)
    {
        cb->buffer = malloc(taille_buffer*sizeof(Image));
     
        cb->courant = cb->buffer;
        cb->buffer_fin = cb->buffer;
        cb->buffer_plein=0;
    }
     
    // Fonction a mettre en fin de programme pour eviter
    // les fuites de memoires dues au malloc du buffer circulaire
    void cb_free(c_buff *cb)
    {
    	free(cb->buffer);
    }
     
    // Fonction d'insertion de l'image dans le buffer circulaire
    void insert_Image(c_buff *cb, Image *img)
    {
        pointG(&img);
        grandAxe(&img);
        petitAxe(&img);
        valTheta(&img);
     
        printf("%p %p\n", cb->courant, img);
        *(cb->courant) = *img;
        printf("%p %p\n", cb->courant, img);
     
        if(cb->courant == cb->buffer_fin)
            cb->buffer_plein=1;
     
        if(cb->courant == cb->buffer_fin)
        {
            cb->courant = cb->buffer_debut;
        }
        else
        {
            cb->courant += sizeof(Image);
        }
    }
     
    // Fonction de calcul
    /*void lectureBuffer(c_buff *cb)
    {
        if(cb->buffer_plein)
        {
            int i;
            for(i=0; i<taille_buffer; i++)
            {
                faire quelque chose xD;
            }
        }
    }*/
     
    int main(int argc, char *argv[])
    {
        Image image={  {0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,
                        0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,
                        0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,
                        0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,
                        0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,
                        0,0,1,0,0,1,1,1,1,0,0,0,0,0,0,0,
                        0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,
                        0,0,0,1,1,0,0,0,0,1,0,0,0,0,0,0,
                        0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0},
                        {0},{0},{0,0},{0,0},{0} };
        c_buff cb;
        cb_init(&cb);
     
        int i, j;
        for(i=0; i<M; i++)
        {
            for(j=0; j<N; j++)
            {
                printf("%d ", image.t[i][j]);
            }
            printf("\n");
        }
     
        insert_Image(&cb, &image);
     
        printf("\nCoordonnees de G: %d-%d\n", image.gX, image.gY);
        printf("\nCoordonnees de a: %d-%d\n", image.gAxe[0], image.gAxe[1]);
        printf("\nCoordonnees de b: %d-%d\n", image.pAxe[0], image.pAxe[1]);
        printf("\nValeur de l'angle theta: %f\n", image.theta);
     
        cb_free(&cb);
        return 0;
    }

  9. #9
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    Bonjour,

    il y a plusieurs choses à dire sur ton code. Mais la première question que je me pose est pourquoi ne pas avoir utilisé le code de Diogène ? Enfin peu importe ...

    Commençons par les warnings émis lors de la compilation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    img.c: In function ‘insert_Image’:
    img.c:217:3: warning: passing argument 1 of ‘pointG’ from incompatible pointer type [enabled by default]
    img.c:76:6: note: expected ‘struct Image *’ but argument is of type ‘struct Image **’
    img.c:218:3: warning: passing argument 1 of ‘grandAxe’ from incompatible pointer type [enabled by default]
    img.c:123:6: note: expected ‘struct Image *’ but argument is of type ‘struct Image **’
    img.c:219:3: warning: passing argument 1 of ‘petitAxe’ from incompatible pointer type [enabled by default]
    img.c:147:6: note: expected ‘struct Image *’ but argument is of type ‘struct Image **’
    img.c:220:3: warning: passing argument 1 of ‘valTheta’ from incompatible pointer type [enabled by default]
    img.c:176:6: note: expected ‘struct Image *’ but argument is of type ‘struct Image **’
    Cela correspond au morceau de code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void insert_Image(c_buff *cb, Image *img)
    {
      pointG(&img);
      grandAxe(&img);
      petitAxe(&img);
      valTheta(&img);
    Et les fonctions impactées ont pour prototype :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void pointG(Image *img)
    void grandAxe(Image *img)
    void petitAxe(Image *img)
    void valTheta(Image* img)
    Tu vois ton erreur, car là les warnings pointent une erreur réelle ?

    Suite des warnings :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    img.c:254:3: warning: missing braces around initializer [-Wmissing-braces]
    img.c:254:3: warning: (near initialization for ‘image.t[0]) [-Wmissing-braces]
    img.c:263:4: warning: braces around scalar initializer [enabled by default]
    img.c:263:4: warning: (near initialization for ‘image.gX’) [enabled by default]
    img.c:263:4: warning: braces around scalar initializer [enabled by default]
    img.c:263:4: warning: (near initialization for ‘image.gY’) [enabled by default]
    img.c:263:4: warning: braces around scalar initializer [enabled by default]
    img.c:263:4: warning: (near initialization for ‘image.theta’) [enabled by default]
    Les warnings sont émis sur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
        Image image={  {0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,
                        0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,
                        0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,
                        0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,
                        0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,
                        0,0,1,0,0,1,1,1,1,0,0,0,0,0,0,0,
                        0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,
                        0,0,0,1,1,0,0,0,0,1,0,0,0,0,0,0,
                        0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0},
                        {0},{0},{0,0},{0,0},{0} };
    Sachant que Image est uns structure définie ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    typedef struct
    {
        int t[M][N]; //Image stockée
        int gX, gY;  //Coordonnées du centre de gravité
        int gAxe[2], pAxe[2];  //Coordonnées des points a et b dans l'ellipse
        float theta; //Angle d'inclinaison du corps
    } Image;
    Tu as des warnings car normalement l'initialisation d'un tableau requiert d'entourer par des accolades chaque ligne de ton tableau, de ne pas entourer les types simples par des acollades, puis en passant c'est bien d'écrire les constantes float en les suffixant d'un f (sinon par défaut le compilateur les prends pour des doubles puis les convertit en float ...). Dans ton cas ces warnings ne pointent pas une erreur, ton initialisation donne le résultat attendu, mais cela ne coûte rien de le faire «correctement».

    Une initialisation qui ne provoque pas de warnings pourrait être :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
      Image image={  { {0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
                       {0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0},
                       {0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0},
                       {0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0},
                       {0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0},
                       {0,0,1,0,0,1,1,1,1,0,0,0,0,0,0,0},
                       {0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0},
                       {0,0,0,1,1,0,0,0,0,1,0,0,0,0,0,0},
                       {0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0} },
                     0, 0,
                     {0,0}, {0,0},
                     0.0f };
    Le derniers warnings sont :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    img.c:252:14: warning: unused parameter ‘argc’ [-Wunused-parameter]
    img.c:252:26: warning: unused parameter ‘argv’ [-Wunused-parameter]
    Pour ne plus voir ces warnings déclare simplement ton main ainsi : int main(void), là non plus il n'y a pas d'erreur en soi, et là non plus ça ne coûte rien de changer son code pour éviter un warning.


    ---


    Bon, maintenant ça compile sans messages d'avertissements ou erreurs. Mais ça ne signifie pas pour autant que ton code est correct.

    Que se passe-t-il lors de la première insertion, donc juste après [codeiniline]cb_init[/codeinline] :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void cb_init(c_buff *cb)
    {
      cb->buffer = malloc(taille_buffer*sizeof(Image));
     
      cb->courant = cb->buffer;
      cb->buffer_fin = cb->buffer;
      cb->buffer_plein=0;
    }
    Ooops ... tu n'initialises pas buffer_debut ? -> erreur sans doute

    Mais continuons avec InsertImage :

    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
    void insert_Image(c_buff *cb, Image *img)
    {
      pointG(img);
      grandAxe(img);
      petitAxe(img);
      valTheta(img);
     
      printf("%p %p\n", cb->courant, img);
      *(cb->courant) = *img;
      printf("%p %p\n", cb->courant, img);
     
      if(cb->courant == cb->buffer_fin)
        cb->buffer_plein=1;
     
      if(cb->courant == cb->buffer_fin)
        {
          cb->courant = cb->buffer_debut;
        }
      else
        {
          cb->courant += sizeof(Image);
        }
    }
    Tu effectues des calculs sur ton image (ce qui en passant est certainement une erreur de design, mais j'en parlerai birèvement à la fin du post), puis :
    • si courant == buffer_fin ce qui est le cas après ton initialisation du buffer :
      • tu dis que le buffer est plein, ce qui n'est manifestement pas le cas
      • tu mets courant sur le pointeur de debut qui n'est pas initialisé, ce qui est une erreur


    Pour comprendre comment implémenter un buffer circulaire je te propose de faire des dessins pour maîtriser ce qui se passe.

    Pour comprendre les erreurs pas de solutions simples : tu déroules ton programme à la main en faisant des dessins ...

    Tu peux aussi (et je te le recommande fortement) utiliser un debugger.
    Je ne connais pas ta plateforme de dèv mais tu en as toujours un. Par exemple avec DDD sous linux on voit que quelque chose ne se passe pas forcément bien lors de cb_init :

    Au début de la fonction (tu vois que ton buffer contient du garbage)





    à la fin de la fonction :





    Apparemment buffer_debut contient encore du garbage et pas les autres membres ... (j'ai surligné en rouge).

    Ce qui ne s'arrange pas à l'entrée de la fonction insert_image :





    et tu vois qu'en sortie il y a au moins 3 membres qui ont des valeurs anormales :






    ----

    Une dernière remarque :
    Normalement une fonction fait une et une seule chose et le fait bien.
    Ce n'est certainement pas une bonne idée au niveau du design d'intégrer la manipulation de l'image dans la fonction d'insertion d'image dans un buffer circulaire ...

  10. #10
    Membre chevronné
    Homme Profil pro
    Cadre informatique
    Inscrit en
    Avril 2013
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Cadre informatique

    Informations forums :
    Inscription : Avril 2013
    Messages : 183
    Par défaut
    Merci beaucoup, je viens de voir ton message et effectivement j'avais plein d'erreurs que j'avais pas corrigé au moment ou j'ai poster mon code.

    Entre temps, j'ai corrigé en jouant toute la journée avec les adresses de chaque variable. Effectivement, le & n'etait pas de rigueur quand j'appelais les fonctions. Ca a eté corrigé avant de voir ton message mais merci de l'avoir trouvé.
    Je viens de rajouter l'initialisation du pointeur buffer_debut.
    Merci pour l'initialisation d'Image dans le main, sa tourne parfaitement maintenant.
    Quant à l'introduction des fonctions pointG(), grandAxe(), petitAxe() et theta(), je les ai mises ici car je veux les faire chaque fois que je veux introduire une nouvelle image dans mon buffer circulaire.
    En quoi est-ce une mauvaise chose?
    Et qu'est ce que je peux utiliser comme debugger, je code sous CodeBlocks sous windows 7.

    Merci

  11. #11
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    Citation Envoyé par Bysbobo Voir le message
    Quant à l'introduction des fonctions pointG(), grandAxe(), petitAxe() et theta(), je les ai mises ici car je veux les faire chaque fois que je veux introduire une nouvelle image dans mon buffer circulaire.En quoi est-ce une mauvaise chose?
    Ce n'est pas forcément une mauvaise chose ni même une erreur si c'est clair. Mais imagine qu'une autre personne lise ou maintienne ton programme, elle voit l'appel à une fonction insert_Image. Si elle ne le sait pas elle va croire que cette fonction fait ce qu'elle prétend faire : insérer une image dans un buffer, sans connaître le code on ne voit pas que l'image sera traitée en même temps et cela peut être à l'origine d'arrachage de cheveux ... à moins de commenter chaque appel à insert_Image -> pas pratique.
    Il est plus lisible de faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    determiner_parametres_ellipse(&img);
    insert_Image(&cbuf, &img);
    Citation Envoyé par Bysbobo Voir le message
    Et qu'est ce que je peux utiliser comme debugger, je code sous CodeBlocks sous windows 7.
    Je ne suis pas un habitué de cet environnement, mais il intègre une interface de debugage : Debuging with code::blocks.
    Tout comme tu as appris à utiliser code::blocks, il va y avoir une période d'apprentissage au debbuger ... mais c'est indispensable de savoir s'en servir

  12. #12
    Membre chevronné
    Homme Profil pro
    Cadre informatique
    Inscrit en
    Avril 2013
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Cadre informatique

    Informations forums :
    Inscription : Avril 2013
    Messages : 183
    Par défaut
    Coucou,

    Je reviens faire appel à ton aide précieuse vu que depuis quelques jours, je galère...
    Je me perds dans toutes mes structures...

    Conformément au dernier post j'ai modifié l'initialisation de mon buffer de telle sorte:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void cb_init(c_buff *cb)
    {
      cb->buffer = malloc(taille_buffer*sizeof(Image));
      cb->buffer_debut = cb->buffer;
      cb->courant = cb->buffer_debut;
      cb->buffer_fin = cb->buffer_debut + (taille_buffer)*sizeof(Image);
      cb->buffer_plein=0;
    }
    Ce qui me gene dans cette définition, c'est que buffer est défini tel que:
    Alors qu'il s'agit d'un ensemble de (taille_buffer, ici 20) Image...

    Du coup, j'ai pensé à faire une init de mon buffer plus de cette facon:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      cb->buffer_debut = malloc(taille_buffer*sizeof(Image));
    J'ai modifié buffer_fin afin d'etre sur qu'il soit différent de buffer_debut pour la suite du programme
    Par contre, j'ai tenté de faire 15000 dessins différents pour bien voir ce que je dois affecter et en quelles circonstances mais je me perds...
    Une fois la fonction cb_init appelée et terminée, je comptais insérer mon image (avec toutes les modifications faites par la fonction Insert_Image) mais j'ai des soucis avec les associations des pointeurs courant avec les images...

    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
    void insert_Image(c_buff *cb, Image *img)
    {
      pointG(img);
      grandAxe(img);
      petitAxe(img);
      valTheta(img);
     
      *(cb->courant) = *img;
     
      if(cb->courant == cb->buffer_fin)
        cb->buffer_plein=1;
     
      if(cb->courant == cb->buffer_fin)
        {
          cb->courant = cb->buffer_debut;
        }
      else
        {
          cb->courant += sizeof(Image);
        }
    }
    Des fois mon programme me sort, après des tests, que buffer_plein vaut 12 alors que je le mets à 1 seulement les "taille_buffer" (ici, 20) images soient introduites mais bon...
    Et pour finir, le top du top, et c'est pourquoi j'ai commencé à re-regarder ces fonctions, c'est que mon programme tourne dans le vide parce qu'il n'aime pas quand je lui appelle plusieurs fois la fonction Insert_Image pour gérer plusieurs images et donc remplir mon buffer.

    Bref, j'espère que je t'ai bien exposé mon problème et d'avance merci

  13. #13
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    Bonjour,

    Reprenons tes besoins, tu veux une structure de donnée qui te permette de stocker temporairement des objets. Tu désires pouvoir y insérer des objets et les récupérer à la manière d'une file (FIFO, premier entré premier sorti). Une méthode (parmi d'autres) est d'utiliser un tableau de taille fixe et de repérer l'endroit où on récupère un objet et l'endroit où on va écrire le suivant. Par exemple on pourrait, à un moment donné, avoir cette situation :

    Ici il s'agit d'un buffer de 5 éléments, ceux d'indice 0,3 et 4 ne sont vides, 1 et 2 sont occupés. Le prochain éléments a être lu sera le 1 et le prochain endroit à recevoir un nouvel élément sera le 3.
    Si on rajoute (enfile) un nouvel élément, il sera placé dans la case 3 (là ou write pointe) puis on fera pointer write vers la case suivante.

    Si on lit (défile) un élément alors on renvoie l'élément pointé par read, puis on fait avancer read.

    Si nous rajoutons maintenant encore un élément, le pointeur write avance mais ne sort pas du buffer car on l'implémente circulaire et il revient au début (comme un modulo).

    Évidemment le pointeur read aura le même comportement quand il arrivera en fin de tableau.

    Rajoutons encore deux éléments pour obtenir :

    Ici la file est pleine, on ne pourra plus rajouter (enfiler) d'éléments. Défilons-les tous. et nous obtenons une file vide :


    Tu remarques qu'en utilisant les pointeurs ainsi il peut-être compliqué de différencier les deux derniers cas en ne se basant que sur la position relative des pointeurs. C'est pourquoi j'ai rajouté un compte d'éléments.
    Initialement la file sera vide (count=0) et les pointeurs pointeront tous les deux sur le début du buffer :


    Résumons ce qu'il nous faut pour notre structure de file
    • un tableau de taille fixe donnée
    • un pointeur pour indiquer le prochain élément à lire (défiler)
    • un pointeur pour indiquer où écrire (enfiler) le prochain élément
    • un compteur qui indique combien d'éléments sont actuellement dans la file
    • la taille des objets enfilés (?)
    • ...


    Les fonctions que nous pouvons implémenter :
    • une pour la création d'une file vide, on spécifiera la taille voulue de la file
    • une pour savoir si la file est vide (facile)
    • une pour savoir si la file est pleine (facile aussi)
    • une pour enfiler un élément
    • une pour défiler un élément
    • ....
    • une pour les amener toutes et dans les ténèbres les lier


    Ça c'est pour la partie théorique. Il va y avoir d'autres décisions à prendre lors de l'implémentation en C comme :
    • ce buffer va-t-il contenir des copies des objets ou des pointeurs sur des objets ?
    • ce buffer doit-il rester générique (on va pouvoir le réutiliser pour différents types d'objets) ou va-t-on le spécialiser (on ne pourra l'utiliser qu'avec un type prédéfinit d'objets)
    • comment réaliser la gestion des erreurs
    • ...

  14. #14
    Membre chevronné
    Homme Profil pro
    Cadre informatique
    Inscrit en
    Avril 2013
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Cadre informatique

    Informations forums :
    Inscription : Avril 2013
    Messages : 183
    Par défaut
    Je vais essayer d'y repondre au fur et a mesure:

    • un tableau de taille fixe donnée -> Je compte passer par le malloc afin d'allouer la memoire et non de passer par une declaration "brute" d'un tableau
    • un pointeur pour indiquer le prochain élément à lire (défiler)->il s'agit du pointeur lecture
    • un pointeur pour indiquer où écrire (enfiler) le prochain élément ->il s'agit du pointeur courant
    • un compteur qui indique combien d'éléments sont actuellement dans la file-> je pense ne pas en avoir besoin dans le sens ou je compte lire la totalite de mon buffer a chaque insertion
    • la taille des objets enfilés (?)-> sizeof(Image)


    Les fonctions que nous pouvons implémenter :
    • une pour la création d'une file vide, on spécifiera la taille voulue de la file-> la fonction cb_init avec le malloc pour "taille_buffer" elements
    • une pour savoir si la file est vide (facile) -> voir ligne de dessous
    • une pour savoir si la file est pleine (facile aussi)-> a l'initialisation j'initialise une variable buffer_plein que je mets a 0 dans un premier temps, ensuite a chaque introduction, je ne fais rien et seulement en arrivant a buffer_fin je passe cette variable a 1
    • une pour enfiler un élément ->il s'agit de la fonction InsertInBuffer
    • une pour défiler un élément-> Je ne pense pas la faire car je compte ecraser le plus vieil element par le plus recent recu
    • ....
    • une pour les amener toutes et dans les ténèbres les lier -> J'ADORE!


    Ça c'est pour la partie théorique. Il va y avoir d'autres décisions à prendre lors de l'implémentation en C comme :
    • ce buffer va-t-il contenir des copies des objets ou des pointeurs sur des objets ? -> Je pensais recevoir mes images, les traiter puis les inserer directement dans le buffer. Effectivement, j'ai peut etre un souci sur le fait que meme si j'ai un pointeur je ne sais pas ou elles sont stockees... Est-ce que je me trompe?
    • ce buffer doit-il rester générique (on va pouvoir le réutiliser pour différents types d'objets) ou va-t-on le spécialiser (on ne pourra l'utiliser qu'avec un type prédéfinit d'objets) ->Non il s'agit d'un projet tres ciblé. Je peux le spécialiser en pointeur d'Image sans souci
    • comment réaliser la gestion des erreurs -> J'en suis pas encore a ce niveau je pense ^^
    • ...
    [/QUOTE]

    Voila pour les questions que tu m'as posé et effectivement cela m'a eclairer sur un possible probleme.
    Desole pour le temps de reponse, mais j'etais au boulot et ensuite j'ai ecrit 3 fois ce message parce qu'a chaque fois je faisais une mauvaise manip' ...

    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
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
     
    #define MIN(a,b) ( (a)<(b) ? (a):(b) ) //Macro pour le calcul du minimum de 2 nombres
    #define MAX(a,b) ( (a)>(b) ? (a):(b) ) //Macro pour le calcul du maximum de 2 nombres
     
    // Image definié en 16:9e pour tests
    #define M 9 //Nombre de lignes de l'image
    #define N 16 //Nombre de colonnes de l'image
    // Valeur arbitraire pour les couleurs de l'image (noir et blanc)
    // A remplacer par les valeurs données par le groupe 1
    #define val_noir 0
    #define val_blanc 255
    // Valeur arbitraire pour le nombre d'images traitees en une seule
    // fois par le Cmotion
    #define taille_buffer 20
     
    // Toutes les variables pour chaque image
    typedef struct
    {
        int t[M][N]; //Image stockée
        int gX, gY;  //Coordonnées du centre de gravité
        int gAxe[2], pAxe[2];  //Coordonnées des points a et b dans l'ellipse
        float theta; //Angle d'inclinaison du corps
    } Image;
     
    // Toutes les variables pour le buffer circulaire
    typedef struct
    {
    	Image *buffer; // Pointeur vers le premier element du buffer
    	Image *courant; // Pointeur vers l'élément courant inséré
    	Image *lecture; // Pointeur pour la lecture du buffer
    	Image *buffer_fin; // Pointeur vers le dernier element du buffer
    	int buffer_plein;
    	int image_cmotion[M][N];
    	int whitepoint, graypoint, blackpoint;
    } Buffer;
     
    // Fonction de calcul du Plus Grand Commun Diviseur de 2 nombres
    int PGCD(int a, int b)
    {
        while(b!=0)
        {
            if( a>=0 && b>=0 )
            {
                int c=a%b;
                a=b;
                b=c;
            }
            else
            {
                if(a<0) a=-a;
                if(b<0) b=-b;
            }
        }
        return a;
    }
     
    // Fonction de calcul de Tout les Communs Diviseurs à partir du PGCD
    void TCD(int *t, int val)
    {
        int i=2, k=1;
        while( i<=val )
        {
            if( !(val%i) )
            {
                t[k]=i;
                k++;
            }
            i++;
        }
        t[0]=k-1;
    }
     
    // Fonction de calcul du centre de gravité par la
    // methode des moments geometriques
    void pointG(Image *img)
    {
        int i, j;
        int m00=0, m10=0, m01=0;
        for (i=0; i<M; i++)
        {
            for (j=0; j<N; j++)
            {
                if(img->t[i][j] == val_blanc)
                {
                    m00++;
                    m10+=i;
                    m01+=j;
                }
            }
        }
        img->gX=(int)( m10/m00 );
        img->gY=(int)( m01/m00 );
    }
     
    /*
    // Fonction de calcul du centre de gravité par une
    // methode personnelle
    void pointG(Image *img)
    {
        int i, j;
        int Xmin=M, Xmax=0, Ymin=N, Ymax=0;
     
        for (i=0; i<M; i++)
        {
            for (j=0; j<N; j++)
            {
                if(img->t[i][j] == val_blanc)
                {
                    Xmin=MIN(Xmin, i);
                    Ymin=MIN(Ymin, j);
                    Xmax=MAX(Xmax, i);
                    Ymax=MAX(Ymax, j);
                }
            }
        }
        img->gX=(int)( (Xmin+Xmax)/2 );
        img->gY=(int)( (Ymin+Ymax)/2 );
    }
    */
    // Fonction de calcul du grand axe de l'ellipse via la plus grande
    // distance par rapport au centre de gravité
    // Calcul des coordonnees de a comme etant la moitie du grand axe
    void grandAxe(Image *img)
    {
        int i, j;
        float dist=0, tmp=0;
        for (i=0; i<=img->gX; i++)
        {
            for (j=0; j<N; j++)
            {
                if(img->t[i][j] == val_blanc)
                {
                    tmp=sqrt( pow(abs(i-img->gX), 2) + pow(abs(j-img->gY), 2) );
                    if( tmp>dist )
                    {
                        dist=tmp;
                        img->gAxe[0]=i;
                        img->gAxe[1]=j;
                    }
                }
            }
        }
        img->gAxe[0] = (int)(img->gAxe[0]/2);
        img->gAxe[1] = (int)(img->gAxe[1]/2);
    }
     
    // Fonction de calcul du petit axe de l'ellipse via le calcul des TCD
    // et de la perpendicularité des 2 axes
    // Calcul des coordonnees de b comme etant la moitie du petit axe
    void petitAxe(Image *img)
    {
        int i, tmpI, tmpJ;
        int tcd[ PGCD( (img->gAxe[0] - img->gX) , (img->gAxe[1] - img->gY) ) ];
     
        TCD(tcd, PGCD( (img->gAxe[0] - img->gX) , (img->gAxe[1] - img->gY) ));
     
        if( tcd[0]==0 || tcd[0]==1 )
        {
            img->pAxe[0]=img->gX;
            img->pAxe[1]=img->gY;
        }
        else
        {
            for(i=1; i<=tcd[0]; i++)
            {
                tmpI = (int)(img->gAxe[0]*2/tcd[i]);
                tmpJ = (int)(img->gAxe[1]*2/tcd[i]);
                if( img->t[tmpI][tmpJ] == val_blanc )
                {
                    img->pAxe[0]=img->gX - tmpI;
                    img->pAxe[1]=img->gY - tmpJ;
                }
            }
            img->pAxe[0] = (int)(img->pAxe[0]/2);
            img->pAxe[1] = (int)(img->pAxe[1]/2);
        }
    }
     
    // Fonction de calcul de théta, angle entre l'axe des ordonnées et
    // l'orientation du grand axe de l'ellipse
    void valTheta(Image* img)
    {
        int i, j;
        float num=0, den1=0, den2=0;
        for(i=0; i<M; i++)
        {
            for(j=0; j<N; j++)
            {
                if( img->t[i][j] == val_blanc )
                {
                    num += i*j;
                    den1 += pow(i,2);
                    den2 += pow(j,2);
                }
            }
        }
        img->theta=(180*atan(2*num/(den1-den2)))/M_PI;
        if(img->theta < 0) img->theta = -img->theta;
    }
     
    // Fonction a mettre en fin de programme pour eviter
    // les fuites de memoires dues au malloc du buffer circulaire
    void cb_free(Buffer *cb)
    {
    	free(cb->buffer);
    }
     
    // Fonction d'initialisation du buffer circulaire
    void cb_init(Buffer *cb)
    {
        cb->buffer = malloc(taille_buffer*sizeof(Image));
        cb->courant = cb->buffer;
        cb->lecture = cb->buffer;
        cb->buffer_fin = cb->buffer + (taille_buffer-1)*sizeof(Image);
     
        int i, j;
        for(i=0; i<M; i++)
        {
            for(j=0; j<N; j++)
            {
                cb->image_cmotion[i][j]=0;
            }
        }
     
        cb->buffer_plein = 0;
        cb->whitepoint = 0;
        cb->graypoint = 0;
        cb->blackpoint = 0;
     
        for(j=0; j<taille_buffer; j++)
        {
            printf("n%d: %p\n", j, cb->courant+j*sizeof(Image));
        }
    }
     
    // Fonction d'insertion de l'image dans le buffer circulaire
    void insertInBuffer(Buffer *cb, Image *img)
    {
        printf("%p %p\n", cb->courant, cb->buffer_fin);
        pointG(img);
        grandAxe(img);
        petitAxe(img);
        valTheta(img);
     
        *(cb->courant) = *img;
        printf("%f\n", (cb->courant)->theta );
     
        if(cb->courant == cb->buffer_fin)
        {
            cb->courant = cb->buffer;
            cb->buffer_plein = 1;
        }
        else
            cb->courant += sizeof(Image);
        printf("%p %d\n", cb->courant, cb->buffer_plein);
    }
     
    // Fonction de lecture du buffer circulaire
    // pour le calcul de l'image en noir et blanc
    void create_Cmotion(Buffer *cb, Image *img)
    {
        int i, j;
        for(i=0; i<M; i++)
        {
            for(j=0; j<N; j++)
            {
                cb->image_cmotion[i][j] = (int)( cb->image_cmotion[i][j]*(taille_buffer/val_blanc) ) + img->t[i][j] ;
            }
        }
     
        if( cb->lecture == cb->buffer_fin )
            cb->lecture = cb->buffer;
        else
            cb->lecture += sizeof(Image);
    }
     
    void Cmotion(Buffer *cb, Image *img)
    {
        int i, j;
        for(i=0; i<M; i++)
        {
            for(j=0; j<N; j++)
            {
                if( cb->image_cmotion[i][j] == val_blanc )
                    cb->whitepoint++;
                else
                {
                    if( cb->image_cmotion[i][j] == val_noir )
                        cb->blackpoint++;
                    else
                        cb->graypoint++;
                }
            }
        }
    }
     
    // Fontion principale du programme
    // Permet le lancement de toutes les fonctions ci-dessus
    int main(void)
    {
        Image image1={ {{0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0},
                        {0,0,0,0,0,0,255,255,0,0,255,255,0,0,0,0},
                        {0,0,0,0,0,0,255,255,0,255,0,0,0,0,0,0},
                        {0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0},
                        {0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0},
                        {0,0,255,0,0,255,255,255,255,0,0,0,0,0,0,0},
                        {0,0,0,0,255,255,255,255,255,0,0,0,0,0,0,0},
                        {0,0,0,255,255,0,0,0,0,255,0,0,0,0,0,0},
                        {0,0,255,255,0,0,0,0,0,255,0,0,0,0,0,0}},
                        0,0,{0,0},{0,0},0.0f };
        Image image2={ {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                        {0,0,0,0,0,0,0,255,0,255,255,255,255,0,0,0},
                        {0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0},
                        {0,0,0,0,0,255,255,255,255,0,0,0,0,0,0,0},
                        {0,0,0,0,0,255,255,255,255,0,0,0,0,0,0,0},
                        {0,0,0,0,255,255,255,255,255,0,0,0,0,0,0,0},
                        {0,0,0,255,255,0,0,255,255,255,0,0,0,0,0,0},
                        {0,0,255,255,0,0,0,255,255,255,0,0,0,0,0,0}},
                        0,0,{0,0},{0,0},0.0f };
        Image image3={ {{0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0},
                        {0,0,0,0,0,0,255,255,0,0,255,255,0,0,0,0},
                        {0,0,0,0,0,0,255,255,0,255,0,0,0,0,0,0},
                        {0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0},
                        {0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0},
                        {0,0,255,0,0,255,255,255,255,0,0,0,0,0,0,0},
                        {0,0,0,0,255,255,255,255,255,0,0,0,0,0,0,0},
                        {0,0,0,255,255,0,0,0,0,255,0,0,0,0,0,0},
                        {0,0,255,255,0,0,0,0,0,255,0,0,0,0,0,0}},
                        0,0,{0,0},{0,0},0.0f };
     
        Buffer cb;
        cb_init(&cb);
     
        insertInBuffer(&cb, &image1);
        insertInBuffer(&cb, &image2);
        insertInBuffer(&cb, &image3);
    /*
        int i, j;
        for(i=0; i<M; i++)
        {
            for(j=0; j<N; j++)
            {
                printf("%d ", image1.t[i][j]);
            }
            printf("\n");
        }
        printf("\n");
        for(i=0; i<M; i++)
        {
            for(j=0; j<N; j++)
            {
                printf("%d ", image2.t[i][j]);
            }
            printf("\n");
        }
        printf("\n");
        for(i=0; i<M; i++)
        {
            for(j=0; j<N; j++)
            {
                printf("%d ", image3.t[i][j]);
            }
            printf("\n");
        }
        printf("\n");
     
        for(i=0; i<taille_buffer; i++)
        {
            create_Cmotion(&cb, &image1);
            create_Cmotion(&cb, &image2);
            create_Cmotion(&cb, &image3);
        }
     
        for(i=0; i<M; i++)
        {
            for(j=0; j<N; j++)
            {
                printf("%d ", cb.image_cmotion[i][j]);
            }
            printf("\n");
        }
     
        printf("\nCoordonnees de G: %d-%d\n", image1.gX, image1.gY);
        printf("\nCoordonnees de G: %d-%d\n", image2.gX, image2.gY);
        printf("\nCoordonnees de G: %d-%d\n", image3.gX, image3.gY);
        printf("\nCoordonnees de a: %d-%d\n", image1.gAxe[0], image1.gAxe[1]);
        printf("\nCoordonnees de b: %d-%d\n", image1.pAxe[0], image1.pAxe[1]);
        printf("\nCoordonnees de a: %d-%d\n", image2.gAxe[0], image2.gAxe[1]);
        printf("\nCoordonnees de b: %d-%d\n", image2.pAxe[0], image2.pAxe[1]);
        printf("\nCoordonnees de a: %d-%d\n", image3.gAxe[0], image3.gAxe[1]);
        printf("\nCoordonnees de b: %d-%d\n", image3.pAxe[0], image3.pAxe[1]);
        printf("\nValeur de l'angle theta: %f\n", image1.theta);
        printf("\nValeur de l'angle theta: %f\n", image2.theta);
        printf("\nValeur de l'angle theta: %f\n", image3.theta);
    */
        cb_free(&cb);
        return 0;
    }
    Par contre, voici la version que j'ai en ce moment, on va dire que toutes les fonctions que j'appelle fonctionne. Mais fonctionne une unique fois et apres elle bug a un moment donné. Je vois pas du tout d'ou sa vient

    Et encore merci pour le super tuto que tu as fait, c'est vrai que c'est toujours utile d'avoir un dessin de ce que l'on programme

  15. #15
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    En parcourant ton code je m'aperçois que tu fais des erreurs sur ce qu'on appelle l'arithmétique des pointeurs.
    En C quand tu ajoutes un entier n à un pointeur p tu ne demandes pas au pointeur de se déplacer de n octets mais de n fois taille de l'objet pointé. Par exemple si tu as défini Image *tab_image=malloc(N*sizeof *tab_image); puis que tu utilises un pointeur pour parcourir ce tableau Image *ptr=tab; alors l'expression ptr+1 ne fait pas pointer ptr un octet après tab mais sizeof *ptr plus loin (la taille d'un objet pointé).

    Si on prends un programme simple pour illustrer ça :
    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
    #include <stdio.h>
    #include <stdlib.h>
     
    #define TSIZE 10
     
    int main(void)
    {
      int *tab;
      int *ptr;
     
      tab=malloc(TSIZE * sizeof *tab);
      ptr=tab;
     
      printf("sizeof int = %zu\nptr=tab\n\n", sizeof(int));
      printf("@tab       = %p\n", tab);
      printf("@ptr       = %p\n", ptr);
      printf("@tab[1]    = %p\n", &tab[1]);
      printf("@ptr + 1   = %p\n\n", ptr+1);
      printf("ptr=&tab[TSIZE-1]\n");
      ptr=&tab[TSIZE-1];
      printf("ptr-tab    = %zd\n", ptr-tab);
     
      free(tab);
     
      return 0;
    }
    Ce programme, qui alloue dynamiquement un tableau de 10 entiers, commence par afficher la taille d'un int. Ensuite on promène un pointeur ptr dans ce tableau.
    En particulier tu vois que ptr+1 pointe 4 octets plus loin que tab, ce 4 est simplement la taille des objets pointés en l'occurence des int.
    Code Sortie : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    > ./test 
    sizeof int = 4
    ptr=tab
     
    @tab       = 0x1cd6010
    @ptr       = 0x1cd6010
    @tab[1]    = 0x1cd6014
    @ptr + 1   = 0x1cd6014
     
    ptr=&tab[TSIZE-1]
    ptr-tab    = 9

  16. #16
    Membre chevronné
    Homme Profil pro
    Cadre informatique
    Inscrit en
    Avril 2013
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Cadre informatique

    Informations forums :
    Inscription : Avril 2013
    Messages : 183
    Par défaut
    Effectivement, ce petit rappel etait de mise!

    En revanche, mon probleme porte sur le fait que je dois jouer sur 2 tableaux...

    D'un coté, gérer mes images une à une, ça au moins ça marche
    De l'autre, il faut que je crée un buffer composé de 20 Images.
    Et c'est là que j'ai un souci pour me balader avec les pointeurs...

    J'ai modifié les sizeof(Image) que j'ajoute pour me déplacer par des +1.

    Je pense avoir trouvé un truc, que je testerais ce soir en rentrant, je te tiens au courant!

    Désolé de tout les soucis que je te donne malgré le fait que tu fasses des supers tutos

  17. #17
    Membre chevronné
    Homme Profil pro
    Cadre informatique
    Inscrit en
    Avril 2013
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Cadre informatique

    Informations forums :
    Inscription : Avril 2013
    Messages : 183
    Par défaut
    J'ai réussi

    Merci pour le coup de main Kwariz

    Voila ce que ça donne. Il y a des tests à la fin pour faire joli mais ça a l'air de tourner !

    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
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
     
    #define MIN(a,b) ( (a)<(b) ? (a):(b) ) //Macro pour le calcul du minimum de 2 nombres
    #define MAX(a,b) ( (a)>(b) ? (a):(b) ) //Macro pour le calcul du maximum de 2 nombres
     
    // Image definié en 16:9e pour tests
    #define M 9 //Nombre de lignes de l'image
    #define N 16 //Nombre de colonnes de l'image
    // Valeur arbitraire pour les couleurs de l'image (noir et blanc)
    // A remplacer par les valeurs données par le groupe 1
    #define val_noir 0
    #define val_blanc 255
    // Valeur arbitraire pour le nombre d'images traitees en une seule
    // fois par le Cmotion
    #define nbImages 20
     
    // Toutes les variables pour chaque image
    typedef struct
    {
        int t[M][N]; //Image stockée
        int gX, gY;  //Coordonnées du centre de gravité
        int gAxe[2], pAxe[2];  //Coordonnées des points a et b dans l'ellipse
        float theta; //Angle d'inclinaison du corps
    } Image;
     
    // Toutes les variables pour le buffer circulaire
    typedef struct
    {
    	Image *buffer_debut; // Pointeur vers le premier element du buffer
    	Image *courant; // Pointeur vers l'élément courant inséré
    	Image *lecture; // Pointeur pour la lecture du buffer
    	Image *buffer_fin; // Pointeur vers le dernier element du buffer
            int buffer_plein, buffer_pret;
    	int image_cmotion[M][N];
    	float val_Cmotion;
    } Buffer;
     
    // Fonction de calcul du Plus Grand Commun Diviseur de 2 nombres
    int PGCD(int a, int b)
    {
        while(b!=0)
        {
            if( a>=0 && b>=0 )
            {
                int c=a%b;
                a=b;
                b=c;
            }
            else
            {
                if(a<0) a=-a;
                if(b<0) b=-b;
            }
        }
        return a;
    }
     
    // Fonction de calcul de Tout les Communs Diviseurs à partir du PGCD
    void TCD(int *t, int val)
    {
        int i=2, k=1;
        while( i<=val )
        {
            if( !(val%i) )
            {
                t[k]=i;
                k++;
            }
            i++;
        }
        t[0]=k-1;
    }
     
    // Fonction de calcul du centre de gravité par la
    // methode des moments geometriques
    void pointG(Image *img)
    {
        int i, j;
        int m00=0, m10=0, m01=0;
        for (i=0; i<M; i++)
        {
            for (j=0; j<N; j++)
            {
                if(img->t[i][j] == val_blanc)
                {
                    m00++;
                    m10+=i;
                    m01+=j;
                }
            }
        }
        img->gX=(int)( m10/m00 );
        img->gY=(int)( m01/m00 );
    }
     
    /*
    // Fonction de calcul du centre de gravité par une
    // methode personnelle
    void pointG(Image *img)
    {
        int i, j;
        int Xmin=M, Xmax=0, Ymin=N, Ymax=0;
     
        for (i=0; i<M; i++)
        {
            for (j=0; j<N; j++)
            {
                if(img->t[i][j] == val_blanc)
                {
                    Xmin=MIN(Xmin, i);
                    Ymin=MIN(Ymin, j);
                    Xmax=MAX(Xmax, i);
                    Ymax=MAX(Ymax, j);
                }
            }
        }
        img->gX=(int)( (Xmin+Xmax)/2 );
        img->gY=(int)( (Ymin+Ymax)/2 );
    }
    */
    // Fonction de calcul du grand axe de l'ellipse via la plus grande
    // distance par rapport au centre de gravité
    // Calcul des coordonnees de a comme etant la moitie du grand axe
    void grandAxe(Image *img)
    {
        int i, j;
        float dist=0, tmp=0;
        for (i=0; i<=img->gX; i++)
        {
            for (j=0; j<N; j++)
            {
                if(img->t[i][j] == val_blanc)
                {
                    tmp=sqrt( pow(abs(i-img->gX), 2) + pow(abs(j-img->gY), 2) );
                    if( tmp>dist )
                    {
                        dist=tmp;
                        img->gAxe[0]=i;
                        img->gAxe[1]=j;
                    }
                }
            }
        }
        img->gAxe[0] = (int)(img->gAxe[0]/2);
        img->gAxe[1] = (int)(img->gAxe[1]/2);
    }
     
    // Fonction de calcul du petit axe de l'ellipse via le calcul des TCD
    // et de la perpendicularité des 2 axes
    // Calcul des coordonnees de b comme etant la moitie du petit axe
    void petitAxe(Image *img)
    {
        int i, tmpI, tmpJ;
        int tcd[ PGCD( (img->gAxe[0] - img->gX) , (img->gAxe[1] - img->gY) ) ];
     
        TCD(tcd, PGCD( (img->gAxe[0] - img->gX) , (img->gAxe[1] - img->gY) ));
     
        if( tcd[0]==0 || tcd[0]==1 )
        {
            img->pAxe[0]=img->gX;
            img->pAxe[1]=img->gY;
        }
        else
        {
            for(i=1; i<=tcd[0]; i++)
            {
                tmpI = (int)(img->gAxe[0]*2/tcd[i]);
                tmpJ = (int)(img->gAxe[1]*2/tcd[i]);
                if( img->t[tmpI][tmpJ] == val_blanc )
                {
                    img->pAxe[0]=img->gX - tmpI;
                    img->pAxe[1]=img->gY - tmpJ;
                }
            }
            img->pAxe[0] = (int)(img->pAxe[0]/2);
            img->pAxe[1] = (int)(img->pAxe[1]/2);
        }
    }
     
    // Fonction de calcul de théta, angle entre l'axe des ordonnées et
    // l'orientation du grand axe de l'ellipse
    void valTheta(Image* img)
    {
        int i, j;
        float num=0, den1=0, den2=0;
        for(i=0; i<M; i++)
        {
            for(j=0; j<N; j++)
            {
                if( img->t[i][j] == val_blanc )
                {
                    num += i*j;
                    den1 += pow(i,2);
                    den2 += pow(j,2);
                }
            }
        }
        img->theta=(180*atan(2*num/(den1-den2)))/M_PI;
        if(img->theta < 0) img->theta = -img->theta;
    }
     
    // Fonction de traitement des images
    void traitementImage(Image *img)
    {
        pointG(img);
        grandAxe(img);
        petitAxe(img);
        valTheta(img);
    }
     
    // Fonction d'initialisation du buffer circulaire
    void initBuffer(Buffer *cb, Image *buff)
    {
        cb->buffer_debut = &buff[0];
        cb->courant = cb->buffer_debut;
        cb->lecture = cb->buffer_debut;
        cb->buffer_fin = &buff[nbImages - 1];
     
        int i, j;
        for(i=0; i<M; i++)
        {
            for(j=0; j<N; j++)
            {
                cb->image_cmotion[i][j]=0;
            }
        }
     
        cb->buffer_plein = 0;
        cb->buffer_pret = 0;
        cb->val_Cmotion = 0.0f;
    }
     
    void Cmotion(Buffer *cb)
    {
        int i, j;
        int nbGray = 0, nbWhite = 0, nbBlack = 0;
        for(i=0; i<M; i++)
        {
            for(j=0; j<N; j++)
            {
                if( cb->image_cmotion[i][j] == val_blanc )
                    nbWhite++;
                else
                {
                    if( cb->image_cmotion[i][j] == val_noir )
                        nbBlack++;
                    else
                        nbGray++;
                }
            }
        }
        cb->val_Cmotion = nbGray / (nbGray + nbWhite);
    }
     
    // Fonction de lecture du buffer circulaire
    // pour le calcul de l'image en noir et blanc
    void create_Cmotion(Buffer *cb)
    {
        int i, j;
        int retrait = (int)(val_blanc/nbImages);
        for(i=0; i<M; i++)
        {
            for(j=0; j<N; j++)
            {
                if( (cb->lecture)->t[i][j] == val_blanc )
                    cb->image_cmotion[i][j] = val_blanc;
                else
                    cb->image_cmotion[i][j] = cb->image_cmotion[i][j] - retrait;
            }
        }
        if( cb->lecture == cb->buffer_fin )
        {
            cb->lecture = cb->buffer_debut;
            cb->buffer_pret = 1;
        }
        else
            (cb->lecture)++;
        if( cb->buffer_pret )
            Cmotion(cb);
    }
     
    // Fonction d'insertion de l'image dans le buffer circulaire
    void insertInBuffer(Buffer *cb, Image *img)
    {
        printf("%p -> ", cb->courant);
        *(cb->courant) = *img;
     
        traitementImage(cb->courant);
     
        if(cb->courant >= cb->buffer_fin)
        {
            cb->courant = cb->buffer_debut;
            cb->buffer_plein = 1;
        }
        else
            cb->courant = (cb->courant)++;
        printf("%p\n", cb->courant);
        if( cb->buffer_plein )
            create_Cmotion(cb);
    }
     
    // Fontion principale du programme
    // Permet le lancement de toutes les fonctions ci-dessus
    int main(void)
    {
        Image image1={ {{0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0},
                        {0,0,0,0,0,0,255,255,0,0,255,255,0,0,0,0},
                        {0,0,0,0,0,0,255,255,0,255,0,0,0,0,0,0},
                        {0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0},
                        {0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0},
                        {0,0,255,0,0,255,255,255,255,0,0,0,0,0,0,0},
                        {0,0,0,0,255,255,255,255,255,0,0,0,0,0,0,0},
                        {0,0,0,255,255,0,0,0,0,255,0,0,0,0,0,0},
                        {0,0,255,255,0,0,0,0,0,255,0,0,0,0,0,0}},
                        0,0,{0,0},{0,0},0.0f };
        Image image2={ {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                        {0,0,0,0,0,0,0,255,0,255,255,255,255,0,0,0},
                        {0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0},
                        {0,0,0,0,0,255,255,255,255,0,0,0,0,0,0,0},
                        {0,0,0,0,0,255,255,255,255,0,0,0,0,0,0,0},
                        {0,0,0,0,255,255,255,255,255,0,0,0,0,0,0,0},
                        {0,0,0,255,255,0,0,255,255,255,0,0,0,0,0,0},
                        {0,0,255,255,0,0,0,255,255,255,0,0,0,0,0,0}},
                        0,0,{0,0},{0,0},0.0f };
        Image image3={ {{0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0},
                        {0,0,0,0,0,0,255,255,0,0,255,255,0,0,0,0},
                        {0,0,0,0,0,0,255,255,0,255,0,0,0,0,0,0},
                        {0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0},
                        {0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0},
                        {0,0,255,0,0,255,255,255,255,0,0,0,0,0,0,0},
                        {0,0,0,0,255,255,255,255,255,0,0,0,0,0,0,0},
                        {0,0,0,255,255,0,0,0,0,255,0,0,0,0,0,0},
                        {0,0,255,255,0,0,0,0,0,255,0,0,0,0,0,0}},
                        0,0,{0,0},{0,0},0.0f };
     
        Buffer cb;
        Image *buff = malloc (nbImages * sizeof(Image));
        if( buff == NULL)
            exit(0);
     
        initBuffer(&cb, buff);
     
        // Introduire ici le flot d'images par une boucle while par exemple
     
        insertInBuffer(&cb, &image1);
        insertInBuffer(&cb, &image2);
        insertInBuffer(&cb, &image3);
     
        int i;
        for(i=0; i<3; i++)
        {
            printf("\nAdresse de l'image: %p\n", buff);
            printf("Coordonnees de G: %d-%d\n", buff->gX, buff->gY);
            printf("Coordonnees de a: %d-%d\n", buff->gAxe[0], buff->gAxe[1]);
            printf("Coordonnees de b: %d-%d\n", buff->pAxe[0], buff->pAxe[1]);
            printf("Valeur de l'angle theta: %f\n", buff->theta);
            buff++;
        }
        free(buff);
        return 0;
    }
    Merci beaucoup

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Intégrer un code "activecells" dans mon code déjà existant
    Par clemgdd dans le forum Macros et VBA Excel
    Réponses: 9
    Dernier message: 14/07/2015, 11h44
  2. Ajouter des objets dans un fichier deja existant
    Par schine dans le forum Persistance des données
    Réponses: 1
    Dernier message: 31/01/2013, 01h42
  3. Écrire et lire un son dans un buffer circulaire
    Par techno_08 dans le forum C
    Réponses: 2
    Dernier message: 17/05/2011, 08h59
  4. Probleme d'écriture dans un fichier deja existant
    Par Elessar01 dans le forum Visual C++
    Réponses: 1
    Dernier message: 18/04/2008, 15h15
  5. Création multiple table paradox dans le code
    Par scarabee dans le forum C++Builder
    Réponses: 8
    Dernier message: 30/10/2002, 10h17

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo