/* Last edited on 2003-07-12 01:49:41 by stolfi */ /*H e V sao, respectivamente, largura e altura(em pixels) da imagem*/ int *bucketing(lista_t *lista, int H, int V) { int *m=NULL; int largura, altura, tetai=-90, tetaf=89; int i, j, l,c,tam; no_t *p; largura=(tetaf-tetai)/5 +1; altura=arredonda(sqrt((H*H)+(V*V))/4) +1; if ( (m=(int *)calloc(tam=(largura*altura+1), sizeof(int))) == NULL ) printf("Problema ao alocar a matriz de contadores.\n"); for(i=0;iprimno; for (i=0; itam; i++) { double cteta = cos(p->teta/180.0*pi); double steta = sin(p->teta/180.0*pi); /*******************************************************************/ /* o valor de "l" pode ser negativo. verificar incoerências. será que não está tudo errado??? acho que não */ /*******************************************************************/ l= abs(arredonda(distancia(p->v,p->h,cteta,steta)/4)); c= (arredonda(p->teta/5) - tetai/5); m[indice(l,c,largura)+1]++; p=p->prox; } /*os picos dessa tabela m correspondem às retas da imagem.*/ return m; } lista_t *extraipicos(int n, int *m, int largura, int altura) { lista_t *lista; no_t *no; int i, tam, tetai=-90; lista=novalista(n); tam=m[0]; for (i=0; ic=m[i+1]; no->teta=tetai+5*coluna(i,largura); no->v=4*linha(i,largura); insereno(no, lista); } return lista; } /* nlinhas é o número de linhas que ele vai tentar identificar, isto é, pega os nlinhas troços mais parecidos com uma linha*/ /* *R, largura e altura são os parâmetros da imagem */ double *detectalinhas2(int nlinhas, int *R, int largura, int altura) { int i=0, j=0;/*contadores*/ double teta=0, maior=0; /*maior=maior nota atribuida a um pixel. utilizado para normalizar a matriz e criar uma imagem */ double *ci, *mm; /* Parâmetro {L} varia em {0..Lmax-1}: */ int Lmax = (int)ceil(sqrt(largura*largura + altura*altura)); /* Parâmetro {teta} varia em {0..Tmax-1}: */ int Tmax = 180; /* Numero de baldes na transformada: */ int n=Lmax*Tmax; /* tamanho da matriz que acumula as notas de cada pixel, jah na forma teta X L */ int *G;/* guarda uma foto da matriz com a acumulação das notas. Eixo vertical = teta ; horizontal = L */ lista_t *lista; no_t *no; double *M;/* guarda a matriz com a acumulação das notas. Eixo vertical = teta ; horizontal = L */ int *MLINHAS;/* guarda uma copia da imagem, mas com a cor de cada pixel relacionada a seu grau de aparencia com uma linha */ ci = curvaideal(0, SIGMA, R, largura); if ( (M=(double *)calloc(n,sizeof(double))) == NULL ) { printf("Defeito ao alocar matriz M em detectalinhas2.\n"); } if ( (G=(int *)calloc(n,sizeof(int))) == NULL ) { printf("Defeito ao alocar matriz G em detectalinhas2.\n"); } if ( (MLINHAS=(int *)calloc(largura*altura,sizeof(int))) == NULL ) { printf("Defeito ao alocar matriz MLINHAS em detectalinhas2.\n"); } for (i=0; i cmax) { cmax = c; mteta=teta; mcteta=cteta; msteta=steta; } } /* cmax é a melhor nota para todos os angulos teta neste pixel */ /* cmax = 0 se o casamento foi perfeito. */ /* cmax << 0 se o casamento foi ruim. */ /* Gv = 1.0 se casamento perfeito, 0.0 se péssimo. */ Gv = (15 - fabs(cmax))/15.0 - 0.393; if (Gv < 0.0) { Gv = 0.0; } if (Gv > 1.0) { Gv = 1.0; } MLINHAS[largura*i + j] = (int)(Gv*255); /*deve pegar uma matriz (o bucket) e somar as notas de cada pixel*/ /* essas distancias devem ser do ponto (i,j) à reta de ângulo teta que passa por (0,0) */ if (i == 100) { fprintf(stderr, "pixel = [%3d,%3d] mteta = %3.0f Gv = %5.3f", i,j,mteta,Gv); } /* Este laço refina a busca do teta */ for (teta=mteta-10; teta<=mteta+15; teta++) { double cteta = cos(teta/180.0*pi); double steta = sin(teta/180.0*pi); iteta = (int)(teta*(Tmax/180) + 0.5 + Tmax) % Tmax; /* um valor de teta indica um índice da matriz, portanto, aumenta todos os valores de teta pra que a contagem se inicie em zero. */ iL = (int)((Lmax + distancia(i,j,cteta,steta))/2 + 0.5); if (i == 100) { fprintf(stderr, " iteta = %d iL = %d\n", iteta,iL); } if ((iL < 0) || (iL > Lmax)) { fprintf(stderr, "** bad iL [%d,%d] = %d **\n", i,j,iL); } else { M[Lmax*iteta + iL] += Gv; } } } } salvaimagem(5, MLINHAS, NULL, NULL, "det.pgm", largura, altura, 255); free(MLINHAS); /*o máximo valor de maior é de 0.972401*/ /* Escreve matriz: */ for (i = 0; i < n; i++) { double Mi = M[i]; if (Mi>maior) { maior = Mi; } } fprintf(stderr, "maior = %f", maior); for (i = 0; i < n; i++) { int Gi = (int)(255*M[i]/maior + 0.5); if (Gi > 255) { Gi = 255; } G[i] = Gi; } /*esta imagem é uma foto da transformada de Hough */ salvaimagem(5, G, NULL, NULL, "f8.pgm", Lmax, 180, 255); free(G); /* pega os nlinhas maiores valores */ lista=novalista(nlinhas); for (i=0; ilista->cmin) || (lista->tamtammax) ) { no = novono(); no->c=M[i];/* a lista é ordenada por valores decrescentes de c */ no->v=-90+linha(i,Lmax);/*teta*/ no->h=coluna(i,Lmax);/*L*/ insereno(no, lista); } } if ( (mm=(double *)calloc(2*nlinhas +1, sizeof(double))) == NULL ) { printf("Falha ao alocar mm em detecta2.\n"); } mm[0] = 2*nlinhas; no=lista->primno; for (i=1; i<=lista->tam; i++) { mm[i]=(double)no->v; /*teta*/ mm[i+nlinhas]=(double)no->h; /* L */ no=no->prox; } liberalista(lista); return mm; } /* usa uma gaussiana unidimensional */ void detectalinhas(int *R, int largura, int altura, int *G) { int i=0, j=0;/*contadores*/ double teta=0; double *ci; /* Na figura grande(f0a.ppm) o ponto (306,173) é uma linha*/ /* (129,144) é reta na vertical(angulo 87 graus) na figura f0.ppm */ /* chutando fator o */ ci = curvaideal(0, SIGMA, R, largura); /*Para cada pixel da imagem grande*/ for (i=JRAIO; i<(altura-JRAIO); i++) { fprintf(stderr, "."); for (j=JRAIO; j<(largura-JRAIO); j++) { double cmax = -1e30, Gv; for (teta=-90; teta<90; teta+=5) { double cteta = cos(teta/180.0*pi); double steta = sin(teta/180.0*pi); double c; c=calculacurvacasamento(R,largura,i,j,cteta,steta,ci); if (c > cmax) { cmax = c; } } /*este if eh soh para testes */ /* if ((i > 100) && (i < 150) && (j > 100) && (j < 150)) { fprintf(stderr, "(%f)", cmax); }*/ /* cmax é a melhor nota para todos os angulos teta neste pixel */ /* cmax = 0 se o casamento foi perfeito. */ /* cmax << 0 se o casamento foi ruim. */ /* Gv = 1.0 se casamento perfeito, 0.0 se péssimo. */ Gv = (15 - fabs(cmax))/15.0; if (Gv < 0.0) { Gv = 0.0; } if (Gv > 1.0) { Gv = 1.0; } G[indice(i,j,largura)] = (int)(255 * Gv + 0.5); } } if (ci) free(ci); } int *extrailinhas(int n, int *R, int largura, int altura) { int i=0, j=0;/*contadores*/ double teta=0; no_t *no=NULL; lista_t *lista=NULL; int *m; double *ci; /* Na figura grande(f0a.ppm) o ponto (306,173) é uma linha*/ /* (129,144) é reta na vertical(angulo 87 graus) na figura f0.ppm */ /* chutando o fator sigma */ ci = curvaideal(0, SIGMA, R, largura); lista=novalista(TAMMAX); /*Para cada pixel da imagem grande*/ for (i=JRAIO; i<(altura-JRAIO); i++) { for (j=JRAIO; j<(largura-JRAIO); j++) { for (teta=-90; teta<90; teta+=5) { double cteta = cos(teta/180.0*pi); double steta = sin(teta/180.0*pi); no=novono(); no->teta=teta; no->v=i; no->h=j; no->c=calculacurvacasamento(R,largura,i,j,cteta,steta,ci); insereno(no, lista); } } } printf("Inicia o Bucketing.\n"); m=bucketing(lista, largura, altura); printf("Termina o Bucketing.\n"); liberalista(lista); printf("Antes de extrair picos.\n"); lista = extraipicos(n,m,largura,altura); printf("Termina extração de picos.\n"); free(m); if ( (m=(int *)calloc(2*n, sizeof(int))) == NULL ) printf("Problemas ao alocar m.\n"); no=lista->primno; for(i=0; i<2*n; i++) { m[i]=no->v; m[2*i]=no->teta; no=no->prox; } printf("Terminou(quase).\n"); liberalista(lista); return m; } char *txtcat (char *a, char *b) { char *r = malloc(strlen(a)+strlen(b)+1); if (r == NULL) { printf("txtcat - Não foi possivel alocar cadeia"); } strcpy(r, a); strcat(r, b); return(r); } case '4': carregaimagem(&R, &G, &B, arq_in, &largura, &altura, &maxcor); m = extrailinhas(10,R,largura,altura); for (i=0; i<10; i++) { pinta(m[i],m[2*i],R,NULL,NULL,largura,altura,maxcor); } free(m); salvaimagem(5, R, NULL, NULL, txtcat(pref_out, ".pgm"), largura, altura, maxcor); break; case '5': carregaimagem(&R, &G, &B, arq_in, &largura, &altura, &maxcor); alocaimagemcinza(&D, largura, altura); detectalinhas(R,largura,altura,D); salvaimagem(5, D, NULL, NULL, txtcat(pref_out, ".pgm"), largura, altura, maxcor); break; case '8': carregaimagem(&R, &G, &B, arq_in, &largura, &altura, &maxcor); mm = detectalinhas2(10,R,largura,altura); for (i=1; i<=10; i++) { // printf("teta: (%d) L: (%d)\n", mm[i], mm[i+10]); pinta(mm[i+10],mm[i],R,NULL,NULL,largura,altura,maxcor); } free(mm); salvaimagem(5, R, NULL, NULL, txtcat(pref_out, ".pgm"), largura, altura, maxcor); break;