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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  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.

+ 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