Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include "BmpLib.h"
- #include <String.h>
- #include <math.h>
- #define debug true
- void donneesImageRGB2ImageTableau(unsigned char **imageDest, const DonneesImageRGB *imageSource) {
- if (debug) printf("[DEBUG] Debut de la copie de l'image RGB en niv de gris \n");
- int i,j;
- for (i=0; i<imageSource->hauteurImage; i++)
- for (j=0; j<imageSource->largeurImage; j++)
- {
- imageDest[i][j] = imageSource->donneesRGB[(i*imageSource->largeurImage + j)*3 + 1];
- }
- if (debug) printf("[DEBUG] Fin de la copie de l'image RGB en niv de gris \n");
- }
- void imageTableau2ImageRGB(unsigned char **imageSource, DonneesImageRGB *imageDest) {
- if (debug) printf("[DEBUG] Debut de la copie de l'image en niv de gris vers image RGB \n");
- int i,j;
- for (i=0; i<imageDest->hauteurImage; i++)
- for (j=0; j<imageDest->largeurImage; j++)
- {
- imageDest->donneesRGB[(i*imageDest->largeurImage + j)*3] = imageSource[i][j];
- imageDest->donneesRGB[(i*imageDest->largeurImage + j)*3 + 1] = imageSource[i][j];
- imageDest->donneesRGB[(i*imageDest->largeurImage + j)*3 + 2] = imageSource[i][j];
- }
- if (debug) printf("[DEBUG] Fin de la copie du tableau en niv de gris vers image RGB \n");
- }
- void afficherImageTableau(unsigned char **image, const DonneesImageRGB *imageSource) {
- if (debug) printf("[DEBUG] Debut de l'affichage de l'image en niv de gris \n");
- int i, j;
- for (i=0; i<imageSource->hauteurImage; i++)
- for (j=0; j<imageSource->largeurImage; j++)
- {
- if (debug) printf("[DEBUG] [%d][%d] = %d\n", i, j, image[i][j]);
- }
- if (debug) printf("[DEBUG] Fin de l'affichage de l'image en niv de gris \n");
- }
- void calculHistogramme(unsigned char **image, int largeur, int hauteur, int *histoEntier, float *histoFloat) {
- if (debug) printf("[DEBUG] Debut du calcul de l'histogramme\n");
- int i,j;
- /* Initialisation du tableau d'histogramme */
- for(i=0; i<256; i++)
- {
- histoEntier[i] = 0;
- histoFloat[i] = 0.0f;
- }
- /* Calcul des histogrammes */
- for (i=0; i<hauteur; i++)
- for(j=0; j<largeur; j++)
- {
- histoEntier[image[i][j]]++;
- histoFloat[image[i][j]]++;
- }
- /* Calcul pour l'histogramme en flottant */
- for (i=0; i<256; i++)
- histoFloat[i] /= largeur*hauteur;
- if (debug) printf("[DEBUG] Fin du calcul de l'histogramme\n");
- }
- void afficheHistogramme(int *histoEntier, float *histoFloat)
- {
- if (debug) printf("[DEBUG] Debut de l'affichage de l'histogramme\n");
- int i;
- for (i=0; i<256; i++)
- if (debug) printf("[DEBUG] H[%d] = %d \t|\tH[%d] = %f\n", i, histoEntier[i], i, histoFloat[i]);
- if (debug) printf("[DEBUG] Fin de l'affichage de l'histogramme\n");
- }
- unsigned char** seuillageAutomatiqueEntropie(unsigned char **image2D, DonneesImageRGB *image, float *histoFloat, int *histoEntier, int *seuilEntropieMax) {
- if (debug) printf("[DEBUG] Debut du seuillage automatique par maximisation de l'entropie\n");
- int s,p;
- double h;
- double h2;
- double hMax = 0.0;
- int nc;
- unsigned char **imageDest = (unsigned char **)malloc(image->hauteurImage*sizeof(unsigned char *));
- for (s=0; s<image->hauteurImage; s++)
- imageDest[s] = (unsigned char *)malloc(image->largeurImage*sizeof(unsigned char));
- for (s=0; s<255; s++)
- {
- h = 0.0f;
- h2 = 0.0f;
- nc = 0;
- for(p=0; p<s; p++)
- {
- if (histoFloat[p] > 0) h += histoFloat[p] * log(histoFloat[p]);
- nc += histoEntier[p];
- }
- if (nc > 0) h *= -1/nc;
- for(p=s+1; p<255; p++)
- {
- if (histoFloat[p] > 0) h2 += histoFloat[p] * log(histoFloat[p]);
- }
- h2 *= -1/(image->largeurImage*image->hauteurImage - nc);
- //Apparement faut pas faire le dernier calcul
- h += h2 + log(nc * (image->largeurImage*image->hauteurImage - nc));
- if (h > hMax)
- {
- hMax = h;
- *seuilEntropieMax = s;
- }
- }
- if (debug) printf("[DEBUG] hMax: %f | sMax: %i\n", hMax, *seuilEntropieMax);
- /* Maintenant qu'on a la valeur de s qui maximise l'entropie */
- /* Tous les pixels dont le niveau de gris est inferieur a s deviennent noir */
- /* Les autres deviennent blanc */
- for (s=0; s<image->hauteurImage; s++)
- for(p=0; p<image->largeurImage; p++)
- {
- if (image2D[s][p] < *seuilEntropieMax) imageDest[s][p] = 0;
- else imageDest[s][p] = 255;
- }
- if (debug) printf("[DEBUG] Fin du seuillage automatique par maximisation de l'entropie\n");
- return imageDest;
- }
- unsigned char** convolution(unsigned char **image2D, DonneesImageRGB *image, int **masque, int taille) {
- int i,j,k,l,val,div;
- unsigned char **imageDest = (unsigned char **)malloc(image->hauteurImage*sizeof(unsigned char *));
- for (i=0; i<image->hauteurImage; i++)
- imageDest[i] = (unsigned char *)malloc(image->largeurImage*sizeof(unsigned char));
- /* Calcul de la somme des coefficients du masque */
- div = 0;
- for(k=-taille/2; k<=taille/2; k++)
- for(l=-taille/2; l<=taille/2; l++)
- {
- div += (int)masque[k+taille/2][l+taille/2];
- }
- /* Convolution de image2D par masque */
- /* sauvegarde du resultat dans imageDest */
- for (i=taille/2; i<image->hauteurImage-taille/2; i++)
- for(j=taille/2; j<image->largeurImage-taille/2; j++)
- {
- val = 0;
- for(k=-taille/2; k<=taille/2; k++)
- for(l=-taille/2; l<=taille/2; l++)
- val += masque[k+taille/2][l+taille/2]*image2D[i+k][j+l];
- if (div != 0) val /= div;
- if (val > 255) imageDest[i][j] = 255;
- else if (val < 0) imageDest[i][j] = 0;
- else imageDest[i][j] = val;
- }
- return imageDest;
- }
- void creerMasqueMoyenneur(int **masque, int taille) {
- int i,j;
- for (i=0; i<taille; i++)
- for (j=0; j<taille; j++)
- masque[i][j] = 1;
- }
- void creerMasqueGaussien(int **masque, int taille) {
- if (taille == 3)
- {
- masque[0][0] = 1;
- masque[0][1] = 2;
- masque[0][2] = 1;
- masque[1][0] = 2;
- masque[1][1] = 4;
- masque[1][2] = 2;
- masque[2][0] = 1;
- masque[2][1] = 2;
- masque[2][2] = 1;
- }
- if (taille == 5)
- {
- masque[0][0] = 1;
- masque[0][1] = 4;
- masque[0][2] = 6;
- masque[0][3] = 4;
- masque[0][4] = 1;
- masque[1][0] = 4;
- masque[1][1] = 16;
- masque[1][2] = 24;
- masque[1][3] = 16;
- masque[1][4] = 4;
- masque[2][0] = 6;
- masque[2][1] = 24;
- masque[2][2] = 36;
- masque[2][3] = 24;
- masque[2][4] = 6;
- masque[3][0] = 4;
- masque[3][1] = 16;
- masque[3][2] = 24;
- masque[3][3] = 16;
- masque[3][4] = 4;
- masque[4][0] = 1;
- masque[4][1] = 4;
- masque[4][2] = 6;
- masque[4][3] = 4;
- masque[4][4] = 1;
- }
- }
- void creerMasqueLaplacien(int **masque, int taille) {
- if (taille == 4)
- {
- masque[0][0] = 0;
- masque[0][1] = -1;
- masque[0][2] = 0;
- masque[1][0] = -1;
- masque[1][1] = 4;
- masque[1][2] = -1;
- masque[2][0] = 0;
- masque[2][1] = -1;
- masque[2][2] = 0;
- }
- if (taille == 8)
- {
- masque[0][0] = -1;
- masque[0][1] = -1;
- masque[0][2] = -1;
- masque[1][0] = -1;
- masque[1][1] = 8;
- masque[1][2] = -1;
- masque[2][0] = -1;
- masque[2][1] = -1;
- masque[2][2] = -1;
- }
- }
- unsigned char** gradientRoberts(unsigned char ** image2D, DonneesImageRGB* image)
- {
- int i,j;
- int gx,gy;
- unsigned char **imageDest = (unsigned char **)malloc(image->hauteurImage*sizeof(unsigned char *));
- for (i=0; i<image->hauteurImage; i++)
- imageDest[i] = (unsigned char *)malloc(image->largeurImage*sizeof(unsigned char));
- for(i=0; i<image->hauteurImage-1; i++)
- for(j=0; j<image->largeurImage-1; j++)
- {
- gx = image2D[i][j+1] - image2D[i][j];
- gy = image2D[i+1][j] - image2D[i][j];
- imageDest[i][j] = sqrt((float)gx*gx + (float)gy*gy);
- }
- return imageDest;
- }
- unsigned char** gradientPrewitt(unsigned char ** image2D, DonneesImageRGB* image)
- {
- int i,j,k,l;
- int gx,gy;
- unsigned char **imageDest = (unsigned char **)malloc(image->hauteurImage*sizeof(unsigned char *));
- for (i=0; i<image->hauteurImage; i++)
- imageDest[i] = (unsigned char *)malloc(image->largeurImage*sizeof(unsigned char));
- int masqueX[3][3] = {{-1,0,1},{-1,0,1},{-1,0,1}};
- int masqueY[3][3] = {{-1,-1,-1},{0,0,0},{1,1,1}};
- for (i=1; i<image->hauteurImage-1; i++)
- for(j=1; j<image->largeurImage-1; j++)
- {
- gx = 0;
- gy = 0;
- for(k=-1; k<=1; k++)
- for(l=-1; l<=1; l++)
- {
- gx += masqueX[k+1][l+1]*image2D[i+k][j+l];
- gy += masqueY[k+1][l+1]*image2D[i+k][j+l];
- }
- imageDest[i][j] = sqrt(gx*gx + gy*gy);
- }
- return imageDest;
- }
- unsigned char** gradientSobel(unsigned char **image2D, DonneesImageRGB* image)
- {
- int i,j,k,l;
- int gx,gy;
- unsigned char **imageDest = (unsigned char **)malloc(image->hauteurImage*sizeof(unsigned char *));
- for (i=0; i<image->hauteurImage; i++)
- imageDest[i] = (unsigned char *)malloc(image->largeurImage*sizeof(unsigned char));
- int masqueX[3][3] = {{-1,0,1},{-2,0,2},{-1,0,1}};
- int masqueY[3][3] = {{-1,-2,-1},{0,0,0},{1,2,1}};
- for (i=1; i<image->hauteurImage-1; i++)
- for(j=1; j<image->largeurImage-1; j++)
- {
- gx = 0;
- gy = 0;
- for(k=-1; k<=1; k++)
- for(l=-1; l<=1; l++)
- {
- gx += masqueX[k+1][l+1]*image2D[i+k][j+l];
- gy += masqueY[k+1][l+1]*image2D[i+k][j+l];
- }
- imageDest[i][j] = sqrt(gx*gx + gy*gy);
- }
- return imageDest;
- }
- unsigned char** filtreMedian(unsigned char **image2D, DonneesImageRGB *image)
- {
- /* Initialisation */
- int i,j,k,l,taille,cpt = 0, min, indiceMin;
- unsigned char **imageDest = (unsigned char **)malloc(image->hauteurImage*sizeof(unsigned char *));
- for (i=0; i<image->hauteurImage; i++)
- imageDest[i] = (unsigned char *)malloc(image->largeurImage*sizeof(unsigned char));
- printf("Taille du masque: ");
- scanf("%d", &taille);
- int **masque = (int **)malloc(taille*sizeof(int*));
- for (i=0; i<taille; i++)
- masque[i] = (int*)malloc(taille*sizeof(int));
- /* Remplissage du masque avec des 1 ou 0 */
- for (i=0; i<taille; i++)
- for(j=0; j<taille; j++)
- {
- printf("MASQUE[%d][%d] = ", i, j);
- scanf("%d", &masque[i][j]);
- if (masque[i][j] == 1) cpt++;
- }
- int *tab = (int*)malloc(cpt*sizeof(int));
- /* On parcour l'ensemble de l'image2D */
- /* En chacun de ses pixels, on calcul la valeur médiane des niv de gris contenus dans le masque */
- /* On donne la valeur médiane au pixel */
- for(i=1; i<image->hauteurImage-1; i++)
- for(j=1; j<image->largeurImage-1; j++)
- {
- cpt = 0;
- for(k=-taille/2; k<=taille/2; k++)
- for(l=-taille/2; l<=taille/2; l++)
- {
- if (masque[k+taille/2][l+taille/2] == 1)
- {
- tab[cpt] = image2D[i+k][j+l];
- cpt++;
- }
- }
- /* On tri le tableau */
- for (k=0; k<cpt-1; k++)
- {
- min = tab[k];
- for(l=k; l<cpt; l++)
- {
- if (tab[l] < min)
- {
- min = tab[l];
- indiceMin = l;
- }
- }
- tab[indiceMin] = tab[k];
- tab[k] = min;
- }
- /* On prend la valeur médiane et on la met dans imageDest[i][j] */
- imageDest[i][j] = tab[cpt/2];
- }
- return imageDest;
- }
- int main(int argc, char *argv[])
- {
- printf("TRAITEMENT D'IMAGES\n\n");
- DonneesImageRGB *image = (DonneesImageRGB *)malloc(sizeof(DonneesImageRGB));
- char *fichier = (char *)malloc(50*sizeof(char));
- int choixMenu, seuilEntropieMax = 0, i =0, taille = 3;
- int *histoEntier = (int *)malloc(256*sizeof(int));
- float *histoFloat = (float *)malloc(256*sizeof(int));
- bool continuer = true;
- int **masque = NULL;
- do{
- printf("Entrez le nom de l'image: ");
- scanf("%49s", fichier);
- image = lisBMPRGB(fichier);
- }while(image == NULL);
- /* Allocation du tableau 2 dimensions contenant l'image en niveau de gris */
- unsigned char **imageDest = NULL;
- unsigned char **image2D = (unsigned char **)malloc(image->hauteurImage*sizeof(unsigned char *));
- for (i=0; i<image->hauteurImage; i++)
- image2D[i] = (unsigned char *)malloc(image->largeurImage*sizeof(unsigned char));
- /* Copie des donnéesRGB de image dans le tableau d'unsigned char à 2 dimensions */
- donneesImageRGB2ImageTableau(image2D, image);
- printf("L'image est bien converti en niveau de gris...\n");
- while (continuer) {
- do
- {
- printf("MENU\n");
- printf("1. Afficher le tableau de l'image en niveau de gris\n");
- printf("2. Calculer l'histogramme\n");
- printf("3. Afficher l'histogramme\n");
- printf("4. Seuillage Automatique par Maximisation de l'Entropie\n");
- printf("5. Convolution par un filtre moyenneur\n");
- printf("6. Convolution par un filtre gaussien\n");
- printf("7. Gradient de Roberts\n");
- printf("8. Gradient de Prewitt\n");
- printf("9. Gradient de Sobel\n");
- printf("10. Laplacien (4 ou 8)\n");
- printf("11. Filtre Median\n");
- printf("12. Sauvegarder l'image\n");
- printf("13. QUITTER\n");
- printf("Choix: ");
- scanf("%d", &choixMenu);
- }while(choixMenu < 1 || choixMenu > 13);
- switch(choixMenu)
- {
- case 1:
- afficherImageTableau(image2D, image);
- break;
- case 2:
- calculHistogramme(image2D, image->largeurImage, image->hauteurImage, histoEntier, histoFloat);
- break;
- case 3:
- afficheHistogramme(histoEntier, histoFloat);
- break;
- case 4:
- imageDest = seuillageAutomatiqueEntropie(image2D, image, histoFloat, histoEntier, &seuilEntropieMax);
- break;
- case 5:
- printf("Entrez la taille du masque: ");
- scanf(" %d", &taille);
- masque = (int**)malloc(taille*sizeof(int*));
- for (i=0; i<taille; i++)
- masque[i] = (int*)malloc(taille*sizeof(int));
- creerMasqueMoyenneur(masque, taille);
- imageDest = convolution(image2D, image, masque, taille);
- break;
- case 6:
- printf("Entrez la taille du masque: ");
- scanf(" %d", &taille);
- masque = (int**)malloc(taille*sizeof(int*));
- for (i=0; i<taille; i++)
- masque[i] = (int*)malloc(taille*sizeof(int));
- creerMasqueGaussien(masque, taille);
- imageDest = convolution(image2D, image, masque, taille);
- break;
- case 7:
- imageDest = gradientRoberts(image2D, image);
- break;
- case 8:
- imageDest = gradientPrewitt(image2D, image);
- break;
- case 9:
- imageDest = gradientSobel(image2D, image);
- break;
- case 10:
- printf("Choix du Laplacien (4 ou 8): ");
- scanf(" %d", &taille);
- masque = (int**)malloc(3*sizeof(int*));
- for (i=0; i<3; i++)
- masque[i] = (int*)malloc(3*sizeof(int));
- creerMasqueLaplacien(masque, taille);
- imageDest = convolution(image2D, image, masque, 3);
- break;
- case 11:
- imageDest = filtreMedian(image2D, image);
- break;
- case 12:
- imageTableau2ImageRGB(imageDest, image);
- ecrisBMPRGB_Dans(image, "image-convoluer.bmp");
- break;
- case 13:
- continuer = false;
- break;
- }
- }
- system("PAUSE");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement