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