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 :

convolution d'image


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de Rniamo
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    508
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 508
    Par défaut convolution d'image
    bonjour, je voudrai faire une convolution dans une image (j'explique à la fin ce que c'est) et ça ne marche pas du tout, les valeurs de couleur que j'obtient sont soit 0 soit hors de la zone de couleur existant sur un PC.

    mon code est :

    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
     
    typedef struct T_image
    {
    	char P[2];
    	int n;
    	int l;
    	int h;
    	int nb_col;
    	int R;
    	int V;
    	int B;
    }T_image;
     
    void convolution(FILE *image0,double M[3][3],int n)
    {
    	FILE *sortie=fopen("image_sortie.ppm","w");
    	T_image I;
     
    	supprim_com(image0,"image.ppm");
    	FILE *image=fopen("image.ppm","r");
    	fseek(image,0,SEEK_SET);
    	fscanf(image,"%c%d\n%d %d\n%d",&(I.P[0]),&(I.n),&(I.l),&(I.h),&(I.nb_col));
    	I.P[1]='\0';	
     
    	fprintf(sortie,"%c%d\n%d %d\n%d\n",I.P[0],I.n,I.l,I.h,I.nb_col);
     
     
    	int R[I.l][n];int V[I.l][n];int B[I.l][n];
    	int h,l,i,j;
    	double R1,V1,B1,R2,V2,B2;
     
    	//initialisation
    	for(j=0;j<n;j++)
    		for(i=0;i<I.l;i++)
    			fscanf(image,"%d\n%d\n%d\n",&(R[i][j]),&(V[i][j]),&(B[i][j]));
     
    	//calcul des pixels "masqués" et des début et fin de lignes (copie)
    	for(h=0;h<I.h;h++)
    		for(l=0;l<I.l;l++)
    		{
    			if (h<((n-1)/2) || h>((I.h-(n-1)/2)-1) || l<((n-1)/2) || l>((I.l-(n-1)/2))-1)
    			{
    				/*if (h<((n-1)/2))
    				{
    					fprintf(sortie,"%d\%d\%d\n",R[l][(n-1)/2],V[l][(n-1)/2],B[l][(n-1)/2]);
    				}
    				if (h>((I.h-(n-1)/2)-1))
    				{
    					if (h!=(I.h-1))
    					{
    						fprintf(sortie,"%d\%d\%d\n",R[l][(n-1)/2],V[l][(n-1)/2],B[l][(n-1)/2]);
    					}
    					else
    					{
    						fprintf(sortie,"%d\%d\%d\n",R[l][n-1],V[l][n-1],B[l][n-1]);
    					}
    				}
    				if (l<((n-1)/2))
    				{
    					fprintf(sortie,"%d\%d\%d\n",R[l][(n-1)/2],V[l][(n-1)/2],B[l][(n-1)/2]);
    				}
    				if (l>((I.l-(n-1)/2))-1)
    				{
    					fprintf(sortie,"%d\%d\%d\n",R[l][(n-1)/2],V[l][(n-1)/2],B[l][(n-1)/2]);
    				}				
    				//fprintf(sortie,"%d\n%d\n%d\n",R[l][h],V[h][h],B[l][h]);*/
    				fprintf(sortie,"255\n255\n255\n");
    			}
    			else
    			{
    				R2=0;V2=0;B2=0;
    				for(j=0;j<n;j++)
    					for(i=0;i<n;i++)
    					{
    						R1=(double)R[l+i-(n-1)/2][j];
    						V1=(double)V[l+i-(n-1)/2][j];
    						B1=(double)B[l+i-(n-1)/2][j];
    						R2=R2+R1*M[i][j];
    						V2=V2+V1*M[i][j];
    						B2=B2+B1*M[i][j];
    					}
    				fprintf(sortie,"%d\n%d\n%d\n",(int)R2,(int)V2,(int)B2);
    				//fprintf(sortie,"100\n166\n55\n");
    			}
    			//on calcule les nouveaux tableaux des couleurs
    			for(j=0;j<n-1;j++)
    				for(i=0;i<I.l;i++)
    				{
    					R[i][j]=R[i][j+1];
    					V[i][j]=V[i][j+1];
    					B[i][j]=B[i][j+1];
    				}
    			for(i=0;i<I.l;i++)
    				fscanf(image,"%d\n%d\n%d\n",&(R[i][n-1]),&(V[i][n-1]),&(B[i][n-1]));			
    		}
     
    	//fin de l'écriture de la convolution	
     
    	fclose(sortie);
    	remove("image.ppm");
    }
    Une convolution c'est quoi ? si on modélise l'image par un tableau I(l,h), un masque M par un tableau (i,i) avec i impaire alors la convolution se calcule pour tout les pixels à une distance supérieure à (i-1)/2 du bords :

    on pose le masque sur l'image, celui-ci ne doit pas dépasser (quelques cases hors de l'image et le résultat n'est pas bon) ; on fait la somme des M(i,j)*I(l,h) superposés ; Cela nous donne la valeur du masuqe qui correspond
    au centre du masque.

    Bien sûr le masque à une certaine "tête" pour rester dans les valeur de couleur possible : 0 mini et 255 maxi pour les composantes R,V,B.

    J'ai choisi le format ppm ascii (P3) pour sa facilité d'accès.

    Pour le moment je ne m'intéresse pas au bords non calculable et je les exclu (la parti qui s'occupera de ça est commentée car les indices des tableaux sont pour le moment faux).

  2. #2
    Membre éclairé Avatar de Rniamo
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    508
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 508
    Par défaut
    personne n'as d'idées ?

  3. #3
    Membre confirmé
    Homme Profil pro
    Consultant
    Inscrit en
    Avril 2006
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Consultant
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Avril 2006
    Messages : 92
    Par défaut
    J'ai pas vraiment d'idée, mais peut être une piste, J'ai fait un projet de traitement d'image il y a longtemps sur des .bmp

    Je me souviens que dans les fichiers y a une entête avant les données de l'image (comme dans tous les fichiers standard je pense !) et une norme.

    Pour le bmp, si je dis pas de bêtises il lui faut un nombre d'octets multiple de 4 par ligne de pixel, en gros si tu a une image de 3pixel par 3pixel et que tu travail sur une image RVB il te faut 3 octet par pixel soit 9 octet par ligne.
    Il complet alors avec 3 case vide pour obtenir un multiple de 4 octet.

    Tu ne semble pas te soucier de ce genres de problème, peut être que cela viens de la !

    Je ne peux t'en dire plus.

  4. #4
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Si tu veux des précisions sur le format ppm, il y en a des tonnes :

    que ce soit ici-même (http://www.developpez.net/forums/sho...d.php?t=347432) , sur le net (http://netpbm.sourceforge.net/doc/pbm.html) ou directement dans le package original (http://netpbm.sourceforge.net/doc/index.html) .

  5. #5
    Membre éclairé Avatar de Rniamo
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    508
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 508
    Par défaut
    Le format ppm n'est pas le prblème, toutes les opérations sur les couches fonctionnent ; par contre la fonction convolution ne marche pas.

    Je m'embrouille dans les indices des tableaux je crois mais je ne trouve pas mon erreur.

  6. #6
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    ben normalement il te faut une image intermédiaire, et là tu as (pour une convolution 3*3 ) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    for ( i = 0 ; i < nlines ; i++ )
       for ( j = 0 ; j < ncols ; j++ )
          {
            pixel[i][j] = ( oldpixel[i-1][j-1] * facteur(i-1,j-1) + 
                            oldpixel[i-1][j] * facteur(i-1,j) +
                            oldpixel[i-1][j+1] * facteur(i-1,j+1) +
                            oldpixel[i][j-1] * facteur(i,j-1) +
                            oldpixel[i][j] * facteur(i,j) +
                            oldpixel[i][j+1] * facteur(i,j+1) +
                            oldpixel[i+1][j-1] * facteur(i+1,j-1) +
                            oldpixel[i+1][j] * facteur(i+1,j) +
                            oldpixel[i+1][j+1] * facteur(i+1,j+1) ) / PoidsTotal ;
         }

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

Discussions similaires

  1. [Image] Créer un noyau de convolution gaussien
    Par millie dans le forum Contribuez
    Réponses: 13
    Dernier message: 02/09/2011, 00h47
  2. [Image] Gradient et Hessienne par Convolution
    Par pseudocode dans le forum Contribuez
    Réponses: 28
    Dernier message: 01/11/2010, 00h01
  3. Convolution d'une image par la multiplication de deux filtres
    Par Azhag70 dans le forum Traitement d'images
    Réponses: 1
    Dernier message: 31/03/2008, 14h26
  4. Convolution d'une image et fonction
    Par samia_6 dans le forum Images
    Réponses: 11
    Dernier message: 23/10/2007, 08h07
  5. convolution d'image
    Par blue dans le forum Algorithmes et structures de données
    Réponses: 9
    Dernier message: 10/04/2005, 23h22

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