#include #include #define DFUNDO (0.25) #define True 1 #define False 0 // PROTOTIPOS INTERNOS void plotaFila( Plotter_t *plt, filaCandidatos_t *fila, QFILA_t qual, int iteracao, int nBoxes, int res_max, float Dmin, float Dmax ); candidato_t *escolheCandidato(filaCandidatos_t *fila,QFILA_t qual); // Escolhe o proximo candidato da fila a refinar de acordo com qual. // IMPLEMENTACOES //lê a imagem na escala informada float_image_t *leImagemTipoEscala(char *bandir,char *tipo,int res,char *nome, char *ext) { char *filename = jsprintf("%s/%s/%s/R%02d.%s",bandir,nome,tipo,res,ext); float_image_t *I=getImageOpenRGB(filename); free(filename); return I; } //função do cálculo da distância dlo float dLoRGB(float aLo,float aHi,float bLo,float bHi,int bgZero) { float xHi,yLo; if (aLo>bLo) { xHi=bHi; yLo=aLo; } else { xHi=aHi; yLo=bLo; } if (xHi>=yLo) return 0; else if (bgZero) { if ((aLo==0)&&(aHi==0)) return DFUNDO; else if ((bLo==0)&&(bHi==0)) return DFUNDO; } else if (aHi < bLo) return (bLo-aHi); else if (aLo > bHi) return (aLo-bHi); assert(0); // Nao deveria chegar aqui. } //função do cálculo da distância dhi float dHiRGB(float aLo,float aHi,float bLo,float bHi,int bgZero) { if ((aLo == 0) && (aHi == 0) && (bLo == 0) && (bHi == 0)) return 0; else if (bgZero && ((aLo == 0) || (bLo == 0))) return DFUNDO; else { float a = fabs(aHi-bLo); float b = fabs(bHi-aLo); if (a>b) return a; else return b; } } //realiza o cálculo da distância distlo entre duas imagens float distLoRGB(float_image_t *Alo,float_image_t *Ahi,float_image_t *Blo,float_image_t *Bhi,int bgZero) { int i=0,j=0,ch=0; float valor=0.0,soma=0.0; for (ch=0;ch< Alo->sz[0];ch++) { for (i=0;isz[1];i++) { for (j=0;jsz[2];j++) { valor=dLoRGB ( float_image_get_sample(Alo,ch,i,j), float_image_get_sample(Ahi,ch,i,j), float_image_get_sample(Blo,ch,i,j), float_image_get_sample(Bhi,ch,i,j), bgZero ); soma+=valor; } } } i=Alo->sz[1]*Alo->sz[2]*Alo->sz[0]; soma=soma/i; return soma; } //realiza o cálculo da distância disthi entre duas imagens float distHiRGB(float_image_t *Alo,float_image_t *Ahi,float_image_t *Blo,float_image_t *Bhi,int bgZero) { int i=0,j=0,ch=0; float valor=0.0,soma=0.0; for (ch=0;chsz[0];ch++) { for (i=0;isz[1];i++) { for (j=0;jsz[2];j++) { valor=dHiRGB ( float_image_get_sample(Alo,ch,i,j), float_image_get_sample(Ahi,ch,i,j), float_image_get_sample(Blo,ch,i,j), float_image_get_sample(Bhi,ch,i,j), bgZero); soma+=valor; } } } i=Alo->sz[1]*Alo->sz[2]*Alo->sz[0]; soma=soma/i; return soma; } void gravaCand(candidato_t *cand,FILE *arq) { fprintf(arq,"%s %02d %8.6f %8.6f %8.6f %8.6f\n",cand->nome,cand->k,cand->distLo,cand->distHi,0.0,0.0); fflush(arq); } void limpaRuins(filaCandidatos_t *fila,int *m) { if ((*m) > fila->n) { (*m) = fila->n; } if ((*m) >= fila->n) { return; } assert((*m) > 0); // Determina o corte - m-esimo Hi: candidato_t *aux = indexaCand(fila,(*m) - 1, QFILA_Hi, comparaCandidatos); assert(aux != NULL); float corte = aux->distHi; // Elimina todo mundo acima do corte: candidato_t *ele = fila->prim[QFILA_Lo]; // Primeiro em ordem de Lo // procura o primeiro ruim: while ((ele != NULL) && (ele->distLo <= corte)) { ele = ele->prox[QFILA_Lo]; } // Elimina todos dali para a frente: while (ele != NULL) { assert(ele->distLo > corte); candidato_t *pro = ele->prox[QFILA_Lo]; // Salva o proximo da lista retiraCandidato(fila,ele); ele = pro; } assert(fila->n >= (*m)); } void limpaBons(filaCandidatos_t *fila,int *m,FILE *arq) { if ((*m) > fila->n) { (*m) = fila->n; } while ((*m) > 0) { assert(fila->n > 0); candidato_t *cmin = indexaCand(fila,0,QFILA_Lo, comparaCandidatos); // candidato com menor Lo assert(cmin != NULL); candidato_t *cseg = indexaCand(fila,1,QFILA_Lo, comparaCandidatos); // candidato com segundo menor Lo, ou NULL if ((cseg != NULL) && (cmin->distHi > cseg->distLo)) break; gravaCand(cmin,arq); retiraCandidato(fila,cmin); (*m)--; } } void selecaoImagemOrdenadasRGB( char *bandir, char *model_name, char *ext, int res_max, int fator, int num_imagens, char *nome_imagem[], int num_resultados, int distsPorNivel[], int bgZero ) { int debug = 1; // Piramide da imagem modelo float_image_t *modeloHi[res_max+1]; float_image_t *modeloLo[res_max+1]; int i; for (i=0; i <= res_max; i++) { modeloLo[i]=leImagemTipoEscala(bandir,"Lo",i,model_name,ext); modeloHi[i]=leImagemTipoEscala(bandir,"Hi",i,model_name,ext); } // Inicializa fila de candidatos: filaCandidatos_t fila = criaFila(); for (i=0; i 100) { num_plotar = 100; } int online = 1; Plotter_t *plt = openPlotter(bandir, model_name, online); while (num_resultados > 0) { // Determina Dmin = menor Lo assert(fila.n >= num_resultados); float Dmin = indexaCand(&fila,0,QFILA_Lo, comparaCandidatos)->distLo; // Determina Dmax = m-esimo menor Hi float Dmax = indexaCand(&fila,num_resultados-1,QFILA_Hi, comparaCandidatos)->distHi; if (debug) { fprintf(stderr, "Dmin = %8.6f Dmax = %8.6f\n", Dmin, Dmax); } assert(Dmin <= Dmax); // Gera um arquivo com as informações atuais plotaFila(plt, &fila, qPl, iteracao, num_plotar, res_max, Dmin, Dmax); iteracao++; // Escolhe candidato para refinar e tira da fila: candidato_t *cand = escolheCandidato(&fila,QFILA_Lo); assert(cand != NULL); if (debug) { fprintf(stderr, "Retirado: "); exibeCand(cand); } char *cand_nome = cand->nome; int cand_k = cand->k; float old_distLo = cand->distLo; float old_distHi = cand->distHi; assert(old_distLo <= old_distHi); retiraCandidato(&fila,cand); cand = NULL; // Refina o candidato: int res = cand_k - 1; assert(res >= 0); float_image_t *BLo=leImagemTipoEscala(bandir,"Lo",res,cand_nome,ext); float_image_t *BHi=leImagemTipoEscala(bandir,"Hi",res,cand_nome,ext); float distLo=distLoRGB(modeloLo[res],modeloHi[res],BLo,BHi,bgZero); float distHi=distHiRGB(modeloLo[res],modeloHi[res],BLo,BHi,bgZero); distsPorNivel[res]++; float_image_free(BLo); float_image_free(BHi); if (debug) { fprintf(stderr, "Calculado: distLo: %8.6f distHi: %8.6f\n", distLo, distHi); fprintf(stderr, "Iteracao: %d\n", iteracao); } if (distLo < old_distLo) { distLo = old_distLo; } if (distHi > old_distHi) { distHi = old_distHi; } assert(distLo <= distHi); cand = insereCandidato(&fila,cand_nome,res,distLo,distHi,comparaCandidatos); if (debug) { fprintf(stderr, "Inserido: "); exibeCand(cand); } if (debug) { fprintf(stderr, "Antes da limpeza n = %d\n", fila.n); } limpaRuins(&fila,&num_resultados); if (debug) { fprintf(stderr, "Limpou ruins n = %d\n", fila.n); } limpaBons(&fila,&num_resultados,arq_resultados); if (debug) { fprintf(stderr, "Limpou bons n = %d\n", fila.n); } if (debug) { fprintf(stderr, "\n"); } } // Limpeza final for (i=0; i <= res_max; i++) { float_image_free(modeloLo[i]); float_image_free(modeloHi[i]); } closePlotter(plt); } candidato_t *escolheCandidato(filaCandidatos_t *fila,QFILA_t qual) { candidato_t *cand0 = NULL; candidato_t *cand1 = NULL; switch(qual) { case QFILA_Lo: { cand0 = indexaCand(fila,0,QFILA_Lo, comparaCandidatos); cand1 = indexaCand(fila,1,QFILA_Lo, comparaCandidatos); assert(cand0 != NULL); assert((cand0->k != 0) || (cand1->k != 0)); // Deveria ter caido fora no limpaBons! if (cand1 == NULL) { return cand0; } else if (cand0->k > cand1->k) { return cand0; } else { return cand1; } } case QFILA_Hi: { cand0 = indexaCand(fila,0,QFILA_Hi, comparaCandidatos); cand1 = indexaCand(fila,1,QFILA_Hi, comparaCandidatos); assert(cand0 != NULL); assert((cand0->k != 0) || (cand1->k == 0)); // Deveria ter caido fora no limpaBons! if (cand1 == NULL) { return cand0; } else if (cand0->k == 0) { return cand1; } else if (cand1->k == 0) { return cand0; } else if (cand0->k > cand1->k) { return cand1; } else if (cand0->k < cand1->k) { return cand0; } else { return cand0; } } case QFILA_Ex: { cand0 = indexaCand(fila,0,QFILA_Ex, comparaCandidatos); assert(cand0 != NULL); while (cand0->k==0) { cand0=cand0->prox[qual]; } assert(cand0!=NULL); return cand0; } default: assert(0); } } void plotaFila( Plotter_t *plt, filaCandidatos_t *fila, QFILA_t qual, int iteracao, int nBoxes, int res_max, float Dmin, float Dmax ) { beginPlot(plt, nBoxes, iteracao); drawQueue(plt, fila->prim[qual], qual, res_max, Dmin, Dmax); endPlot(plt); } int comparaCandidatos(candidato_t *x,candidato_t *y,QFILA_t qual) { switch(qual) { case QFILA_Lo: { if (x->distLo < y->distLo) { return -1; } else if (x->distLo > y->distLo) { return +1; } else if (x->k > y->k) { return -1; } else if (x->k < y->k) { return +1; } else {return 0; } } case QFILA_Hi: { if (x->distHi < y->distHi) { return -1; } else if (x->distHi > y->distHi) { return +1; } else if (x->k > y->k) { return -1; } else if (x->k < y->k) { return +1; } else {return 0; } } case QFILA_Ex: { float xMd = (x->distLo + x->distHi)/2; float yMd = (y->distLo + y->distHi)/2; if (xMd < yMd) { return -1; } else if (xMd > yMd) { return +1; } else if (x->k > y->k) { return -1; } else if (x->k < y->k) { return +1; } else {return 0; } } default: assert(0); } }