/* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Juin 2002 */ /* Filtrage matriciel */ #include #include #include #include #include #include #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); }