Une image initiale
Négation
Assombrissement
Eclaircissement
Diminution du contraste
Augmentation du contraste
Fichier
Filtre1.fls6 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