L'exécutable

Thermes.jpg (48666 octets) SpectreThermes.gif (3773 octets)

Une image initiale

Negatif.jpg (48248 octets) NegatifFonction.gif (3200 octets) NegatifSpectre.gif (3881 octets)

Négation

LuminositeMoins.jpg (46750 octets) LuminositeMoinsFonction.gif (3240 octets) LuminositeMoinsSpectre.gif (3269 octets)

Assombrissement

LuminositeMoinsFonction.gif (3240 octets) LuminositeMoinsSpectre.gif (3269 octets)

Eclaircissement

ContrasteMoins.jpg (41071 octets) ContrasteMoinsFonction.gif (3210 octets) ContrasteMoinsSpectre.gif (3198 octets)

Diminution du contraste

ContrastePlus.jpg (55030 octets) ContrastePlusFonction.gif (3233 octets) ContrastePlusSpectre.gif (3749 octets)

Augmentation du contraste

Fichier Filtre1.fls
6
  0  50
110 140
130 210
150 230
180 200
255 180
FiltreArbitraire.gif (4622 octets)
FiltreArbitraire.jpg (27714 octets) FiltreArbitraireSpectre.gif (4833 octets)
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

Les fichiers PICT : ImagesPICT.zip

RETOUR