Advertisement
kdelemme

Cadeau de noel

Jan 3rd, 2012
149
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 29.82 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "BmpLib.h"
  4.  
  5. #include <String.h>
  6. #include <math.h>
  7.  
  8. #define debug true
  9.  
  10.  
  11. void donneesImageRGB2ImageTableau(unsigned char **imageDest, const DonneesImageRGB *imageSource) {
  12.     if (debug) printf("[DEBUG] Debut de la copie de l'image RGB en niv de gris \n");
  13.    
  14.     int i,j;
  15.  
  16.     for (i=0; i<imageSource->hauteurImage; i++)
  17.         for (j=0; j<imageSource->largeurImage; j++)
  18.         {
  19.             imageDest[i][j] = imageSource->donneesRGB[(i*imageSource->largeurImage + j)*3 + 1];
  20.         }
  21.      if (debug) printf("[DEBUG] Fin de la copie de l'image RGB en niv de gris \n");
  22. }
  23.  
  24.  
  25. void imageTableau2ImageRGB(unsigned char **imageSource, DonneesImageRGB *imageDest) {
  26.    
  27.     if (debug) printf("[DEBUG] Debut de la copie de l'image en niv de gris vers image RGB \n");
  28.     int i,j;
  29.    
  30.     for (i=0; i<imageDest->hauteurImage; i++)
  31.         for (j=0; j<imageDest->largeurImage; j++)
  32.         {
  33.             imageDest->donneesRGB[(i*imageDest->largeurImage + j)*3] = imageSource[i][j];
  34.             imageDest->donneesRGB[(i*imageDest->largeurImage + j)*3 + 1] = imageSource[i][j];
  35.             imageDest->donneesRGB[(i*imageDest->largeurImage + j)*3 + 2] = imageSource[i][j];
  36.         }
  37.     if (debug) printf("[DEBUG] Fin de la copie du tableau en niv de gris vers image RGB \n");
  38. }
  39.  
  40.  
  41. void afficherImageTableau(unsigned char **image, const DonneesImageRGB *imageSource) {
  42.    
  43.     if (debug) printf("[DEBUG] Debut de l'affichage de l'image en niv de gris \n");
  44.     int i, j;
  45.    
  46.     for (i=0; i<imageSource->hauteurImage; i++)
  47.         for (j=0; j<imageSource->largeurImage; j++)
  48.         {
  49.             if (debug) printf("[DEBUG] [%d][%d] = %d\n", i, j, image[i][j]);
  50.         }
  51.     if (debug) printf("[DEBUG] Fin de l'affichage de l'image en niv de gris \n");
  52. }
  53.  
  54.  
  55. void calculHistogramme(unsigned char **image, int largeur, int hauteur, int *histoEntier, float *histoFloat) {
  56.     if (debug) printf("[DEBUG] Debut du calcul de l'histogramme\n");
  57.    
  58.     int i,j;
  59.     /* Initialisation du tableau d'histogramme */
  60.     for(i=0; i<256; i++)
  61.     {
  62.         histoEntier[i] = 0;
  63.         histoFloat[i] = 0.0f;
  64.     }
  65.    
  66.     /* Calcul des histogrammes */
  67.     for (i=0; i<hauteur; i++)
  68.         for(j=0; j<largeur; j++)
  69.         {
  70.             histoEntier[image[i][j]]++;
  71.             histoFloat[image[i][j]]++;  
  72.         }
  73.    
  74.     /* Calcul pour l'histogramme en flottant */
  75.     for (i=0; i<256; i++)
  76.         histoFloat[i] /= largeur*hauteur;
  77.        
  78.     if (debug) printf("[DEBUG] Fin du calcul de l'histogramme\n");
  79.    
  80. }
  81.  
  82. void afficheHistogramme(int *histoEntier, float *histoFloat)
  83. {
  84.     if (debug) printf("[DEBUG] Debut de l'affichage de l'histogramme\n");
  85.     int i;
  86.     for (i=0; i<256; i++)
  87.        if (debug) printf("[DEBUG] H[%d] = %d \t|\tH[%d] = %f\n", i, histoEntier[i], i, histoFloat[i]);
  88.        
  89.     if (debug) printf("[DEBUG] Fin de l'affichage de l'histogramme\n");
  90. }
  91.  
  92. unsigned char** seuillageAutomatiqueEntropie(unsigned char **image2D, DonneesImageRGB *image, float *histoFloat, int *histoEntier, int *seuilEntropieMax) {
  93.    
  94.     if (debug) printf("[DEBUG] Debut du seuillage automatique par maximisation de l'entropie\n");
  95.    
  96.     int s,p;
  97.     double h;
  98.     double h2;
  99.     double hMax = 0.0;
  100.     int nc;
  101.    
  102.     unsigned char **imageDest = (unsigned char **)malloc(image->hauteurImage*sizeof(unsigned char *));
  103.     for (s=0; s<image->hauteurImage; s++)
  104.         imageDest[s] = (unsigned char *)malloc(image->largeurImage*sizeof(unsigned char));
  105.    
  106.    
  107.    
  108.     for (s=0; s<255; s++)
  109.     {
  110.         h = 0.0f;
  111.         h2 = 0.0f;
  112.         nc = 0;
  113.        
  114.         for(p=0; p<s; p++)
  115.         {
  116.             if (histoFloat[p] > 0) h += histoFloat[p] * log(histoFloat[p]);
  117.             nc += histoEntier[p];
  118.         }
  119.         if (nc > 0) h *= -1/nc;
  120.        
  121.         for(p=s+1; p<255; p++)
  122.         {
  123.             if (histoFloat[p] > 0) h2 += histoFloat[p] * log(histoFloat[p]);
  124.         }  
  125.         h2 *= -1/(image->largeurImage*image->hauteurImage - nc);
  126.         //Apparement faut pas faire le dernier calcul
  127.         h += h2 + log(nc * (image->largeurImage*image->hauteurImage - nc));
  128.        
  129.         if (h > hMax)
  130.         {
  131.             hMax = h;
  132.             *seuilEntropieMax = s;  
  133.         }
  134.        
  135.     }
  136.    
  137.     if (debug) printf("[DEBUG] hMax: %f | sMax: %i\n", hMax, *seuilEntropieMax);
  138.    
  139.     /* Maintenant qu'on a la valeur de s qui maximise l'entropie */
  140.     /* Tous les pixels dont le niveau de gris est inferieur a s deviennent noir */
  141.     /* Les autres deviennent blanc */
  142.     for (s=0; s<image->hauteurImage; s++)
  143.         for(p=0; p<image->largeurImage; p++)
  144.         {
  145.             if (image2D[s][p] < *seuilEntropieMax) imageDest[s][p] = 0;
  146.             else imageDest[s][p] = 255;
  147.         }
  148.    
  149.     if (debug) printf("[DEBUG] Fin du seuillage automatique par maximisation de l'entropie\n");
  150.    
  151.     return imageDest;
  152. }
  153.  
  154. unsigned char** convolution(unsigned char **image2D, DonneesImageRGB *image, int **masque, int taille)
  155. {
  156.     if (debug) printf("[DEBUG] Debut de convolution\n");
  157.    
  158.     int i,j,k,l,val,div;
  159.    
  160.     unsigned char **imageDest = (unsigned char **)malloc(image->hauteurImage*sizeof(unsigned char *));
  161.     for (i=0; i<image->hauteurImage; i++)
  162.         imageDest[i] = (unsigned char *)malloc(image->largeurImage*sizeof(unsigned char));
  163.    
  164.     /* Calcul de la somme des coefficients du masque */
  165.     div = 0;    
  166.     for(k=-taille/2; k<=taille/2; k++)
  167.         for(l=-taille/2; l<=taille/2; l++)
  168.         {
  169.             div += (int)masque[k+taille/2][l+taille/2];
  170.         }
  171.    
  172.     /* Convolution de image2D par masque */
  173.     /* sauvegarde du resultat dans imageDest */
  174.     for (i=taille/2; i<image->hauteurImage-taille/2; i++)
  175.         for(j=taille/2; j<image->largeurImage-taille/2; j++)
  176.         {
  177.             val = 0;
  178.             for(k=-taille/2; k<=taille/2; k++)
  179.                 for(l=-taille/2; l<=taille/2; l++)
  180.                     val += masque[k+taille/2][l+taille/2]*image2D[i+k][j+l];
  181.                    
  182.              
  183.             if (div != 0) val /= div;  
  184.             if (val > 255) imageDest[i][j] = 255;
  185.             else if (val < 0) imageDest[i][j] = 0;
  186.             else imageDest[i][j] = val;
  187.         }
  188.    
  189.     if (debug) printf("[DEBUG] Fin de convolution\n");
  190.    
  191.     return imageDest;
  192. }
  193.  
  194. /*
  195. Crée le masque moyenneur de la taille spécifiée
  196. */
  197. void creerMasqueMoyenneur(int **masque, int taille) {
  198.     int i,j;
  199.    
  200.     for (i=0; i<taille; i++)
  201.         for (j=0; j<taille; j++)
  202.             masque[i][j] = 1;
  203. }
  204.  
  205. /*
  206. Crée le masque gaussien 3x3 ou 5x5
  207. */
  208. void creerMasqueGaussien(int **masque, int taille) {
  209.    
  210.     if (taille == 3)
  211.     {
  212.         masque[0][0] = 1;
  213.         masque[0][1] = 2;
  214.         masque[0][2] = 1;
  215.         masque[1][0] = 2;
  216.         masque[1][1] = 4;
  217.         masque[1][2] = 2;
  218.         masque[2][0] = 1;
  219.         masque[2][1] = 2;
  220.         masque[2][2] = 1;
  221.     }
  222.     if (taille == 5)
  223.     {
  224.         masque[0][0] = 1;
  225.         masque[0][1] = 4;
  226.         masque[0][2] = 6;
  227.         masque[0][3] = 4;
  228.         masque[0][4] = 1;
  229.         masque[1][0] = 4;
  230.         masque[1][1] = 16;
  231.         masque[1][2] = 24;
  232.         masque[1][3] = 16;
  233.         masque[1][4] = 4;
  234.         masque[2][0] = 6;
  235.         masque[2][1] = 24;
  236.         masque[2][2] = 36;
  237.         masque[2][3] = 24;
  238.         masque[2][4] = 6;
  239.         masque[3][0] = 4;
  240.         masque[3][1] = 16;
  241.         masque[3][2] = 24;
  242.         masque[3][3] = 16;
  243.         masque[3][4] = 4;
  244.         masque[4][0] = 1;
  245.         masque[4][1] = 4;
  246.         masque[4][2] = 6;
  247.         masque[4][3] = 4;
  248.         masque[4][4] = 1;
  249.     }
  250. }
  251.  
  252. /*
  253. Crée le masque laplacien 4 ou 8
  254. */
  255. void creerMasqueLaplacien(int **masque, int taille) {
  256.    
  257.     if (taille == 4)
  258.     {
  259.         masque[0][0] = 0;
  260.         masque[0][1] = -1;
  261.         masque[0][2] = 0;
  262.         masque[1][0] = -1;
  263.         masque[1][1] = 4;
  264.         masque[1][2] = -1;
  265.         masque[2][0] = 0;
  266.         masque[2][1] = -1;
  267.         masque[2][2] = 0;
  268.     }
  269.     if (taille == 8)
  270.     {
  271.         masque[0][0] = -1;
  272.         masque[0][1] = -1;
  273.         masque[0][2] = -1;
  274.         masque[1][0] = -1;
  275.         masque[1][1] = 8;
  276.         masque[1][2] = -1;
  277.         masque[2][0] = -1;
  278.         masque[2][1] = -1;
  279.         masque[2][2] = -1;
  280.     }
  281. }
  282.  
  283. /*
  284. Crée le masque de la taille spécifiée
  285. et le renvoie.
  286. */
  287. int** creerMasque(int taille) {
  288.     int i,j;
  289.    
  290.     int **masque = (int**)malloc(taille*sizeof(int*));
  291.  
  292.     for (i=0; i<taille; i++)
  293.         masque[i] = (int*)malloc(taille*sizeof(int));
  294.    
  295.     for (i=0; i<taille; i++)
  296.         for(j=0; j<taille; j++)
  297.         {
  298.             printf("MASQUE[%d][%d] = ",i,j);
  299.             scanf(" %d", &masque[i][j]);
  300.         }
  301.        
  302.     return masque;
  303. }
  304.  
  305. /*
  306. Retourne l'image en niveau de gris après application du gradient de Roberts.
  307. */
  308. unsigned char** gradientRoberts(unsigned char ** image2D, DonneesImageRGB* image)
  309. {
  310.     if (debug) printf("[DEBUG] Debut du filtrage par le gradient de Roberts\n");
  311.     int i,j;
  312.     int gx,gy;
  313.    
  314.     unsigned char **imageDest = (unsigned char **)malloc(image->hauteurImage*sizeof(unsigned char *));
  315.     for (i=0; i<image->hauteurImage; i++)
  316.         imageDest[i] = (unsigned char *)malloc(image->largeurImage*sizeof(unsigned char));
  317.        
  318.     for(i=0; i<image->hauteurImage-1; i++)
  319.         for(j=0; j<image->largeurImage-1; j++)
  320.         {
  321.             gx = image2D[i][j+1] - image2D[i][j];
  322.             gy = image2D[i+1][j] - image2D[i][j];
  323.             imageDest[i][j] = sqrt((float)gx*gx + (float)gy*gy);
  324.         }
  325.        
  326.     if (debug) printf("[DEBUG] Fin du filtrage par le gradient de Roberts\n");
  327.     return imageDest;
  328. }
  329.  
  330. /*
  331. Retourne l'image en niveau de gris après application du gradient de Prewitt.
  332. */
  333. unsigned char** gradientPrewitt(unsigned char ** image2D, DonneesImageRGB* image)
  334. {
  335.     if (debug) printf("[DEBUG] Debut du filtrage par le gradient de Prewitt\n");
  336.     int i,j,k,l;
  337.     int gx,gy;
  338.    
  339.     unsigned char **imageDest = (unsigned char **)malloc(image->hauteurImage*sizeof(unsigned char *));
  340.     for (i=0; i<image->hauteurImage; i++)
  341.         imageDest[i] = (unsigned char *)malloc(image->largeurImage*sizeof(unsigned char));
  342.    
  343.     /* Masque de Prewitt */
  344.     int masqueX[3][3] = {{-1,0,1},{-1,0,1},{-1,0,1}};
  345.     int masqueY[3][3] = {{-1,-1,-1},{0,0,0},{1,1,1}};
  346.    
  347.    
  348.     for (i=1; i<image->hauteurImage-1; i++)
  349.         for(j=1; j<image->largeurImage-1; j++)
  350.         {
  351.             gx = 0;
  352.             gy = 0;
  353.             for(k=-1; k<=1; k++)
  354.                 for(l=-1; l<=1; l++)
  355.                 {
  356.                     gx += masqueX[k+1][l+1]*image2D[i+k][j+l];
  357.                     gy += masqueY[k+1][l+1]*image2D[i+k][j+l];
  358.                 }
  359.                    
  360.             imageDest[i][j] = sqrt(gx*gx + gy*gy);
  361.         }
  362.    
  363.     if (debug) printf("[DEBUG] Fin du filtrage par le gradient de Prewitt\n");
  364.     return imageDest;
  365. }
  366.  
  367. /*
  368. Retourne l'image en niveau de gris après application du gradient de Sobel.
  369. */
  370. unsigned char** gradientSobel(unsigned char **image2D, DonneesImageRGB* image)
  371. {
  372.     if (debug) printf("[DEBUG] Debut du filtrage par le gradient de Sobel\n");
  373.     int i,j,k,l;
  374.     int gx,gy;
  375.    
  376.     unsigned char **imageDest = (unsigned char **)malloc(image->hauteurImage*sizeof(unsigned char *));
  377.     for (i=0; i<image->hauteurImage; i++)
  378.         imageDest[i] = (unsigned char *)malloc(image->largeurImage*sizeof(unsigned char));
  379.    
  380.     /* Masque de Sobel */
  381.     int masqueX[3][3] = {{-1,0,1},{-2,0,2},{-1,0,1}};
  382.     int masqueY[3][3] = {{-1,-2,-1},{0,0,0},{1,2,1}};
  383.    
  384.     /* On parcourt tous les pixels de l'image */
  385.     for (i=1; i<image->hauteurImage-1; i++)
  386.         for(j=1; j<image->largeurImage-1; j++)
  387.         {
  388.             gx = 0;
  389.             gy = 0;
  390.             for(k=-1; k<=1; k++)
  391.                 for(l=-1; l<=1; l++)
  392.                 {
  393.                     gx += masqueX[k+1][l+1]*image2D[i+k][j+l];
  394.                     gy += masqueY[k+1][l+1]*image2D[i+k][j+l];
  395.                 }
  396.                    
  397.             imageDest[i][j] = sqrt(gx*gx + gy*gy);
  398.         }
  399.     if (debug) printf("[DEBUG] Fin du filtrage par le gradient de Sobel\n");
  400.     return imageDest;
  401. }
  402.  
  403. unsigned char** filtreMedian(unsigned char **image2D, DonneesImageRGB *image, int **masque, int taille)
  404. {
  405.     if (debug) printf("[DEBUG] Debut du filtrage par le filtre Median\n");
  406.     /* Initialisation */
  407.     int i,j,k,l,cpt = 0, min, indiceMin;
  408.    
  409.     unsigned char **imageDest = (unsigned char **)malloc(image->hauteurImage*sizeof(unsigned char *));
  410.     for (i=0; i<image->hauteurImage; i++)
  411.         imageDest[i] = (unsigned char *)malloc(image->largeurImage*sizeof(unsigned char));
  412.    
  413.  
  414.     /* On compte combien de 1 se trouve dans le masque */
  415.     /* Afin de savoir combien de case contiendra notre tableau à trier */
  416.     for (i=0; i<taille; i++)
  417.         for(j=0; j<taille; j++)
  418.         {
  419.             if (masque[i][j] == 1) cpt++;
  420.         }
  421.     int *tab = (int*)malloc(cpt*sizeof(int));
  422.    
  423.     /* On parcour l'ensemble de l'image2D */
  424.     /* En chacun de ses pixels, on calcul la valeur médiane des niv de gris contenus dans le masque */
  425.     /* On donne la valeur médiane au pixel */
  426.    
  427.     for(i=taille/2; i<image->hauteurImage-taille/2; i++)
  428.         for(j=taille/2; j<image->largeurImage-taille/2; j++)
  429.         {
  430.             cpt = 0;
  431.             for(k=-taille/2; k<=taille/2; k++)
  432.                 for(l=-taille/2; l<=taille/2; l++)
  433.                 {
  434.                     if (masque[k+taille/2][l+taille/2] == 1)
  435.                     {
  436.                         tab[cpt] = image2D[i+k][j+l];
  437.                         cpt++;
  438.                     }
  439.                 }
  440.            
  441.             /* On tri le tableau */
  442.  
  443.             for (k=0; k<cpt-1; k++)
  444.             {
  445.                 min = tab[k];
  446.                 indiceMin = k;
  447.                 for(l=k+1; l<cpt; l++)
  448.                 {
  449.                    if (tab[l] < min)
  450.                    {
  451.                      min = tab[l];
  452.                      indiceMin = l;  
  453.                     }
  454.                 }
  455.                 tab[indiceMin] = tab[k];
  456.                 tab[k] = min;
  457.             }
  458.            
  459.             /* On prend la valeur médiane et on la met dans imageDest[i][j] */
  460.             imageDest[i][j] = tab[cpt/2];
  461.         }
  462.     if (debug) printf("[DEBUG] Fin du filtrage par le filtre median\n");
  463.     return imageDest;
  464. }
  465.  
  466. /*
  467. Retourne l'image dilatée en niveau de gris.
  468. On recherche pour chaque pixel, le pixel maximum présent dans son voisinage
  469. On sauvegarde ce maximum dans l'image destinataire.
  470. */
  471. unsigned char** dilatation(unsigned char** image2D, DonneesImageRGB* image, int** masque, int taille)
  472. {
  473.     if (debug) printf("[DEBUG] Debut de la dilatation\n");
  474.     int i,j,k,l,sup;
  475.    
  476.     unsigned char **imageDest = (unsigned char **)malloc(image->hauteurImage*sizeof(unsigned char *));
  477.     for (i=0; i<image->hauteurImage; i++)
  478.         imageDest[i] = (unsigned char *)malloc(image->largeurImage*sizeof(unsigned char));
  479.    
  480.     for(i=taille/2; i<image->hauteurImage-taille/2; i++)
  481.         for(j=taille/2; j<image->largeurImage-taille/2; j++)
  482.         {
  483.             sup = image2D[i][j];
  484.             for(k=-taille/2; k<=taille/2; k++)
  485.                 for(l=-taille/2; l<=taille/2; l++)
  486.                 {
  487.                        if (image2D[i+k][j+l] > sup && masque[k+taille/2][l+taille/2] == 1) sup = image2D[i+k][j+l];
  488.                 }
  489.             imageDest[i][j] = sup;
  490.         }
  491.        
  492.     if (debug) printf("[DEBUG] Fin de la dilatation\n");
  493.     return imageDest;
  494. }
  495.  
  496. /*
  497. Retourne l'image erodée en niveau de gris.
  498. Pour chaque pixel, on recherche le pixel de valeur minimum présent dans son voisinage
  499. On sauvegarde ce minimum dans l'image destinataire.
  500. */
  501. unsigned char** erosion(unsigned char** image2D, DonneesImageRGB* image, int** masque, int taille)
  502. {
  503.     if (debug) printf("[DEBUG] Debut de l'erosion\n");
  504.     int i,j,k,l,inf;
  505.    
  506.     unsigned char **imageDest = (unsigned char **)malloc(image->hauteurImage*sizeof(unsigned char *));
  507.     for (i=0; i<image->hauteurImage; i++)
  508.         imageDest[i] = (unsigned char *)malloc(image->largeurImage*sizeof(unsigned char));
  509.    
  510.     for(i=taille/2; i<image->hauteurImage-taille/2; i++)
  511.         for(j=taille/2; j<image->largeurImage-taille/2; j++)
  512.         {
  513.             inf = image2D[i][j];
  514.             for(k=-taille/2; k<=taille/2; k++)
  515.                 for(l=-taille/2; l<=taille/2; l++)
  516.                 {
  517.                        if (image2D[i+k][j+l] < inf && masque[k+taille/2][l+taille/2] == 1) inf = image2D[i+k][j+l];
  518.                 }
  519.             imageDest[i][j] = inf;
  520.         }
  521.        
  522.     if (debug) printf("[DEBUG] Fin de l'erosion\n");
  523.     return imageDest;
  524. }
  525.  
  526. /*
  527. Retourne l'image difference entre imageDest1 et imageDest2 en niveau de gris.
  528. Pour chaque pixel, on effectue la soustraction entre imageDest1 et imageDest2.
  529. Si la difference est négative, on met le pixel à 0.
  530. */
  531. unsigned char** difference(unsigned char **imageDest1, unsigned char **imageDest2, DonneesImageRGB *image)
  532. {
  533.     if (debug) printf("[DEBUG] Debut de la difference\n");
  534.     int i,j;
  535.    
  536.     unsigned char **imageDest = (unsigned char **)malloc(image->hauteurImage*sizeof(unsigned char *));
  537.     for (i=0; i<image->hauteurImage; i++)
  538.         imageDest[i] = (unsigned char *)malloc(image->largeurImage*sizeof(unsigned char));
  539.        
  540.     for (i=0; i<image->hauteurImage; i++)
  541.         for(j=0; j<image->largeurImage; j++)
  542.         {
  543.             if (imageDest1[i][j] < imageDest2[i][j]) imageDest[i][j] = 0;
  544.             else imageDest[i][j] = imageDest1[i][j] - imageDest2[i][j];
  545.         }
  546.     if (debug) printf("[DEBUG] Fin de la difference\n");
  547.     return imageDest;
  548. }
  549.  
  550.  
  551. /*
  552. Retourne le perimetre de chaque forme de l'image.
  553. Parcour l'ensemble de l'image, pour chaque pixel (i,j),
  554. on regarde si il touche au moins un pixel noir
  555. si c'est le cas, c'est un pixel du contour, on incrémente le cpt
  556. */
  557. int calculPerimetre(unsigned char **imageDest, DonneesImageRGB *image)
  558. {
  559.     if (debug) printf("[DEBUG] Debut du calcul du perimetre\n");
  560.     int i,j, cpt=0, k, l;
  561.     bool estContour = false;
  562.    
  563.     for(i=1; i<image->hauteurImage-1; i++)
  564.         for(j=1; j<image->largeurImage-1; j++)
  565.         {
  566.             estContour = false;
  567.             for(k=-1;k<=1;k++)
  568.                 for(l=-1;l<=1;l++)
  569.                 {
  570.                     if (imageDest[i][j] == 255)
  571.                     {
  572.                         if (imageDest[i+k][j+l] == 0) estContour = true;    
  573.                     }
  574.                 }
  575.             if (estContour) cpt++;
  576.         }
  577.    
  578.     if (debug) printf("[DEBUG] Fin du calcul du perimetre\n");
  579.     return cpt;  
  580. }
  581.  
  582. /*
  583. Retourne le nombre de pixel blanc correspondant à la surface des formes présentes sur l'image
  584. */
  585. int calculSurface(unsigned char **imageDest, DonneesImageRGB *image)
  586. {
  587.     if (debug) printf("[DEBUG] Debut du calcul de la surface\n");
  588.     int i,j, cpt=0;
  589.    
  590.     for(i=0; i<image->hauteurImage; i++)
  591.         for(j=0; j<image->largeurImage; j++)
  592.             if (imageDest[i][j] == 255)
  593.                 cpt++;
  594.     if (debug) printf("[DEBUG] Fin du calcul de la surface\n");
  595.     return cpt;
  596. }
  597.  
  598. /*
  599. Retourne la circularite Geometrique suivant le perimetre et la surface passés en parametre
  600. */
  601. float circulariteGeometrique(int perimetre, int surface)
  602. {
  603.     float res = 4*3.1415*(float)surface/((float)perimetre*(float)perimetre);
  604.     return res;
  605. }
  606.  
  607. /*
  608. Algorithme de Crofton
  609. P = pi/4*(a*(N0+N90) + a*rac(2)/2*(N45+N135))
  610. a = distance horizontale entre deux pixels
  611. */
  612. float perimetreCrofton(unsigned char **image2D, DonneesImageRGB *image)
  613. {
  614.     int i,j,k,l,nbPixNoir;
  615.     /* etiquette[0] = N0, etiquette[1] = N45, etiquette[2] = N90, etiquette[3] = N135 */
  616.     int etiquette[4] = {0,0,0,0};
  617.     float crofton = 0.0f;
  618.    
  619.     unsigned char **imageDest = (unsigned char **)malloc(image->hauteurImage*sizeof(unsigned char *));
  620.     for (i=0; i<image->hauteurImage; i++)
  621.         imageDest[i] = (unsigned char *)malloc(image->largeurImage*sizeof(unsigned char));
  622.    
  623.     /* On conserve simplement les points du contour */
  624.     for (i=1;i<image->hauteurImage-1;i++)
  625.         for(j=1;j<image->largeurImage-1;j++)
  626.         {
  627.             nbPixNoir = 0;
  628.             if (image2D[i][j] == 255)
  629.             {
  630.                 for(k=-1;k<=1;k++)
  631.                     for(l=-1;l<=1;l++)
  632.                     {
  633.                         if (image2D[i+k][j+l] == 0) nbPixNoir++;  
  634.                     }
  635.                 if (nbPixNoir < 2) imageDest[i][j] = 0;
  636.                 else imageDest[i][j] = 255;
  637.             }
  638.         }
  639.    
  640.     /* Recherche de la direction des points */
  641.     for(i=1;i<image->hauteurImage-1;i++)
  642.         for(j=1;j<image->largeurImage-1;j++)
  643.             if (imageDest[i][j] == 255)
  644.             {
  645.                 if (imageDest[i][j+1] == 255) etiquette[0]++; //0 degres
  646.                 else if (imageDest[i-1][j+1] == 255) etiquette[1]++; //45 degres
  647.                 else if (imageDest[i-1][j] == 255) etiquette[2]++; //90 degres
  648.                 else if (imageDest[i-1][j-1] == 255) etiquette[3]++; //135 degres
  649.             }
  650.            
  651.     crofton = 3.1415/4.0*((float)etiquette[0]+(float)etiquette[2] + (sqrt(2)/2.0)*((float)etiquette[1]+(float)etiquette[3]));
  652.     return crofton;
  653. }
  654.  
  655. /*
  656. Moment cours:
  657.     Crofton -> approximation du périmetre meilleur que par comptage de point
  658.     Surface -> Comptage de point ou comptage de point intérieurs + périmetre
  659. */
  660.  
  661. int main(int argc, char *argv[])
  662. {
  663.    
  664.     printf("TRAITEMENT D'IMAGES\n\n");
  665.    
  666.     DonneesImageRGB *image = (DonneesImageRGB *)malloc(sizeof(DonneesImageRGB));
  667.     char *fichier = (char *)malloc(50*sizeof(char));
  668.    
  669.     int choixMenu, seuilEntropieMax = 0, i =0, taille = 3;
  670.     int perimetre = 0;
  671.     int surface = 0;
  672.     int *histoEntier = (int *)malloc(256*sizeof(int));
  673.     float *histoFloat = (float *)malloc(256*sizeof(int));
  674.     bool continuer = true;
  675.     int **masque = NULL;
  676.    
  677.     do{
  678.         printf("Entrez le nom de l'image: ");
  679.         scanf("%49s", fichier);
  680.         image = lisBMPRGB(fichier);
  681.     }while(image == NULL);
  682.    
  683.     /* Allocation du tableau 2 dimensions contenant l'image en niveau de gris */
  684.     unsigned char **imageDest = NULL;
  685.     unsigned char **imageDest1 = NULL;
  686.     unsigned char **imageDest2 = NULL;
  687.     unsigned char **image2D = (unsigned char **)malloc(image->hauteurImage*sizeof(unsigned char *));
  688.     for (i=0; i<image->hauteurImage; i++)
  689.         image2D[i] = (unsigned char *)malloc(image->largeurImage*sizeof(unsigned char));
  690.    
  691.     /* Copie des donnéesRGB de image dans le tableau d'unsigned char à 2 dimensions */
  692.     donneesImageRGB2ImageTableau(image2D, image);
  693.  
  694.     printf("L'image est bien converti en niveau de gris...\n");
  695.    
  696.     while (continuer) {
  697.         do
  698.         {
  699.             printf("MENU\n");
  700.             printf("1. Afficher le tableau de l'image en niveau de gris\n");
  701.             printf("2. Calculer l'histogramme\n");
  702.             printf("3. Afficher l'histogramme\n");
  703.             printf("4. Seuillage Automatique par Maximisation de l'Entropie\n");
  704.             printf("5. Convolution par un filtre moyenneur\n");
  705.             printf("6. Convolution par un filtre gaussien\n");
  706.             printf("7. Gradient de Roberts\n");
  707.             printf("8. Gradient de Prewitt\n");
  708.             printf("9. Gradient de Sobel\n");
  709.             printf("10. Laplacien (4 ou 8)\n");
  710.             printf("11. Filtre Median\n");
  711.             printf("12. Dilatation\n");
  712.             printf("13. Erosion\n");
  713.             printf("14. Ouverture (Erosion + Dilatation)\n");
  714.             printf("15. Fermeture (Dilatation + Erosion)\n");
  715.             printf("16. Gradient Morphologique (Dilatation - Erosion)\n");
  716.             printf("17. Circularite Geometrique (Comptage de points)\n");
  717.             printf("18. Circularite Geometrique (Crofton)\n");
  718.             printf("19. Sauvegarder l'image\n");
  719.             printf("20. QUITTER\n");
  720.             printf("Choix: ");
  721.             scanf("%d", &choixMenu);
  722.         }while(choixMenu < 1 || choixMenu > 20);
  723.        
  724.         switch(choixMenu)
  725.         {
  726.             case 1:
  727.                 afficherImageTableau(image2D, image);
  728.                 break;
  729.             case 2:
  730.                 calculHistogramme(image2D, image->largeurImage, image->hauteurImage, histoEntier, histoFloat);
  731.                 break;
  732.             case 3:
  733.                 afficheHistogramme(histoEntier, histoFloat);
  734.                 break;
  735.             case 4:
  736.                 imageDest = seuillageAutomatiqueEntropie(image2D, image, histoFloat, histoEntier, &seuilEntropieMax);
  737.                 break;
  738.             case 5:
  739.                  printf("Entrez la taille du masque: ");
  740.                  scanf(" %d", &taille);
  741.                  masque = (int**)malloc(taille*sizeof(int*));
  742.    
  743.                 for (i=0; i<taille; i++)
  744.                     masque[i] = (int*)malloc(taille*sizeof(int));
  745.                    
  746.                 creerMasqueMoyenneur(masque, taille);
  747.                 imageDest = convolution(image2D, image, masque, taille);
  748.                 break;
  749.             case 6:
  750.                  printf("Entrez la taille du masque: ");
  751.                  scanf(" %d", &taille);
  752.                  masque = (int**)malloc(taille*sizeof(int*));
  753.    
  754.                 for (i=0; i<taille; i++)
  755.                     masque[i] = (int*)malloc(taille*sizeof(int));
  756.                    
  757.                 creerMasqueGaussien(masque, taille);
  758.                 imageDest = convolution(image2D, image, masque, taille);
  759.                 break;
  760.             case 7:
  761.                 imageDest = gradientRoberts(image2D, image);
  762.                 break;
  763.             case 8:
  764.                 imageDest = gradientPrewitt(image2D, image);
  765.                 break;
  766.             case 9:
  767.                 imageDest = gradientSobel(image2D, image);
  768.                 break;
  769.             case 10:
  770.                 printf("Choix du Laplacien (4 ou 8): ");
  771.                 scanf(" %d", &taille);
  772.                 masque = (int**)malloc(3*sizeof(int*));
  773.    
  774.                 for (i=0; i<3; i++)
  775.                     masque[i] = (int*)malloc(3*sizeof(int));
  776.                    
  777.                 creerMasqueLaplacien(masque, taille);
  778.                 imageDest = convolution(image2D, image, masque, 3);
  779.                 break;
  780.                
  781.             case 11:
  782.                 printf("Entrez la taille du masque: ");
  783.                 scanf(" %d", &taille);          
  784.                 masque = creerMasque(taille);
  785.                
  786.                 imageDest = filtreMedian(image2D, image, masque, taille);
  787.                 break;
  788.                
  789.             case 12:
  790.                 printf("Entrez la taille du masque: ");
  791.                 scanf(" %d", &taille);          
  792.                 masque = creerMasque(taille);
  793.                
  794.                 imageDest = dilatation(image2D, image, masque, taille);
  795.                 break;
  796.            
  797.             case 13:
  798.                 printf("Entrez la taille du masque: ");
  799.                 scanf(" %d", &taille);
  800.                  
  801.                 creerMasque(taille);
  802.                 imageDest = erosion(image2D, image, masque, taille);
  803.                 break;
  804.                
  805.             case 14:
  806.                 printf("Entrez la taille du masque: ");
  807.                 scanf(" %d", &taille);
  808.                    
  809.                 masque = creerMasque(taille);
  810.                 imageDest = erosion(image2D, image, masque, taille);
  811.                 imageDest = dilatation(imageDest, image, masque, taille);
  812.                 break;
  813.                
  814.             case 15:
  815.                 printf("Entrez la taille du masque: ");
  816.                 scanf(" %d", &taille);
  817.                    
  818.                 masque = creerMasque(taille);
  819.                 imageDest = dilatation(image2D, image, masque, taille);
  820.                 imageDest = erosion(imageDest, image, masque, taille);
  821.                 break;
  822.                
  823.             case 16:
  824.                 printf("Entrez la taille du masque: ");
  825.                 scanf(" %d", &taille);
  826.                    
  827.                 masque = creerMasque(taille);
  828.                 imageDest1 = dilatation(image2D, image, masque, taille);
  829.                
  830.                 imageDest2 = erosion(image2D, image, masque, taille);
  831.                
  832.                 imageDest = difference(imageDest1, imageDest2, image);
  833.                
  834.                
  835.                 break;
  836.            
  837.             case 17:
  838.                 perimetre = calculPerimetre(image2D, image);
  839.                 printf("Perimetre: %d - Total: %d\n", perimetre, image->hauteurImage*image->largeurImage);
  840.                
  841.                 surface = calculSurface(image2D, image);
  842.                 printf("Surface: %d - Total: %d\n", surface, image->hauteurImage*image->largeurImage);
  843.                
  844.                 printf("Circularite Geometrique: %f\n", circulariteGeometrique(perimetre, surface));
  845.                 break;
  846.            
  847.             case 18:
  848.                 perimetre = perimetreCrofton(image2D, image);
  849.                 printf("Perimetre: %d - Total: %d\n", perimetre, image->hauteurImage*image->largeurImage);
  850.                
  851.                 surface = calculSurface(image2D, image);
  852.                 printf("Surface: %d - Total: %d\n", surface, image->hauteurImage*image->largeurImage);
  853.                
  854.                 printf("Circularite Geometrique (Crofton): %f\n", circulariteGeometrique(perimetre, surface));
  855.                 break;
  856.                
  857.             case 19:
  858.                 imageTableau2ImageRGB(imageDest, image);
  859.                 ecrisBMPRGB_Dans(image, "image-convoluer.bmp");
  860.                 break;
  861.                
  862.             case 20:
  863.                 continuer = false;
  864.                 break;
  865.         }
  866.     }
  867.  
  868.     system("PAUSE");   
  869.     return 0;
  870. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement