 
 
Une image initiale
 
  
 
Négation
 
  
 
Assombrissement
 
  

Eclaircissement
 
  
 
Diminution du contraste
 
  
 
Augmentation du contraste
| Fichier
    Filtre1.fls 6 0 50 110 140 130 210 150 230 180 200 255 180 |  | 
|   |  | 
| Filtre arbitraire | |
Le source: FiltrageSpectral.cpp
/* Auteur: Nicolas JANEY         */
/* nicolas.janey@univ-fcomte.fr  */
/* Juin 2002                     */
/* Filtrage spectral             */
#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"
typedef void *filtre;
struct spectre {
  int t[256];
  int max; } ;
struct filtreParametre {
  int n;
  GLubyte y[256]; } ;
static int f1 ;
static int f2 ;
static int f3 ;
static int f4 ;
static int f5 ;
static struct espace bt = { 0,0,0,0 } ;
static struct espace imagef = { 0,0,0,0 } ;
static spectre si;
static spectre sf;
static int flt = 0 ;
static int tflt = 0 ;
static int img = 0 ;
static filtre filtres[5] ;
static float fact = 1.0F ;
static filtreParametre fp;
GLubyte filtration(GLubyte b) {
  return(fp.y[b]);
}
GLubyte identite(GLubyte b) {
  return(b);
}
GLubyte negative(GLubyte b) {
  return(255-b);
}
GLubyte luminosite(GLubyte b) {
  return((GLubyte) (pow(b/255.0,(double) fact)*255.0+0.5));
}
GLubyte contraste(GLubyte b) {
  if ( b > 127 ) {
    return((GLubyte) (pow((b-127.5)/127.5,(double) fact)*127.5+128)); }
    else {
    return((GLubyte) (-pow((127.5-b)/127.5,(double) fact)*127.5+128)); }
}
void initSpectre(spectre *s) {
  for ( int i = 0 ; i < 256 ; i++ ) {
    s->t[i] = 0; }
  s->max = 0;
}
void calculSpectre(spectre *s,espace *im) {
  initSpectre(s);
  int i,j;
  if ( tflt == 1 ) {
    for ( i = 0 ; i < im->dy ; i++ )
      for ( j = 0 ; j < 3*im->dx ; j++ )
        s->t[im->p[i][j]]++ ;
    s->max = s->t[0];
    for ( i = 1 ; i < 256 ; i++ )
      if ( s->t[i] > s->max )
        s->max = s->t[i]; }
    else {
    for ( i = 0 ; i < im->dy ; i++ )
      for ( j = 0 ; j < im->dx ; j++ ) {
        int v =(int) im->p[i][3*j]+im->p[i][3*j+1]+im->p[i][3*j+2];
        s->t[v/3]++ ; }
    s->max = s->t[0];
    for ( i = 1 ; i < 256 ; i++ )
      if ( s->t[i] > s->max )
        s->max = s->t[i]; }
}
 
void initFiltres(void) {
  filtres[0] =(void *) identite;
  filtres[1] =(void *) negative;
  filtres[2] =(void *) luminosite;
  filtres[3] =(void *) contraste;
  filtres[4] =(void *) filtration;
}
 
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,imagei->dy,24);
  for ( int y = 0 ; y < imagef->dy ; y++ )
    for ( int x = 0 ; x < imagef->dx*3 ; x++ )
      imagef->p[y][x] =((GLubyte (*)(GLubyte b)) f)(imagei->p[y][x]);
}
void lectureFiltre(char *filename,filtreParametre *f) {
  FILE *num;
  num = fopen(filename,"rt");
  if ( num ) {
    GLubyte xi,xf;
    GLubyte yi,yf;
    fscanf(num,"%d",&f->n);
    fscanf(num,"%uc",&xi);
    fscanf(num,"%uc",&yi);
    for ( int i = 1 ; i < f->n ; i++ ) {
      fscanf(num,"%uc",&xf);
      fscanf(num,"%uc",&yf);
      for ( int x = xi ; x <= xf ; x++ )
        f->y[x] =(GLubyte) (0.49+yi +(double) (x-xi)/(xf-xi)*(yf-yi)); 
      xi = xf;
      yi = yf; }
    fclose(num); }
    else {
    printf("Fichier non existant : %s\n",filename); }
}
void chargementFiltre(void) { 
  flt = 4;
  char fichier[300];
  printf("Nom du fichier filtre a charger : ");
  scanf("%s",fichier);
  lectureFiltre(fichier,&fp) ;
  if ( bt.dx != 0 )
    filtrerImage(&bt,&imagef,&filtres[flt]);
  glutPostWindowRedisplay(f1);
  glutPostWindowRedisplay(f2);
  glutPostWindowRedisplay(f3);
}
void raffraichissementFiltre(void) { 
  if ( bt.dx != 0 )
    filtrerImage(&bt,&imagef,filtres[flt]);
  glutPostWindowRedisplay(f2);
  glutPostWindowRedisplay(f3); 
  calculSpectre(&sf,&imagef);
  glutPostWindowRedisplay(f4); 
}
void incrementationFiltre(void) { 
  flt = (flt+1)%4;
  raffraichissementFiltre(); 
}
void raffraichissementImage(void) {
  filtrerImage(&bt,&imagef,filtres[flt]);
  glutSetWindow(f2);
  glutReshapeWindow(imagef.dx,imagef.dy);
  glutSetWindow(f1);
  glutReshapeWindow(bt.dx,bt.dy);
  glutPostWindowRedisplay(f1);
  glutPostWindowRedisplay(f2);
  calculSpectre(&sf,&imagef);
  calculSpectre(&si,&bt);
  glutPostWindowRedisplay(f4);
  glutPostWindowRedisplay(f5);
}
void chargementImage(char *fichier) {
  liberation_espace(&bt) ;      
  lecture_PICT24_compacte(fichier,&bt) ;
  raffraichissementImage(); 
}
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.0,255.0,0.0,255.0,-1.0,1.0); 
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}
void display2() {
  glClear(GL_COLOR_BUFFER_BIT);
  glPushMatrix();
  glBegin(GL_LINE_STRIP);
  for ( int i = 0 ; i <= 255 ; i++ ) {
    glVertex2f(i,((GLubyte (*)(GLubyte b)) filtres[flt])(i)); }
  glEnd();
  glPopMatrix();
  glFlush();
  glutSwapBuffers();
}
void displaySf(void) { 
  glClear(GL_COLOR_BUFFER_BIT); 
  glPushMatrix();
  if ( sf.max != 0 ) {
    glBegin(GL_LINES);
    for ( int i = 0 ; i < 256 ; i++ ) {
      glVertex2f(i,0.0F);
      glVertex2f(i,(float) sf.t[i]*200.0F/sf.max); }
    glEnd(); }
  glPopMatrix();
  glFinish();
  glutSwapBuffers();
} 
void displaySi(void) { 
  glClear(GL_COLOR_BUFFER_BIT); 
  glPushMatrix();
  if ( si.max != 0 ) {
    glBegin(GL_LINES);
    for ( int i = 0 ; i < 256 ; i++ ) {
      glVertex2f(i,0.0F);
      glVertex2f(i,(float) si.t[i]*200.0F/si.max); }
    glEnd(); }
  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 10  : chargementFiltre();
               break;
    case 0   :
    case 1   : 
    case 2   : 
    case 3   : 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 menuFiltre = glutCreateMenu(selectFiltre);
  glutAddMenuEntry("Identite",0);
  glutAddMenuEntry("Negative",1);
  glutAddMenuEntry("Luminosite",2);
  glutAddMenuEntry("Contraste",3);
  glutAddMenuEntry("Fichier filtre",10);
  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 45   : fact = fact*1.1F;
                filtrerImage(&bt,&imagef,filtres[flt]);
                calculSpectre(&sf,&imagef);
                glutPostWindowRedisplay(f2);
                glutPostWindowRedisplay(f3);
                glutPostWindowRedisplay(f4);
                break;
    case 43   : fact = fact/1.1F;
                filtrerImage(&bt,&imagef,filtres[flt]);
                calculSpectre(&sf,&imagef);
                glutPostWindowRedisplay(f2);
                glutPostWindowRedisplay(f3);
                glutPostWindowRedisplay(f4);
                break;
    case 'i'  : chargementImageArbitraire();
                break;
    case 0x0D : img = (img+1)%11;
                selectImage24(img+1);
                break;
    case 'f'  : chargementFiltre();
                break;
    case 't'  : tflt = (tflt+1)%2;
                calculSpectre(&sf,&imagef);
                calculSpectre(&si,&bt);
                glutPostWindowRedisplay(f4);
                glutPostWindowRedisplay(f5);
                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 spectral"); 
  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(255,255);
  glutInitWindowPosition(540,30);
  f3 = glutCreateWindow("Fonction de filtrage");
  myinit(); 
  creerMenus();
  glutDisplayFunc(display2);
  glutReshapeFunc(reshape2);
  glutKeyboardFunc(key);
  glutInitWindowSize(256,200); 
  glutInitWindowPosition(520,300); 
  f4 = glutCreateWindow("Spectre modifie"); 
  myinit(); 
  creerMenus();
  glutReshapeFunc(reshape);
  glutKeyboardFunc(key);
  glutDisplayFunc(displaySf);
  glutInitWindowSize(256,200); 
  glutInitWindowPosition(420,400); 
  f5 = glutCreateWindow("Spectre initial"); 
  myinit(); 
  creerMenus();
  glutReshapeFunc(reshape);
  glutKeyboardFunc(key);
  glutDisplayFunc(displaySi);
  glutMainLoop();
  return(0);
}
Les modules utilitaires : Modules.zip
Les modules de gestion des images au format Macintosh PICT 24bits : PICT.zip