Advertisement
kdelemme

Traitement d'image (Sobel, Prewitt, Gaussien, ...)

Dec 21st, 2011
137
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 17.62 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "BmpLib.h"
  4. #include <String.h>
  5. #include <math.h>
  6.  
  7. #define debug true
  8.  
  9.  
  10. void donneesImageRGB2ImageTableau(unsigned char **imageDest, const DonneesImageRGB *imageSource) {
  11.     if (debug) printf("[DEBUG] Debut de la copie de l'image RGB en niv de gris \n");
  12.    
  13.     int i,j;
  14.  
  15.     for (i=0; i<imageSource->hauteurImage; i++)
  16.         for (j=0; j<imageSource->largeurImage; j++)
  17.         {
  18.             imageDest[i][j] = imageSource->donneesRGB[(i*imageSource->largeurImage + j)*3 + 1];
  19.         }
  20.      if (debug) printf("[DEBUG] Fin de la copie de l'image RGB en niv de gris \n");
  21. }
  22.  
  23.  
  24. void imageTableau2ImageRGB(unsigned char **imageSource, DonneesImageRGB *imageDest) {
  25.    
  26.     if (debug) printf("[DEBUG] Debut de la copie de l'image en niv de gris vers image RGB \n");
  27.     int i,j;
  28.    
  29.     for (i=0; i<imageDest->hauteurImage; i++)
  30.         for (j=0; j<imageDest->largeurImage; j++)
  31.         {
  32.             imageDest->donneesRGB[(i*imageDest->largeurImage + j)*3] = imageSource[i][j];
  33.             imageDest->donneesRGB[(i*imageDest->largeurImage + j)*3 + 1] = imageSource[i][j];
  34.             imageDest->donneesRGB[(i*imageDest->largeurImage + j)*3 + 2] = imageSource[i][j];
  35.         }
  36.     if (debug) printf("[DEBUG] Fin de la copie du tableau en niv de gris vers image RGB \n");
  37. }
  38.  
  39.  
  40. void afficherImageTableau(unsigned char **image, const DonneesImageRGB *imageSource) {
  41.    
  42.     if (debug) printf("[DEBUG] Debut de l'affichage de l'image en niv de gris \n");
  43.     int i, j;
  44.    
  45.     for (i=0; i<imageSource->hauteurImage; i++)
  46.         for (j=0; j<imageSource->largeurImage; j++)
  47.         {
  48.             if (debug) printf("[DEBUG] [%d][%d] = %d\n", i, j, image[i][j]);
  49.         }
  50.     if (debug) printf("[DEBUG] Fin de l'affichage de l'image en niv de gris \n");
  51. }
  52.  
  53.  
  54. void calculHistogramme(unsigned char **image, int largeur, int hauteur, int *histoEntier, float *histoFloat) {
  55.     if (debug) printf("[DEBUG] Debut du calcul de l'histogramme\n");
  56.    
  57.     int i,j;
  58.     /* Initialisation du tableau d'histogramme */
  59.     for(i=0; i<256; i++)
  60.     {
  61.         histoEntier[i] = 0;
  62.         histoFloat[i] = 0.0f;
  63.     }
  64.    
  65.     /* Calcul des histogrammes */
  66.     for (i=0; i<hauteur; i++)
  67.         for(j=0; j<largeur; j++)
  68.         {
  69.             histoEntier[image[i][j]]++;
  70.             histoFloat[image[i][j]]++;  
  71.         }
  72.    
  73.     /* Calcul pour l'histogramme en flottant */
  74.     for (i=0; i<256; i++)
  75.         histoFloat[i] /= largeur*hauteur;
  76.        
  77.     if (debug) printf("[DEBUG] Fin du calcul de l'histogramme\n");
  78.    
  79. }
  80.  
  81. void afficheHistogramme(int *histoEntier, float *histoFloat)
  82. {
  83.     if (debug) printf("[DEBUG] Debut de l'affichage de l'histogramme\n");
  84.     int i;
  85.     for (i=0; i<256; i++)
  86.        if (debug) printf("[DEBUG] H[%d] = %d \t|\tH[%d] = %f\n", i, histoEntier[i], i, histoFloat[i]);
  87.        
  88.     if (debug) printf("[DEBUG] Fin de l'affichage de l'histogramme\n");
  89. }
  90.  
  91. unsigned char** seuillageAutomatiqueEntropie(unsigned char **image2D, DonneesImageRGB *image, float *histoFloat, int *histoEntier, int *seuilEntropieMax) {
  92.    
  93.     if (debug) printf("[DEBUG] Debut du seuillage automatique par maximisation de l'entropie\n");
  94.    
  95.     int s,p;
  96.     double h;
  97.     double h2;
  98.     double hMax = 0.0;
  99.     int nc;
  100.    
  101.     unsigned char **imageDest = (unsigned char **)malloc(image->hauteurImage*sizeof(unsigned char *));
  102.     for (s=0; s<image->hauteurImage; s++)
  103.         imageDest[s] = (unsigned char *)malloc(image->largeurImage*sizeof(unsigned char));
  104.    
  105.    
  106.    
  107.     for (s=0; s<255; s++)
  108.     {
  109.         h = 0.0f;
  110.         h2 = 0.0f;
  111.         nc = 0;
  112.        
  113.         for(p=0; p<s; p++)
  114.         {
  115.             if (histoFloat[p] > 0) h += histoFloat[p] * log(histoFloat[p]);
  116.             nc += histoEntier[p];
  117.         }
  118.         if (nc > 0) h *= -1/nc;
  119.        
  120.         for(p=s+1; p<255; p++)
  121.         {
  122.             if (histoFloat[p] > 0) h2 += histoFloat[p] * log(histoFloat[p]);
  123.         }  
  124.         h2 *= -1/(image->largeurImage*image->hauteurImage - nc);
  125.         //Apparement faut pas faire le dernier calcul
  126.         h += h2 + log(nc * (image->largeurImage*image->hauteurImage - nc));
  127.        
  128.         if (h > hMax)
  129.         {
  130.             hMax = h;
  131.             *seuilEntropieMax = s;  
  132.         }
  133.        
  134.     }
  135.    
  136.     if (debug) printf("[DEBUG] hMax: %f | sMax: %i\n", hMax, *seuilEntropieMax);
  137.    
  138.     /* Maintenant qu'on a la valeur de s qui maximise l'entropie */
  139.     /* Tous les pixels dont le niveau de gris est inferieur a s deviennent noir */
  140.     /* Les autres deviennent blanc */
  141.     for (s=0; s<image->hauteurImage; s++)
  142.         for(p=0; p<image->largeurImage; p++)
  143.         {
  144.             if (image2D[s][p] < *seuilEntropieMax) imageDest[s][p] = 0;
  145.             else imageDest[s][p] = 255;
  146.         }
  147.    
  148.     if (debug) printf("[DEBUG] Fin du seuillage automatique par maximisation de l'entropie\n");
  149.    
  150.     return imageDest;
  151. }
  152.  
  153. unsigned char** convolution(unsigned char **image2D, DonneesImageRGB *image, int **masque, int taille) {
  154.    
  155.     int i,j,k,l,val,div;
  156.    
  157.     unsigned char **imageDest = (unsigned char **)malloc(image->hauteurImage*sizeof(unsigned char *));
  158.     for (i=0; i<image->hauteurImage; i++)
  159.         imageDest[i] = (unsigned char *)malloc(image->largeurImage*sizeof(unsigned char));
  160.    
  161.     /* Calcul de la somme des coefficients du masque */
  162.     div = 0;    
  163.     for(k=-taille/2; k<=taille/2; k++)
  164.         for(l=-taille/2; l<=taille/2; l++)
  165.         {
  166.             div += (int)masque[k+taille/2][l+taille/2];
  167.         }
  168.    
  169.     /* Convolution de image2D par masque */
  170.     /* sauvegarde du resultat dans imageDest */
  171.     for (i=taille/2; i<image->hauteurImage-taille/2; i++)
  172.         for(j=taille/2; j<image->largeurImage-taille/2; j++)
  173.         {
  174.             val = 0;
  175.             for(k=-taille/2; k<=taille/2; k++)
  176.                 for(l=-taille/2; l<=taille/2; l++)
  177.                     val += masque[k+taille/2][l+taille/2]*image2D[i+k][j+l];
  178.                    
  179.              
  180.             if (div != 0) val /= div;  
  181.             if (val > 255) imageDest[i][j] = 255;
  182.             else if (val < 0) imageDest[i][j] = 0;
  183.             else imageDest[i][j] = val;
  184.         }
  185.    
  186.    
  187.     return imageDest;
  188. }
  189.  
  190. void creerMasqueMoyenneur(int **masque, int taille) {
  191.     int i,j;
  192.    
  193.     for (i=0; i<taille; i++)
  194.         for (j=0; j<taille; j++)
  195.             masque[i][j] = 1;
  196. }
  197.  
  198. void creerMasqueGaussien(int **masque, int taille) {
  199.    
  200.     if (taille == 3)
  201.     {
  202.         masque[0][0] = 1;
  203.         masque[0][1] = 2;
  204.         masque[0][2] = 1;
  205.         masque[1][0] = 2;
  206.         masque[1][1] = 4;
  207.         masque[1][2] = 2;
  208.         masque[2][0] = 1;
  209.         masque[2][1] = 2;
  210.         masque[2][2] = 1;
  211.     }
  212.     if (taille == 5)
  213.     {
  214.         masque[0][0] = 1;
  215.         masque[0][1] = 4;
  216.         masque[0][2] = 6;
  217.         masque[0][3] = 4;
  218.         masque[0][4] = 1;
  219.         masque[1][0] = 4;
  220.         masque[1][1] = 16;
  221.         masque[1][2] = 24;
  222.         masque[1][3] = 16;
  223.         masque[1][4] = 4;
  224.         masque[2][0] = 6;
  225.         masque[2][1] = 24;
  226.         masque[2][2] = 36;
  227.         masque[2][3] = 24;
  228.         masque[2][4] = 6;
  229.         masque[3][0] = 4;
  230.         masque[3][1] = 16;
  231.         masque[3][2] = 24;
  232.         masque[3][3] = 16;
  233.         masque[3][4] = 4;
  234.         masque[4][0] = 1;
  235.         masque[4][1] = 4;
  236.         masque[4][2] = 6;
  237.         masque[4][3] = 4;
  238.         masque[4][4] = 1;
  239.     }
  240. }
  241.  
  242. void creerMasqueLaplacien(int **masque, int taille) {
  243.    
  244.     if (taille == 4)
  245.     {
  246.         masque[0][0] = 0;
  247.         masque[0][1] = -1;
  248.         masque[0][2] = 0;
  249.         masque[1][0] = -1;
  250.         masque[1][1] = 4;
  251.         masque[1][2] = -1;
  252.         masque[2][0] = 0;
  253.         masque[2][1] = -1;
  254.         masque[2][2] = 0;
  255.     }
  256.     if (taille == 8)
  257.     {
  258.         masque[0][0] = -1;
  259.         masque[0][1] = -1;
  260.         masque[0][2] = -1;
  261.         masque[1][0] = -1;
  262.         masque[1][1] = 8;
  263.         masque[1][2] = -1;
  264.         masque[2][0] = -1;
  265.         masque[2][1] = -1;
  266.         masque[2][2] = -1;
  267.     }
  268. }
  269.  
  270. unsigned char** gradientRoberts(unsigned char ** image2D, DonneesImageRGB* image)
  271. {
  272.     int i,j;
  273.     int gx,gy;
  274.    
  275.     unsigned char **imageDest = (unsigned char **)malloc(image->hauteurImage*sizeof(unsigned char *));
  276.     for (i=0; i<image->hauteurImage; i++)
  277.         imageDest[i] = (unsigned char *)malloc(image->largeurImage*sizeof(unsigned char));
  278.        
  279.     for(i=0; i<image->hauteurImage-1; i++)
  280.         for(j=0; j<image->largeurImage-1; j++)
  281.         {
  282.             gx = image2D[i][j+1] - image2D[i][j];
  283.             gy = image2D[i+1][j] - image2D[i][j];
  284.             imageDest[i][j] = sqrt((float)gx*gx + (float)gy*gy);
  285.         }
  286.        
  287.    
  288.     return imageDest;
  289. }
  290.  
  291. unsigned char** gradientPrewitt(unsigned char ** image2D, DonneesImageRGB* image)
  292. {
  293.     int i,j,k,l;
  294.     int gx,gy;
  295.    
  296.     unsigned char **imageDest = (unsigned char **)malloc(image->hauteurImage*sizeof(unsigned char *));
  297.     for (i=0; i<image->hauteurImage; i++)
  298.         imageDest[i] = (unsigned char *)malloc(image->largeurImage*sizeof(unsigned char));
  299.        
  300.     int masqueX[3][3] = {{-1,0,1},{-1,0,1},{-1,0,1}};
  301.     int masqueY[3][3] = {{-1,-1,-1},{0,0,0},{1,1,1}};
  302.    
  303.    
  304.     for (i=1; i<image->hauteurImage-1; i++)
  305.         for(j=1; j<image->largeurImage-1; j++)
  306.         {
  307.             gx = 0;
  308.             gy = 0;
  309.             for(k=-1; k<=1; k++)
  310.                 for(l=-1; l<=1; l++)
  311.                 {
  312.                     gx += masqueX[k+1][l+1]*image2D[i+k][j+l];
  313.                     gy += masqueY[k+1][l+1]*image2D[i+k][j+l];
  314.                 }
  315.                    
  316.             imageDest[i][j] = sqrt(gx*gx + gy*gy);
  317.         }
  318.    
  319.     return imageDest;
  320. }
  321.  
  322. unsigned char** gradientSobel(unsigned char **image2D, DonneesImageRGB* image)
  323. {
  324.     int i,j,k,l;
  325.     int gx,gy;
  326.    
  327.     unsigned char **imageDest = (unsigned char **)malloc(image->hauteurImage*sizeof(unsigned char *));
  328.     for (i=0; i<image->hauteurImage; i++)
  329.         imageDest[i] = (unsigned char *)malloc(image->largeurImage*sizeof(unsigned char));
  330.        
  331.     int masqueX[3][3] = {{-1,0,1},{-2,0,2},{-1,0,1}};
  332.     int masqueY[3][3] = {{-1,-2,-1},{0,0,0},{1,2,1}};
  333.    
  334.    
  335.     for (i=1; i<image->hauteurImage-1; i++)
  336.         for(j=1; j<image->largeurImage-1; j++)
  337.         {
  338.             gx = 0;
  339.             gy = 0;
  340.             for(k=-1; k<=1; k++)
  341.                 for(l=-1; l<=1; l++)
  342.                 {
  343.                     gx += masqueX[k+1][l+1]*image2D[i+k][j+l];
  344.                     gy += masqueY[k+1][l+1]*image2D[i+k][j+l];
  345.                 }
  346.                    
  347.             imageDest[i][j] = sqrt(gx*gx + gy*gy);
  348.         }
  349.    
  350.     return imageDest;
  351. }
  352.  
  353. unsigned char** filtreMedian(unsigned char **image2D, DonneesImageRGB *image)
  354. {
  355.     /* Initialisation */
  356.     int i,j,k,l,taille,cpt = 0, min, indiceMin;
  357.    
  358.     unsigned char **imageDest = (unsigned char **)malloc(image->hauteurImage*sizeof(unsigned char *));
  359.     for (i=0; i<image->hauteurImage; i++)
  360.         imageDest[i] = (unsigned char *)malloc(image->largeurImage*sizeof(unsigned char));
  361.    
  362.     printf("Taille du masque: ");
  363.     scanf("%d", &taille);
  364.    
  365.     int **masque = (int **)malloc(taille*sizeof(int*));
  366.     for (i=0; i<taille; i++)
  367.         masque[i] = (int*)malloc(taille*sizeof(int));
  368.    
  369.     /* Remplissage du masque avec des 1 ou 0 */
  370.     for (i=0; i<taille; i++)
  371.         for(j=0; j<taille; j++)
  372.         {
  373.             printf("MASQUE[%d][%d] = ", i, j);
  374.             scanf("%d", &masque[i][j]);
  375.             if (masque[i][j] == 1) cpt++;
  376.         }
  377.     int *tab = (int*)malloc(cpt*sizeof(int));
  378.    
  379.    
  380.     /* On parcour l'ensemble de l'image2D */
  381.     /* En chacun de ses pixels, on calcul la valeur médiane des niv de gris contenus dans le masque */
  382.     /* On donne la valeur médiane au pixel */
  383.    
  384.     for(i=1; i<image->hauteurImage-1; i++)
  385.         for(j=1; j<image->largeurImage-1; j++)
  386.         {
  387.             cpt = 0;
  388.             for(k=-taille/2; k<=taille/2; k++)
  389.                 for(l=-taille/2; l<=taille/2; l++)
  390.                 {
  391.                     if (masque[k+taille/2][l+taille/2] == 1)
  392.                     {
  393.                         tab[cpt] = image2D[i+k][j+l];
  394.                         cpt++;
  395.                     }
  396.                 }
  397.            
  398.             /* On tri le tableau */
  399.  
  400.             for (k=0; k<cpt-1; k++)
  401.             {
  402.                 min = tab[k];
  403.                 for(l=k; l<cpt; l++)
  404.                 {
  405.                    if (tab[l] < min)
  406.                    {
  407.                      min = tab[l];
  408.                      indiceMin = l;  
  409.                     }
  410.                 }
  411.                 tab[indiceMin] = tab[k];
  412.                 tab[k] = min;
  413.             }
  414.            
  415.             /* On prend la valeur médiane et on la met dans imageDest[i][j] */
  416.             imageDest[i][j] = tab[cpt/2];
  417.         }
  418.    
  419.     return imageDest;
  420. }
  421.  
  422. int main(int argc, char *argv[])
  423. {
  424.     printf("TRAITEMENT D'IMAGES\n\n");
  425.    
  426.     DonneesImageRGB *image = (DonneesImageRGB *)malloc(sizeof(DonneesImageRGB));
  427.     char *fichier = (char *)malloc(50*sizeof(char));
  428.    
  429.     int choixMenu, seuilEntropieMax = 0, i =0, taille = 3;
  430.     int *histoEntier = (int *)malloc(256*sizeof(int));
  431.     float *histoFloat = (float *)malloc(256*sizeof(int));
  432.     bool continuer = true;
  433.     int **masque = NULL;
  434.    
  435.     do{
  436.         printf("Entrez le nom de l'image: ");
  437.         scanf("%49s", fichier);
  438.         image = lisBMPRGB(fichier);
  439.     }while(image == NULL);
  440.    
  441.     /* Allocation du tableau 2 dimensions contenant l'image en niveau de gris */
  442.     unsigned char **imageDest = NULL;
  443.     unsigned char **image2D = (unsigned char **)malloc(image->hauteurImage*sizeof(unsigned char *));
  444.     for (i=0; i<image->hauteurImage; i++)
  445.         image2D[i] = (unsigned char *)malloc(image->largeurImage*sizeof(unsigned char));
  446.    
  447.     /* Copie des donnéesRGB de image dans le tableau d'unsigned char à 2 dimensions */
  448.     donneesImageRGB2ImageTableau(image2D, image);
  449.  
  450.     printf("L'image est bien converti en niveau de gris...\n");
  451.    
  452.     while (continuer) {
  453.         do
  454.         {
  455.             printf("MENU\n");
  456.             printf("1. Afficher le tableau de l'image en niveau de gris\n");
  457.             printf("2. Calculer l'histogramme\n");
  458.             printf("3. Afficher l'histogramme\n");
  459.             printf("4. Seuillage Automatique par Maximisation de l'Entropie\n");
  460.             printf("5. Convolution par un filtre moyenneur\n");
  461.             printf("6. Convolution par un filtre gaussien\n");
  462.             printf("7. Gradient de Roberts\n");
  463.             printf("8. Gradient de Prewitt\n");
  464.             printf("9. Gradient de Sobel\n");
  465.             printf("10. Laplacien (4 ou 8)\n");
  466.             printf("11. Filtre Median\n");
  467.             printf("12. Sauvegarder l'image\n");
  468.             printf("13. QUITTER\n");
  469.             printf("Choix: ");
  470.             scanf("%d", &choixMenu);
  471.         }while(choixMenu < 1 || choixMenu > 13);
  472.        
  473.         switch(choixMenu)
  474.         {
  475.             case 1:
  476.                 afficherImageTableau(image2D, image);
  477.                 break;
  478.             case 2:
  479.                 calculHistogramme(image2D, image->largeurImage, image->hauteurImage, histoEntier, histoFloat);
  480.                 break;
  481.             case 3:
  482.                 afficheHistogramme(histoEntier, histoFloat);
  483.                 break;
  484.             case 4:
  485.                 imageDest = seuillageAutomatiqueEntropie(image2D, image, histoFloat, histoEntier, &seuilEntropieMax);
  486.                 break;
  487.             case 5:
  488.                  printf("Entrez la taille du masque: ");
  489.                  scanf(" %d", &taille);
  490.                  masque = (int**)malloc(taille*sizeof(int*));
  491.    
  492.                 for (i=0; i<taille; i++)
  493.                     masque[i] = (int*)malloc(taille*sizeof(int));
  494.                    
  495.                 creerMasqueMoyenneur(masque, taille);
  496.                 imageDest = convolution(image2D, image, masque, taille);
  497.                 break;
  498.             case 6:
  499.                  printf("Entrez la taille du masque: ");
  500.                  scanf(" %d", &taille);
  501.                  masque = (int**)malloc(taille*sizeof(int*));
  502.    
  503.                 for (i=0; i<taille; i++)
  504.                     masque[i] = (int*)malloc(taille*sizeof(int));
  505.                    
  506.                 creerMasqueGaussien(masque, taille);
  507.                 imageDest = convolution(image2D, image, masque, taille);
  508.                 break;
  509.             case 7:
  510.                 imageDest = gradientRoberts(image2D, image);
  511.                 break;
  512.             case 8:
  513.                 imageDest = gradientPrewitt(image2D, image);
  514.                 break;
  515.             case 9:
  516.                 imageDest = gradientSobel(image2D, image);
  517.                 break;
  518.             case 10:
  519.                 printf("Choix du Laplacien (4 ou 8): ");
  520.                  scanf(" %d", &taille);
  521.                  masque = (int**)malloc(3*sizeof(int*));
  522.    
  523.                 for (i=0; i<3; i++)
  524.                     masque[i] = (int*)malloc(3*sizeof(int));
  525.                    
  526.                 creerMasqueLaplacien(masque, taille);
  527.                 imageDest = convolution(image2D, image, masque, 3);
  528.                 break;
  529.                
  530.             case 11:
  531.                 imageDest = filtreMedian(image2D, image);
  532.                 break;
  533.             case 12:
  534.                 imageTableau2ImageRGB(imageDest, image);
  535.                 ecrisBMPRGB_Dans(image, "image-convoluer.bmp");
  536.                 break;
  537.             case 13:
  538.                 continuer = false;
  539.                 break;
  540.         }
  541.     }
  542.  
  543.     system("PAUSE");   
  544.     return 0;
  545. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement