/* * seg_regiao.c * * Este programa ilustra a segmentacao de uma imagem em 2 regioes, * a partir de uma semente e o valor de diferenca * admissivel. O algoritmo flood fill e utilizado. * A semente deve ser definida pelo * usuario atravess de um click sobre um pixel da imagem. * A diferenca inicial e 0.05 (5%) e pode ser modificada * atraves da tecla * +: incremento de 0.01 * -: decremento de 0.01 * Ao acionar a tecla ESC o processo sera interrompido. * * Ting (02/11/08) */ #define _USE_MATH_DEFINES #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. /* 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 int win; // id da janela principal int swin1, swin2; // id das subjanelas do glut GLubyte pixel[3]; char *data; GLubyte *imagem, *t_imagem; GLushort sx, sy; double c; /***********************************************************/ /* Flood fill */ void flood_fill (int x, int y, double c, GLubyte target, GLubyte replace) { if (fabs(imagem[y*width+x]-target)/target > c) return; if (t_imagem[y*width+x] == 0) return; t_imagem[y*width+x] = 0; if (x>0) flood_fill (x-1, y, c, target, replace); if (y>0) flood_fill (x, y-1, c, target, replace); if (x= 0; i--) for (j=(width-1); j >= 0; j--) { t_imagem[i*width+j] = 255; } sy = height-128; sx = 128; printf("target=%d ** diferenca=%f\n", imagem[sy*width+sx], c); flood_fill(sx,sy,c,imagem[sy*width+sx],0); } 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); glPointSize(5.0); glBegin(GL_POINTS); glColor3f(1.0,0.0,0.0); glVertex2s(sx, sy); glEnd(); // forcar a execucao dos comandos enviados a OpenGL glFlush(); } void display_swin2() { // Desenhar a regiao segmentada por crescimento da semente glutSetWindow(swin2); glDisable(GL_DITHER); // resetar as cores nos buffers de cor glClear(GL_COLOR_BUFFER_BIT); // Definir a origem da imagem glRasterPos2i(0,0); glDrawPixels(width,height,GL_LUMINANCE, GL_UNSIGNED_BYTE, t_imagem); // forcar a execucao dos comandos enviados a OpenGL glFlush(); } void main_reshape(int w, int h) { glViewport(0,0,(GLsizei)w,(GLsizei)h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, (GLfloat) w, 0.0, (GLfloat) h); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); /* redefinir a posição e as dimensões da sub-janela 1 */ glutSetWindow(swin1); glutPositionWindow(0, 0); glutReshapeWindow(width, height); /* redefinir a posição e as dimensões da sub-janela 2 */ glutSetWindow(swin2); glutPositionWindow(width,0 ); glutReshapeWindow(width, height); } void reshape_swin1(int w, int h) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, (GLfloat) width, 0.0, (GLfloat) height); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void reshape_swin2(int w, int h) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, (GLfloat) width, 0.0, (GLfloat) height); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } /* ARGSUSED1 */ void mouse(int button, int state, int x, int y) { int i,j; if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) { for (i=(height-1); i >= 0; i--) for (j=(width-1); j >= 0; j--) { t_imagem[i*width+j] = 255; } sx = x; sy = height-y; printf("target=%d ** diferenca=%f\n", imagem[sy*width+sx], c); flood_fill(sx,sy,c,imagem[sy*width+sx],0); display_swin1(); display_swin2(); } } void keyboard(unsigned char key, int x, int y) { int i,j; switch (key) { case '+': c += 0.01; if (c > 1.) c = 1.; break; case '-': c -= 0.01; if (c < 0.) c = 0.; break; case 27: free((char *)imagem); free((char *)t_imagem); exit(0); return; } for (i=(height-1); i >= 0; i--) for (j=(width-1); j >= 0; j--) { t_imagem[i*width+j] = 255; } printf("target=%d ** diferenca=%f\n", imagem[sy*width+sx], c); flood_fill(sx,sy,c,imagem[sy*width+sx],0); display_swin2(); } int main(int argc, char **argv) { int i, j; /* 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, (int)height); glutInitWindowPosition(0,0); win = glutCreateWindow(argv[0]); 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); glutMouseFunc(mouse); swin2 = glutCreateSubWindow(win,(int)width,0,(int)257,(int)height); glutReshapeFunc(reshape_swin2); glutDisplayFunc(display_swin2); glutKeyboardFunc(keyboard); init(); glutMainLoop(); return(0); }