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