/* * seg_histograma.c * * Este programa ilustra a segmentacao orientada a histograma. * Ele segmenta uma imagem de niveis de cinza em 2 regioes. O limiar * deve ser definido pelo usuario clicando o mouse sobre * o valor desejado no histograma. * * Importante: GL_EXTENSIONS deve conter GL_ARB_imaging * Utilize a seguinte instrucao para certificar-se: * printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS)); * * * Ting (02/11/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 glGetMinmax (GLenum, GLboolean, GLenum, GLenum, GLvoid *); extern void glMinmax (GLenum, GLenum, GLboolean); extern void glGetHistogram (GLenum, GLboolean, GLenum, GLenum, GLvoid *); extern void glHistogram (GLenum, GLsizei, GLenum, GLboolean); #endif /* Include here the header of the image to be processed width and height are defined */ #include "child_profile.h" /* ascii code for the escape key */ #define ESCAPE 27 #define HISTOGRAM_SIZE 256 int win; // id da janela principal int swin1, swin2,swin3; // id das subjanelas do glut GLushort limiar; GLubyte pixel[3]; char *data; GLubyte *imagem, *t_imagem; GLubyte valores[2]; // valor minimo e maximo dos pixels GLuint values[HISTOGRAM_SIZE]; // distribuicao de frequencias /***********************************************************/ /* Histograma e Limites dos valores */ void histograma (void) { /* Define o formato da imagem da qual será feita a distribuicao de frequencias */ glHistogram(GL_HISTOGRAM, HISTOGRAM_SIZE, GL_LUMINANCE, GL_TRUE); /* Habilita histograma */ glEnable(GL_HISTOGRAM); glRasterPos2i(0, 0); glDrawPixels(width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, imagem); glGetHistogram(GL_HISTOGRAM, GL_TRUE, GL_LUMINANCE, GL_UNSIGNED_INT, values); glDisable(GL_HISTOGRAM); /* Define o formato da imagem */ glMinmax(GL_MINMAX, GL_LUMINANCE, GL_TRUE); glEnable(GL_MINMAX); glRasterPos2i(0,0); glDrawPixels(width,height,GL_LUMINANCE, GL_UNSIGNED_BYTE, imagem); glGetMinmax(GL_MINMAX, GL_TRUE, GL_LUMINANCE, GL_UNSIGNED_BYTE, valores); glDisable(GL_MINMAX); } /***********************************************************/ void init(void) { int i, j; /* definir a cor em preto (0,0,0) como cor de "CLEAR" */ glClearColor (0.0, 0.0, 0.0, 0.0); // definir a forma como os dados sao des/empacotados da memoria glutSetWindow(swin1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ALIGNMENT, 1); glutSetWindow(swin2); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ALIGNMENT, 1); glutSetWindow(swin3); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ALIGNMENT, 1); // Inicializar com o limiar 127 limiar=127; for (i=(height-1); i >= 0; i--) for (j=(width-1); j >= 0; j--) { if (imagem[i*width+j] < limiar) t_imagem[i*width+j] = 0; else t_imagem[i*width+j] = 255; } } void main_display(void) { glClearColor(0.8, 0.8, 0.8, 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3f(0.f, 0.f, 0.f); } void display_swin1() { // Desenhar os pixels da imagem original glutSetWindow(swin1); glDisable(GL_DITHER); // resetar as cores nos buffers de cor glClear(GL_COLOR_BUFFER_BIT); //Definir a origem da imagem em coordenadas da janela obtidas glRasterPos2i(0,0); glDrawPixels(width,height,GL_LUMINANCE, GL_UNSIGNED_BYTE, imagem); // forcar a execucao dos comandos enviados a OpenGL glFlush(); } void display_swin2() { GLushort i, max; double fator; // Desenhar o histograma glutSetWindow(swin2); glDisable(GL_DITHER); // resetar as cores nos buffers de cor glClear(GL_COLOR_BUFFER_BIT); // Determinar a frequencia de distribuicao dos valores histograma(); // Normaliza a quantidade em funcao da altura da janela for (max = i=0; i< HISTOGRAM_SIZE; i++) { if (values[i] > max) max = values[i]; } fator = (height*1.0)/max; glBegin(GL_LINE_STRIP); glColor3f(1.0,1.0,1.0); for (i=0; i= 0; i--) for (j=(width-1); j >= 0; j--) { if (imagem[i*width+j] < limiar) t_imagem[i*width+j] = 0; else t_imagem[i*width+j] = 255; } display_swin2(); display_swin3(); } } void keyboard(unsigned char key, int x, int y) { switch (key) { case 27: free((char *)imagem); free((char *)t_imagem); exit(0); return; } } int main(int argc, char **argv) { int i, j; #ifdef _WIN32 GLenum err; #endif /* Alocar memoria para imagens */ imagem = (GLubyte *) malloc (sizeof(GLubyte)*height*width); t_imagem = (GLubyte *) malloc (sizeof(GLubyte)*height*width); /* Extrair imagem */ data = header_data; for (i=(height-1); i >= 0; i--) for (j=(width-1); j >= 0; j--) { HEADER_PIXEL(data,pixel) imagem[i*width+j] = pixel[0]; } glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB ); glutInitWindowSize((int)2*width+257, (int)height); 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 glutReshapeFunc(main_reshape); glutDisplayFunc(main_display); glutKeyboardFunc(keyboard); swin1 = glutCreateSubWindow(win,(int)width,0,(int)width,(int)height); glutReshapeFunc(reshape_swin1); glutDisplayFunc(display_swin1); glutKeyboardFunc(keyboard); swin2 = glutCreateSubWindow(win,(int)width,0,(int)257,(int)height); glutReshapeFunc(reshape_swin2); glutDisplayFunc(display_swin2); glutKeyboardFunc(keyboard); glutMouseFunc(mouse); swin3 = glutCreateSubWindow(win,(int)width+257,0,(int)width,(int)height); glutReshapeFunc(reshape_swin3); glutDisplayFunc(display_swin3); glutKeyboardFunc(keyboard); init(); glutMainLoop(); return(0); }