/* * op_images_b.c * * Este programa ilustra operacoes basicas * sobre as amostras de imagens binarias * s : scaling * r : rotation * h : shearing * t : translacao * g : mascara gaussiana * e : mascara de tenda * b : mascara box * i : inverte * o : OR * n : NOR * a : AND * d : NAND * x : XOR * + : soma * - : subtracao * * : multiplicacao * / : divisao * * Sao visaulizadas 3 imagens: * imagem esquerda: destination * imagem direita: source * imagem do meio: resultado * * Ting (17/10/08) */ // #define _USE_MATH_DEFINES #ifdef _WIN32 #include #endif #include // Header File For The GLUT Library #include // Header file for standard file i/o. #include // Header file for malloc/free. #include // Header file for math functions. #ifndef _WIN32 extern void glConvolutionFilter2D (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); #endif /* ascii code for the escape key */ #define ESCAPE 27 /* dimensoes da imagem */ #define ALTURA 256 #define LARGURA 256 GLfloat gaussian[7][7] = { {1.,4.,8.,10.,8.,4.,1.}, {4.,12.,25.,29.,25.,12.,4.}, {8.,25.,49.,58.,49.,25.,8.}, {10.,29.,58.,67.,58.,29.,10.}, {8.,25.,49.,58.,49.,25.,8.}, {4.,12.,25.,29.,25.,12.,4.}, {1.,4.,8.,10.,8.,4.,1.}, }; GLfloat box[3][3] = { {1.,1.,1.}, {1.,1.,1.}, {1.,1.,1.}, }; GLfloat tent[5][5] = { {1.,1.,1.,1.,1.}, {1.,2.,2.,2.,1.}, {1.,2.,3.,2.,1.}, {1.,2.,2.,2.,1.}, {1.,1.,1.,1.,1.}, }; GLubyte imagem[LARGURA][ALTURA], overlay[LARGURA][ALTURA], tmp[LARGURA][ALTURA]; GLubyte tg_imagem[LARGURA][ALTURA][3]; int win; // id da janela principal int swin1, swin2, swin3; // id das subjanelas do glut int opcao = 8; GLushort opcode = GL_OR; double m[3][3]; /*********************************************************************/ // Linhas: y; Colunas:x ([y][x]) void makeCheckImage(void) { int i, j, c; for (i = 0; i < LARGURA; i++) { for (j = 0; j < ALTURA; j++) { c = (((i&0x8)==0)^((j&0x8)==0))*255; imagem[i][j] = (GLubyte) c; } } } void makeBoxImage(void) { int i, j; for (i = 0; i < LARGURA; i++) { for (j = 0; j < ALTURA; j++) overlay[i][j] = 0; } for (i = LARGURA/4; i < (3*LARGURA)/4; i++) { for (j = ALTURA/4; j < (3*ALTURA)/4; j++) overlay[i][j] = (GLubyte) 255; } } void transfImage(void) { int i, j, k, l; for (i = 0; i < LARGURA; i++) { for (j = 0; j < ALTURA; j++) { tg_imagem[i][j][0] = (GLubyte) 255; tg_imagem[i][j][1] = 0; tg_imagem[i][j][2] = 0; } } for (i = 0; i < LARGURA; i++) { for (j = 0; j < ALTURA; j++) { k = m[0][0]*i + m[1][0]*j + m[0][2]; l = m[0][1]*i + m[1][1]*j + m[1][2]; if (k>0 && l > 0 && k 3 && opcao < 7) { glEnable(GL_CONVOLUTION_2D); if (opcao == 4) glConvolutionFilter2D(GL_CONVOLUTION_2D, GL_LUMINANCE, 3, 3, GL_LUMINANCE, GL_FLOAT, box); else if (opcao == 5) glConvolutionFilter2D(GL_CONVOLUTION_2D, GL_LUMINANCE, 5, 5, GL_LUMINANCE, GL_FLOAT, tent); else if (opcao == 6) glConvolutionFilter2D(GL_CONVOLUTION_2D, GL_LUMINANCE, 7, 7, GL_LUMINANCE, GL_FLOAT, gaussian); glRasterPos2i(0, 0); glDrawPixels(LARGURA, ALTURA, GL_LUMINANCE, GL_UNSIGNED_BYTE, imagem); glDisable(GL_CONVOLUTION_2D); } else if (opcao > 6 && opcao < 13) { // Operacoes Logicas entre destination (imagem) e source (overlay) glDrawPixels(LARGURA, ALTURA, GL_LUMINANCE, GL_UNSIGNED_BYTE, imagem); glEnable(GL_COLOR_LOGIC_OP); glLogicOp(opcode); glDrawPixels(LARGURA, ALTURA, GL_LUMINANCE, GL_UNSIGNED_BYTE, overlay); glDisable(GL_COLOR_LOGIC_OP); } else if (opcao > 12 && opcao < 17) { // Operacaoe Aritmeticas if (opcao == 13) { /* soma */ for (i=0; i< LARGURA; i++) for (j=0; j< ALTURA; j++) { valor = (imagem[i][j] + overlay[i][j]); if (valor < 0) tmp[i][j] = (GLubyte)0; else if (valor > 255) tmp[i][j] = (GLubyte)255; else tmp[i][j] = (GLubyte)valor; } } else if (opcao == 14) { /* subtracao */ for (i=0; i< LARGURA; i++) for (j=0; j< ALTURA; j++) { valor = (imagem[i][j] - overlay[i][j]); if (valor < 0) tmp[i][j] = (GLubyte)0; else if (valor > 255) tmp[i][j] = (GLubyte)255; else tmp[i][j] = (GLubyte)valor; } } else if (opcao == 15) { /* multiplicacao */ for (i=0; i< LARGURA; i++) for (j=0; j< ALTURA; j++) { valor = (imagem[i][j] * overlay[i][j]); if (valor < 0) tmp[i][j] = (GLubyte)0; else if (valor > 255) tmp[i][j] = (GLubyte)255; else tmp[i][j] = (GLubyte)valor; } } else if (opcao == 16) { /* divisao */ for (i=0; i< LARGURA; i++) for (j=0; j< ALTURA; j++) { if (overlay[i][j] > 0 ) valor = 255*(imagem[i][j] / overlay[i][j]); else valor = 255; if (valor < 0) tmp[i][j] = (GLubyte)0; else if (valor > 255) tmp[i][j] = (GLubyte)255; else tmp[i][j] = (GLubyte)valor; } } glRasterPos2i(0, 0); glDrawPixels(LARGURA, ALTURA, GL_LUMINANCE, GL_UNSIGNED_BYTE, tmp); } glFlush(); } void display_swin3() { // Desenhar os pixels da segunda imagem de uma operacao binaria glutSetWindow(swin3); glDisable(GL_DITHER); glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); if (opcao > 6) { glRasterPos2i(0, 0); glDrawPixels(LARGURA, ALTURA, GL_LUMINANCE, GL_UNSIGNED_BYTE, overlay); } glFlush(); } void main_reshape(int w, int h) { glViewport(0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, (GLdouble) w, 0.0, (GLdouble) h); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); /* redefinir a posição e as dimensões da sub-janela 1 */ glutSetWindow(swin1); glutPositionWindow(0, 0); glutReshapeWindow(LARGURA, ALTURA); /* redefinir a posição e as dimensões da sub-janela 2 */ glutSetWindow(swin2); glutPositionWindow(LARGURA, 0); glutReshapeWindow(LARGURA, ALTURA); /* redefinir a posição e as dimensões da sub-janela 2 */ glutSetWindow(swin3); glutPositionWindow(2*LARGURA, 0); glutReshapeWindow(LARGURA, ALTURA); } void reshape_swin1(int w, int h) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, (GLfloat) LARGURA, 0.0, (GLfloat) ALTURA); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void reshape_swin2(int w, int h) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, (GLfloat)LARGURA, 0.0, (GLfloat) ALTURA); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void reshape_swin3(int w, int h) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, (GLfloat)LARGURA, 0.0, (GLfloat) ALTURA); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void keyboard(unsigned char key, int x, int y) { switch (key) { case 's': // Scaling opcao = 0; m[0][0] = m[1][1] = 1.5; m[2][2] = 1.0; m[0][1] = m[0][2] = m[1][0] = m[1][2] = m[2][0] = m[2][1] = 0.0; transfImage(); break; case 'r': // Rotation opcao = 1; m[0][0] = m[1][1] = cos (M_PI_4); m[0][1] = sin (M_PI_4); m[1][0] = -m[0][1]; m[2][2] = 1.0; m[0][2] = -(LARGURA/2)*m[0][0] - (ALTURA/2)*m[1][0] + (LARGURA/2); m[1][2] = -(LARGURA/2)*m[0][1] - (ALTURA/2)*m[1][1] + (ALTURA/2); m[2][0] = m[2][1] = 0.0; transfImage(); break; case 'h': // Shearing opcao = 2; m[0][0] = m[1][1] = m[2][2] = 1.0; m[1][0] = 0.4; m[0][1] = 0.6; m[0][2] = m[1][2] = m[2][0] = m[2][1] = 0.0; transfImage(); break; case 't': // Translation opcao = 3; m[2][0] = m[2][1] = m[0][1] = m[1][0] = 0; m[0][0] = m[1][1] = m[2][2] = 1.0; m[0][2] = 10.0; m[1][2] = 10.0; transfImage(); break; case 'b': // Mascara de convolucao box opcao = 4; break; case 'e': // Mascara de convolucao tenta opcao = 5; break; case 'g': // Mascara de convolucao gaussiana opcao = 6; break; case 'i': // INVERT opcao = 7; opcode = GL_INVERT; break; case 'o': // OR opcao = 8; opcode = GL_OR; break; case 'n': // NOR opcao = 9; opcode = GL_NOR; break; case 'a': // AND opcao = 10; opcode = GL_AND; break; case 'd': // NAND opcao = 11; opcode = GL_NAND; break; case 'x': // XOR opcao = 12; opcode = GL_XOR; break; case '+': // Soma opcao = 13; break; case '-': // Subtracao opcao = 14; break; case '*': // Multiplicacao opcao = 15; break; case '/': // Divisao opcao = 16; break; case 27: exit(0); } // Atualizar o conteudo das sub-janelas display_swin2(); display_swin3(); } /************************************************************************/ // Main configuration // int main(int argc, char** argv) { #ifdef _WIN32 GLenum err; #endif glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB ); glutInitWindowSize(LARGURA*3, ALTURA); glutInitWindowPosition(0,0); win = glutCreateWindow(argv[0]); #ifdef _WIN32 // Inicializar glew err = glewInit(); if (GLEW_OK != err) { /* Problem: glewInit failed, something is seriously wrong. */ printf ("glewInit failed.\n"); } if (glewGetExtension("GL_ARB_imaging")) { printf ("GL_ARB_Imaging is supported.\n"); } #endif glutDisplayFunc(main_display); glutReshapeFunc(main_reshape); glutKeyboardFunc(keyboard); swin1 = glutCreateSubWindow(win,0,0,LARGURA,ALTURA); glutReshapeFunc(reshape_swin1); glutDisplayFunc(display_swin1); glutKeyboardFunc(keyboard); swin2 = glutCreateSubWindow(win,LARGURA,0,LARGURA,ALTURA); glutReshapeFunc(reshape_swin2); glutDisplayFunc(display_swin2); glutKeyboardFunc(keyboard); swin3 = glutCreateSubWindow(win,2*LARGURA,0,LARGURA,ALTURA); glutReshapeFunc(reshape_swin3); glutDisplayFunc(display_swin3); glutKeyboardFunc(keyboard); init(); glutMainLoop(); return 0; }