lindexed_img.c

00001 /*
00002 *    Copyright (c) 2007. The BATI team. All right reserved.
00003 *
00004 *    This file is part of BATI library.
00005 *
00006 *    BATI library is free software: you can redistribute it and/or modify
00007 *    it under the terms of the GNU General Public License as published by
00008 *    the Free Software Foundation, either version 3 of the License, or
00009 *    (at your option) any later version.
00010 *
00011 *    BATI library  is distributed in the hope that it will be useful,
00012 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 *    GNU General Public License for more details.
00015 *
00016 *    You should have received a copy of the GNU General Public License
00017 *    along with BATI library.  If not, see <http://www.gnu.org/licenses/>.
00018 */
00019 /* ************************* lindexed_img.c *************************** */
00020 /*                                                                      */
00021 /* ******************************************************************** */
00022 
00036 #include "image.h"
00037 #include "proto2D.h"
00038 #include "indexed_img.h"
00039 #include <stdlib.h>
00040 
00041 
00042 
00043 /* *************************  LECTURE  ****************************** */
00057 param *indexed_img_lect(kohonenstruct *des, param *ptp, char *debq)
00058 {
00059   char question[500];
00060 
00061   sprintf(question, "%s Nombre de couches - val. max 256 (entier)", debq); 
00062   lec_param(question, ptp);
00063   des->nrcouches = atoi(ptp->rep);
00064   ptp = ptp->next;
00065 
00066   sprintf(question, "%s Nombre d'epoques (entier)", debq); 
00067   lec_param(question, ptp);
00068   des->nrepochs = atoi(ptp->rep);
00069   ptp = ptp->next;
00070    
00071   return(ptp);
00072 }
00073 
00074 
00075 /* *************************  INITIALISATION  ************************** */
00088 int indexed_img_init(kohonenstruct *des, imarvb im0, imau1 *imres)
00089 {   
00090   register long int totalElements, i;
00091     
00092   totalElements = 0;
00093   totalElements += im0.nr * im0.nc;  
00094 
00095   imres->nr = im0.nr;
00096   imres->nc = im0.nc;
00097   alloc_imau1(imres);
00098   alloc_lut_u12(imres);
00099 
00100   des->Dist.nr = des->nrcouches;
00101   des->Dist.nc = 1;
00102   alloc_imadb(&des->Dist);
00103 
00104   des->Weight1.nr = 3;
00105   des->Weight1.nc = des->nrcouches;  
00106   alloc_imadb(&des->Weight1);
00107   
00108   des->Weight2.nr = 3;
00109   des->Weight2.nc = des->nrcouches;  
00110   alloc_imadb(&des->Weight2);
00111 
00112   des->TrainingData.nr = 3;
00113   des->TrainingData.nc = totalElements;
00114   alloc_imadb(&des->TrainingData);
00115 
00116   des->T.nr = des->nrcouches;
00117   des->T.nc = 1;
00118   alloc_imau1(&des->T);
00119   
00120 
00121 }
00122 
00123 /* *************************  CALCUL  ************************** */
00139 int indexed_img_calc(kohonenstruct *des, imarvb im0, imau1 *imres)
00140 {
00141     register int l, c, i, j, x, y, k, t, left, center, right, neighbourhood;
00142     double minf, auxf = 0.0, w2_w1, sigma, learningRatio;
00143     double sigma_max, sigma_min, a, b, q, learn0, smin, smax;
00144     register long int currImage, totalElements;
00145 
00146     pixu1 rouge, vert, bleu;
00147    
00148     FILE *fStream;
00149     char *filename = "WEIGHTS.TXT";    
00150     unsigned char tampon = 0;
00151 
00152     /* ***************************************** */
00153     /*  Construction de l'ensemble de donnes pour l'entrainement  */
00154 
00155   printf("\nOn cree l'ensemble des donnees pour l'entrainement ..."); 
00156 
00157   i = 0;
00158      for(y = 0; y < im0.nc; y++)
00159        for(x = 0; x < im0.nr; x++){
00160            des->TrainingData.p[0][i] = im0.r[x][y]; 
00161            des->TrainingData.p[1][i] = im0.v[x][y];
00162            des->TrainingData.p[2][i] = im0.b[x][y];
00163            i++;
00164        }
00165 
00166   // initialization des poids
00167   j = 0;
00168   for(i = 0; i < des->nrcouches ; i++) {
00169      des->Weight1.p[0][i] = des->TrainingData.p[0][j];
00170      des->Weight1.p[1][i] = des->TrainingData.p[1][j];
00171      des->Weight1.p[2][i] = des->TrainingData.p[2][j];
00172      j += (int)((pixdb)(des->TrainingData.nc) / (pixdb)(des->nrcouches));
00173   }
00174  
00175   printf("fait\n");
00176 
00177   /* ***************************************** */
00178   /* Antrainer la reseau  */
00179   
00180   k = t = 0;
00181   printf("\nOn entraine le reseau ...\n\n");
00182   smax = -(des->nrcouches)/ (2 * log(0.1));
00183   sigma_max = sqrt(smax);
00184   smin = -1 / log(0.1);
00185   sigma_min = sqrt(smin);
00186   a = (des->nrcouches / 2 - 1) / (sigma_max - sigma_min);
00187   b = (sigma_max - (des->nrcouches) * sigma_min / 2) / (sigma_max - sigma_min);
00188   q = (sigma_max - sigma_min) / des->nrepochs;
00189   sigma = sigma_max;
00190   learn0 = (pixdb)(des->TrainingData.nr) / 4 + 4;
00191   
00192   do {
00193 
00194     srand(0);
00195     for(i = 0; i < (des->TrainingData.nc); i += (int)(150 *(double)rand() / RAND_MAX)) {
00196 
00197        printf("%cEpoque %d / %d en cours...", 13, k + 1, des->nrepochs);
00198        fflush(stdout);
00199   
00200        // Calcule les distances 
00201        for(c = 0; c < des->nrcouches; c++) {
00202          des->Dist.p[0][c] = 0.0;
00203          des->Dist.p[0][c] += (des->TrainingData.p[0][i] - des->Weight1.p[0][c]) * (des->TrainingData.p[0][i] - des->Weight1.p[0][c]);
00204          des->Dist.p[0][c] += (des->TrainingData.p[1][i] - des->Weight1.p[1][c]) * (des->TrainingData.p[1][i] - des->Weight1.p[1][c]);      
00205          des->Dist.p[0][c] += (des->TrainingData.p[2][i] - des->Weight1.p[2][c]) * (des->TrainingData.p[2][i] - des->Weight1.p[2][c]);      
00206          des->Dist.p[0][c] = sqrt(des->Dist.p[0][c]);
00207             }
00208 
00209        // finding the best matched node
00210        center = des->nrcouches; minf = des->Dist.p[0][0];
00211        for(c = 1; c < des->nrcouches; c++)
00212          if(minf > des->Dist.p[0][c]){
00213            minf = des->Dist.p[0][c];
00214            center = c + des->nrcouches;
00215          } 
00216        
00217        // updating the weights
00218        des->T.p[0][center - (des->nrcouches)]; /*  = des->T.p[0][center - (des->nrcouches)]++; */
00219        neighbourhood = (int)(a * sigma + b);
00220        learningRatio = learn0 / (learn0 + des->T.p[0][center - (des->nrcouches)]);
00221        left = center - neighbourhood;
00222        right = center + neighbourhood;
00223        
00224        for(c = left; c <= right; c++) {
00225           des->Weight2.p[0][c % des->nrcouches] = des->Weight1.p[0][c % des->nrcouches] + learningRatio * exp(((double)c - center) * (center - c) / (2 * sigma *sigma)) * (des->TrainingData.p[0][i] - des->Weight1.p[0][c % des->nrcouches]);
00226           des->Weight2.p[1][c % des->nrcouches] = des->Weight1.p[1][c % des->nrcouches] + learningRatio * exp(((double)c - center) * (center - c) / (2 * sigma *sigma)) * (des->TrainingData.p[1][i] - des->Weight1.p[1][c % des->nrcouches]);
00227           des->Weight2.p[2][c % des->nrcouches] = des->Weight1.p[2][c % des->nrcouches] + learningRatio * exp(((double)c - center) * (center - c) / (2 * sigma *sigma)) * (des->TrainingData.p[2][i] - des->Weight1.p[2][c % des->nrcouches]);
00228        }
00229        
00230        //updating the weights
00231            w2_w1 = ceil(des->Weight2.p[0][0] - des->Weight1.p[0][0]);
00232 
00233        for(c = 0; c < des->nrcouches; c++){
00234            des->Weight1.p[0][c] = des->Weight2.p[0][c];
00235            des->Weight1.p[1][c] = des->Weight2.p[1][c];
00236            des->Weight1.p[2][c] = des->Weight2.p[2][c];
00237        } 
00238        t++;
00239        
00240     } 
00241     k++;
00242     if((auxf = sigma - q) < sigma_min)
00243         sigma = sigma_min;
00244     else
00245         sigma = auxf;
00246    
00247   } while(k < des->nrepochs);
00248  
00249   printf("fait\n"); 
00250   
00251 
00252   /* ****************************************** */
00253   /*   sauvegarder les poids dans fichier   */
00254    
00255    if (fStream = fopen(filename, "w")) {
00256       for (j = 0; j < des->nrcouches; j++)
00257         fprintf(fStream, "%8.4f  %8.4f  %8.4f\n", des->Weight1.p[0][j], des->Weight1.p[1][j], des->Weight1.p[2][j]);
00258     fclose(fStream);
00259    }
00260 
00261 
00262 
00263    /* ***************************************** */
00264    /* Construction de l'image indexee  */
00265 
00266    printf("\nOn cree l'image indexee ...");
00267 
00268       for(c = 0; c < des->nrcouches; c++){
00269            imres->lutr[c] = (pixu1)(ceil(des->Weight2.p[0][c])); 
00270            imres->lutv[c] = (pixu1)(ceil(des->Weight2.p[1][c]));
00271            imres->lutb[c] = (pixu1)(ceil(des->Weight2.p[2][c]));
00272         }
00273 
00274 
00275    for(x = 0; x < im0.nr; x++)
00276      for(y = 0; y < im0.nc; y++) {
00277 
00278         // calcule les distances
00279         for(c = 0; c < des->nrcouches; c++) {
00280            des->Dist.p[0][c] = 0.0;
00281            des->Dist.p[0][c] += (im0.r[x][y] - des->Weight2.p[0][c]) * (im0.r[x][y] - des->Weight2.p[0][c]);
00282            des->Dist.p[0][c] += (im0.v[x][y] - des->Weight2.p[1][c]) * (im0.v[x][y] - des->Weight2.p[1][c]);
00283            des->Dist.p[0][c] += (im0.b[x][y] - des->Weight2.p[2][c]) * (im0.b[x][y] - des->Weight2.p[2][c]);
00284            des->Dist.p[0][c] = sqrt(des->Dist.p[0][c]);
00285         }
00286         
00287        // find the best node
00288        center = 0.0;
00289        minf = des->Dist.p[0][0];
00290        for(c = 1; c < des->nrcouches; c++)
00291          if(minf > des->Dist.p[0][c]) {
00292               minf = des->Dist.p[0][c];
00293               center = c;
00294          }
00295        imres->p[x][y] = (unsigned char)center;
00296       }
00297      printf("fait \n");   
00298    
00299    free_imau1(&des->T); 
00300    free_imadb(&des->TrainingData);
00301    free_imadb(&des->Weight2);
00302    free_imadb(&des->Dist);
00303 }
00304 
00305 
00306 int alloc_lut_u12(imau1 *im)
00307 {
00308    if( im->lutr!=NULL && im->lutv!=NULL && im->lutb!=NULL ){
00309         free(im->lutr);
00310         free(im->lutv);
00311         free(im->lutb);
00312     }           
00313 
00314 
00315         if( (im->lutr = (pixu1*)malloc(256 * sizeof(pixu1))) == NULL ||
00316             (im->lutv = (pixu1*)malloc(256 * sizeof(pixu1))) == NULL ||
00317             (im->lutb = (pixu1*)malloc(256 * sizeof(pixu1))) == NULL )
00318           {
00319           printf ("lutr, lutv, lutb: ERREUR allocation impossible\n");  
00320           exit(1); 
00321           }
00322 }
00323 
00324 int free_lut_u12(imau1 *im)
00325 {
00326   free(im->lutb); im->lutb = NULL;
00327   free(im->lutv); im->lutv = NULL;
00328   free(im->lutr); im->lutr = NULL;
00329   
00330 }
00331 

Generated on Tue Apr 22 13:31:04 2008 for ima2D by  doxygen 1.5.3