L'exécutable

 

 

 

Le source: FiltrageMatriciel.cpp

/* Auteur: Nicolas JANEY         */
/* nicolas.janey@univ-fcomte.fr  */
/* Juin 2002                     */
/* Filtrage matriciel            */

#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>

#include "PICTBitmapGL.h"
#include "PICTMain.h"

#include "ModuleCouleurs.h"
#include "ModuleFont.h"

struct filtre {
  int type;
  int n;
  float **t; };

static int f1 ;
static int f2 ;
static int f3 ;
static struct espace bt = { 0,0,0,0 } ;
static struct espace imagef = { 0,0,0,0 } ;
static int flt = 0 ;
static int img = 0 ;
static filtre filtres[13] ;

void liberationFiltre(filtre *f) {
  for ( int i = 0 ; i < f->n ; i++ )
    free(f->t[i]);
  free(f->t);
  f->n = 0;
}

void allocationFiltre(filtre *f,int n) {
  f->n = n;
  f->t =(float **) calloc(n,sizeof(float *));
  for ( int i = 0 ; i < n ; i++ )
    f->t[i] =(float *) calloc(n,sizeof(float));
}

void lectureFiltre(char *filename,filtre *f) {
  FILE *num;
  num = fopen(filename,"rt");
  if ( num ) {
    fscanf(num,"%d",&f->n);
    fscanf(num,"%d",&f->type);
    allocationFiltre(f,f->n);
    for ( int i = 0 ; i < f->n ; i++ )
      for ( int j = 0 ; j < f->n ; j++ )
        fscanf(num,"%f",&f->t[i][j]);
    fclose(num); }
    else {
    printf("Fichier non existant : %s\n",filename); }
}

void initFiltres(void) {
  int i,j;
  allocationFiltre(&filtres[0],3);
  allocationFiltre(&filtres[1],3);
  allocationFiltre(&filtres[2],3);
  allocationFiltre(&filtres[3],3);
  allocationFiltre(&filtres[4],3);
  allocationFiltre(&filtres[5],3);
  allocationFiltre(&filtres[6],5);
  allocationFiltre(&filtres[7],3);
  allocationFiltre(&filtres[8],3);
  allocationFiltre(&filtres[9],3);
  allocationFiltre(&filtres[10],3);
  allocationFiltre(&filtres[11],3);
  filtres[0].type = 0;
  filtres[1].type = 0;
  filtres[2].type = 0;
  filtres[3].type = 0;
  filtres[4].type = 1;
  filtres[5].type = 1;
  filtres[6].type = 0;
  filtres[7].type = 1;
  filtres[8].type = 1;
  filtres[9].type = 1;
  filtres[10].type = 1;
  filtres[11].type = 1;
  for ( i = 0 ; i < filtres[0].n ; i++ )
    for ( j = 0 ; j < filtres[0].n ; j++ )
      filtres[0].t[i][j] = 1.0F/9.0F;
  for ( i = 0 ; i < filtres[1].n ; i++ )
    for ( j = 0 ; j < filtres[1].n ; j++ )
      if ( (i+j)%2 == 1 )
        filtres[1].t[i][j] = 0.2F;
  filtres[1].t[1][1] = 0.2F;
  for ( i = 0 ; i < filtres[2].n ; i++ )
    for ( j = 0 ; j < filtres[2].n ; j++ )
      if ( (i+j)%2 == 1 )
        filtres[2].t[i][j] = 0.125F;
  filtres[2].t[1][1] = 0.5F;
  for ( i = 0 ; i < filtres[3].n ; i++ )
    for ( j = 0 ; j < filtres[3].n ; j++ )
      filtres[3].t[i][j] = ( (i+j)%2 == 1 ) ? 0.125F : 0.0625;
  filtres[3].t[1][1] = 0.25F;
  for ( i = 0 ; i < filtres[4].n ; i++ ) {
    filtres[4].t[i][0] = -1.0F;
    filtres[4].t[i][1] = 0.0F;
    filtres[4].t[i][2] = 1.0F; }
  for ( i = 0 ; i < filtres[5].n ; i++ )
    for ( j = 0 ; j < filtres[5].n ; j++ )
      if ( (i+j)%2 == 1 )
        filtres[5].t[i][j] = 1.0F;
  filtres[5].t[1][1] = -4.0F;
  for ( i = 0 ; i < filtres[6].n ; i++ )
    for ( j = 0 ; j < filtres[6].n ; j++ )
      filtres[6].t[i][j] = 0.04F;
  for ( i = 0 ; i < filtres[7].n ; i++ ) {
    filtres[7].t[0][i] = -1.0F;
    filtres[7].t[1][i] = 0.0F;
    filtres[7].t[2][i] = 1.0F; }
  for ( i = 0 ; i < filtres[8].n ; i++ ) {
    for ( j = 0 ; j < filtres[8].n ; j++ )
      if ( i > j )
        filtres[8].t[i][j] = -1.0F;
        else
        if ( i < j )
          filtres[8].t[i][j] = 1.0F; }
  filtres[9].t[1][0] = -1.0F;
  filtres[9].t[1][1] = 0.0F;
  filtres[9].t[1][2] = 1.0F;
  for ( i = 0 ; i < filtres[10].n ; i++ )
    if ( i != 1 ) {
      filtres[10].t[i][0] = -1.0F;
      filtres[10].t[i][1] = 0.0F;
      filtres[10].t[i][2] = 1.0F; }
      else {
      filtres[10].t[i][0] = -2.0F;
      filtres[10].t[i][1] = 0.0F;
      filtres[10].t[i][2] = 2.0F; }
  for ( i = 0 ; i < filtres[11].n ; i++ )
    for ( j = 0 ; j < filtres[11].n ; j++ )
      filtres[11].t[i][j] = 1.0F;
  filtres[11].t[1][1] = -8.0F;
  filtres[12].n = 0;
}
 
void myinit(void) { 
  glClearColor(0.0,0.0,0.0,1.0); 
  glPixelStorei(GL_UNPACK_ALIGNMENT,1); 
  glPixelStorei(GL_PACK_ALIGNMENT,1); 


void displayi(void) { 
  glClear(GL_COLOR_BUFFER_BIT); 
  glPushMatrix();
  affichageGLBitmap(&bt) ;
  glPopMatrix();
  glFlush(); 
  glutSwapBuffers();


void displayf(void) { 
  glClear(GL_COLOR_BUFFER_BIT); 
  glPushMatrix();
  affichageGLBitmap(&imagef) ;
  glPopMatrix();
  glFlush(); 
  glutSwapBuffers();


void filtrerImage(espace *imagei,espace *imagef,filtre *f) {
  liberation_espace(imagef);
  new_espace(imagef,imagei->dx-f->n+1,imagei->dy-f->n+1,24);
  for ( int y = 0 ; y < imagef->dy ; y++ ) {
    for ( int x = 0 ; x < imagef->dx ; x++ ) {
      float r = 0;
      float v = 0;
      float b = 0;
      for ( int j = 0 ; j < f->n ; j++ )
        for ( int i = 0 ; i < f->n ; i++ ) {
          r += imagei->p[y+j][(x+i)*3] * f->t[j][i];
          v += imagei->p[y+j][(x+i)*3+1] * f->t[j][i];
          b += imagei->p[y+j][(x+i)*3+2] * f->t[j][i]; }
      if ( f->type) {
        r = fabs(r);
        v = fabs(v);
        b = fabs(b); }
      if ( r > 255.0F )
        r = 255.0F;
      if ( v > 255.0F )
        v = 255.0F;
      if ( b > 255.0F )
        b = 255.0F;
      imagef->p[y][x*3] =(unsigned char) r ;
      imagef->p[y][x*3+1] =(unsigned char) v ;
      imagef->p[y][x*3+2] =(unsigned char) b ; } }
}

void chargementFiltre(void) { 
  flt = 11;
  char fichier[300];
  printf("Nom du fichier filtre a charger : ");
  scanf("%s",fichier);
  liberationFiltre(&filtres[flt]) ;      
  lectureFiltre(fichier,&filtres[flt]) ;
  glutSetWindow(f3);
  glutReshapeWindow(80*filtres[flt].n,10+20*filtres[flt].n);
  if ( bt.dx != 0 ) {
    filtrerImage(&bt,&imagef,&filtres[flt]);
    glutSetWindow(f2);
    glutReshapeWindow(imagef.dx-filtres[flt].n+1,imagef.dy-filtres[flt].n+1); }
  glutPostWindowRedisplay(f1);
  glutPostWindowRedisplay(f2);
  glutPostWindowRedisplay(f3); 
}

void raffraichissementFiltre(void) { 
  glutSetWindow(f3);
  glutReshapeWindow(80*filtres[flt].n,10+20*filtres[flt].n);
  if ( bt.dx != 0 ) {
    filtrerImage(&bt,&imagef,&filtres[flt]);
    glutSetWindow(f2);
    glutReshapeWindow(imagef.dx-filtres[flt].n+1,imagef.dy-filtres[flt].n+1); }
  glutPostWindowRedisplay(f1);
  glutPostWindowRedisplay(f2);
  glutPostWindowRedisplay(f3); 
}

void incrementationFiltre(void) { 
  flt = (flt+1)%12;
  raffraichissementFiltre() ;
}

void raffraichissement(void) {
  filtrerImage(&bt,&imagef,&filtres[flt]);
  glutSetWindow(f2);
  glutReshapeWindow(imagef.dx-filtres[flt].n+1,imagef.dy-filtres[flt].n+1);
  glutSetWindow(f1);
  glutReshapeWindow(bt.dx,bt.dy);
  glutPostWindowRedisplay(f1);
  glutPostWindowRedisplay(f2);
  glutPostWindowRedisplay(f3);
}

void chargementImage(char *fichier) {
  liberation_espace(&bt) ;      
  lecture_PICT24_compacte(fichier,&bt) ;
  raffraichissement(); 
}

void chargementImageArbitraire(void) {
  char fichier[300];
  printf("Nom du fichier PICT 24 bits a charger : ");
  scanf("%s",fichier);
  chargementImage(fichier); 
}

void reshape(int w,int h) {
  glViewport(0,0,w,h);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(0,w,0,h,-1.0,1.0); 
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}

void reshape2(int w,int h) {
  glViewport(0,0,w,h);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(0,w,-h,0,-1.0,1.0); 
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}

void display2() {
  glClear(GL_COLOR_BUFFER_BIT);
  glPushMatrix();
  float pos = 1.0F;
  glColor4fv(couleurBlanc());
  for ( int i = 0 ; i < filtres[flt].n ; i++ ) {
    for ( int j = 0 ; j < filtres[flt].n ; j++ ) {
      placeFontCursor(5.0F+80.0F*j,-pos*20.0F,0.0F) ;
      simpleBitmapOutput(0,REGULAR8x13,"%7.4lf",filtres[flt].t[i][j]) ; }
    pos += 1.0F; }
  glPopMatrix();
  glFlush();
  glutSwapBuffers();
}

void select(int selection) {
  switch (selection) {
    case 1   : if ( imagef.dx != 0 ) {
                 char fichier[300];
                 printf("Nom du fichier PICT 24 bits a sauver : ");
                 scanf("%s",fichier);
                 sauvegarde_PICT24_compacte(fichier,&imagef) ; }
               break;
    case 0   : exit(0);
               break; }
  glutPostRedisplay();
}

void selectImage24(int selection) {
  switch (selection) {
    case 1   : chargementImage("Pict24-1.pct");
               break;
    case 2   : chargementImage("Pict24-2.pct");
               break;
    case 3   : chargementImage("Pict24-3.pct");
               break;
    case 4   : chargementImage("Pict24-4.pct");
               break;
    case 5   : chargementImage("Thermes.pct");
               break;
    case 6   : chargementImage("PlaceDeLaLiberte.pct");
               break;
    case 7   : chargementImage("ABCD.pct");
               break;
    case 8   : chargementImage("Formes.pct");
               break;
    case 9   : chargementImage("Lignes.pct");
               break;
    case 10  : chargementImage("Quadrillage.pct");
               break;
    case 11  : chargementImage("Temple.pct");
               break;
    case -1  : chargementImageArbitraire();
               break; }
}

void selectFiltre(int selection) {
  switch (selection) {
    case 100 : chargementFiltre();
               break; }
}

void selectFiltreMoyenne3(int selection) {
  switch (selection) {
    case 0   :
    case 1   : 
    case 2   : 
    case 3   : flt = selection;
               raffraichissementFiltre();
               break; }
}

void selectFiltreMoyenne5(int selection) {
  switch (selection) {
    case 6   : flt = selection;
               raffraichissementFiltre();
               break; }
}

void selectFiltreGradient(int selection) {
  switch (selection) {
    case 7   :
    case 8   :
    case 9   :
    case 10  :
    case 4   : flt = selection;
               raffraichissementFiltre();
               break; }
}

void selectFiltreLaplacien(int selection) {
  switch (selection) {
    case 11  :
    case 5   : flt = selection;
               raffraichissementFiltre();
               break; }
}

void creerMenus(void) {
  int menuImage24 = glutCreateMenu(selectImage24);
  glutAddMenuEntry("Pict24-1.pct",1);
  glutAddMenuEntry("Pict24-2.pct",2);
  glutAddMenuEntry("Pict24-3.pct",3);
  glutAddMenuEntry("Pict24-4.pct",4);
  glutAddMenuEntry("Thermes.pct",5);
  glutAddMenuEntry("PlaceDeLaLiberte.pct",6);
  glutAddMenuEntry("ABCD.pct",7);
  glutAddMenuEntry("Formes.pct",8);
  glutAddMenuEntry("Lignes.pct",9);
  glutAddMenuEntry("Quadrillage.pct",10);
  glutAddMenuEntry("Temple.pct",11);
  glutAddMenuEntry("Fichier PICT 24 bits",-1);
  int menuFiltreMoyenne3 = glutCreateMenu(selectFiltreMoyenne3);
  glutAddMenuEntry("Moyenne simple octogonal",0);
  glutAddMenuEntry("Moyenne simple en croix",1);
  glutAddMenuEntry("Moyenne pondere n°1",2);
  glutAddMenuEntry("Moyenne pondere n°2",3);
  int menuFiltreMoyenne5 = glutCreateMenu(selectFiltreMoyenne5);
  glutAddMenuEntry("Moyenne simple octogonal",6);
  int menuFiltreGradient = glutCreateMenu(selectFiltreGradient);
  glutAddMenuEntry("Prewitt vertical",4);
  glutAddMenuEntry("Prewitt horizontal",7);
  glutAddMenuEntry("Prewitt diagonal",8);
  glutAddMenuEntry("Croix",9);
  glutAddMenuEntry("Sobel",10);
  int menuFiltreLaplacien = glutCreateMenu(selectFiltreLaplacien);
  glutAddMenuEntry("Laplacien carré",5);
  glutAddMenuEntry("Laplacien octogonal",11);
  int menuFiltre = glutCreateMenu(selectFiltre);
  glutAddSubMenu("Moyenne 3x3",menuFiltreMoyenne3);
  glutAddSubMenu("Moyenne 5x5",menuFiltreMoyenne5);
  glutAddSubMenu("Gradient",menuFiltreGradient);
  glutAddSubMenu("Laplacien",menuFiltreLaplacien);
  glutAddMenuEntry("Fichier filtre",100);
  glutCreateMenu(select);
  glutAddSubMenu("Charger image PICT 24 bits",menuImage24);
  glutAddMenuEntry("Sauver image PICT 24 bits",1);
  glutAddSubMenu("Filtre",menuFiltre);
  glutAddMenuEntry("Quitter",0);
  glutAttachMenu(GLUT_RIGHT_BUTTON);
}

void key(unsigned char key,int x,int y) {
  switch ( key ) {
    case 'i'  : chargementImageArbitraire();
                break;
    case 0x0D : img = (img+1)%11;
                selectImage24(img+1);
                break;
    case 'f'  : chargementFiltre();
                break;
    case ' '  : incrementationFiltre();
                break;
    case 0x1B : exit(0);
                break; }
}

int main(int argc,char **argv) {
  initFiltres();
  glutInit(&argc,argv);
  glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE);
  glutInitWindowSize(200,200); 
  glutInitWindowPosition(30,30); 
  f1 = glutCreateWindow("Filtrage matriciel"); 
  creerMenus();
  myinit(); 
  glutReshapeFunc(reshape);
  glutKeyboardFunc(key);
  glutDisplayFunc(displayi);
  glutInitWindowSize(200,200); 
  glutInitWindowPosition(30,300); 
  f2 = glutCreateWindow("Image filtrée");
  myinit(); 
  creerMenus();
  glutReshapeFunc(reshape);
  glutKeyboardFunc(key);
  glutDisplayFunc(displayf);
  glutInitWindowSize(240,70);
  glutInitWindowPosition(540,110);
  f3 = glutCreateWindow("Matrice de filtrage");
  myinit(); 
  creerMenus();
  glutDisplayFunc(display2);
  glutReshapeFunc(reshape2);
  glutKeyboardFunc(key);
  glutMainLoop();
  return(0);
}

Les modules utilitaires : Modules.zip

Les modules de gestion des images au format Macintosh PICT 24bits : PICT.zip

Les fichiers PICT : ImagesPICT.zip

RETOUR