ldistance_ima.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 
00049 #include <stdio.h>
00050 #include <stdlib.h>
00051 #include <math.h>
00052 #include "image.h"
00053 #include "proto2D.h"
00054 #include "distance_ima.h"
00055 
00056 
00057 #define   max(x,y)  (((x)>(y))?(x):(y))
00058 #define   min(x,y)  (((x)<(y))?(x):(y))
00059 #define   abs(x) ((x>0)?x:-x)
00060 
00061 typedef  unsigned char Byte;
00062 
00063 
00064 
00065 /* ****************************************************************************/
00066 /*                             FONCTION MINIMUN                               */
00067 /*   Cette fonction retourne le minimum d'un tableau de 25 elements .         */
00068 /*   ainsi que sa position x0 et y0                                           */
00069 /* ****************************************************************************/
00070 
00071 
00072 int  minimum( unsigned int   masque[5][5],
00073               unsigned int   *x0, unsigned int *y0)
00074 {
00075      register int i,j;
00076      int mini, mini1;
00077 
00078      mini=masque[0][0];
00079      *x0 = 0;
00080      *y0 = 0;
00081      for ( i=0 ; i<5 ; i++ )
00082          for ( j=0 ; j<5 ; j++ )
00083          {            
00084              mini1=min(masque[i][j],mini);
00085              if (mini1 < mini)
00086              {
00087                 mini = mini1;
00088                 *x0 = i;
00089                 *y0 = j;
00090              }  
00091          }
00092 
00093          return   mini;               
00094      }
00095 
00096 
00097 /* ***************************************************************************/
00098 /*                       FIN  FONCTION MINIMUN                               */
00099 /* ***************************************************************************/
00100 
00101 
00102 /* ***************************************************************************/
00103 /*                             FONCTION DISTANCE                             */
00104 /*   Cette fonction calcule la distance de chaque pixel d'une image au       */
00105 /*                    fond ( Background ).                                   */
00106 /* ***************************************************************************/
00107 
00108 void  distance(imau1 *im1, imau1 *im2 , float l, int n)
00109 {
00110 
00111        register int   x,y;
00112        int            a1,b1,c1,d1,e1;
00113        int            maximum,fin,niveau,recop,recop1;
00114        int            w,compt;
00115        unsigned int   x1,y1;
00116        double         val;
00117        float          valeur,inter;
00118        float          tt,vv,s;
00119        float          n1,n2,n3,num,denom;
00120        float          delta1,delta2,delta3;
00121        float          A,B,C,D,E;
00122        int            A1,B1,C1,D1,E1;   
00123        int            ydebut;
00124        int            *ima_dist;
00125        int            *ima_dist1;
00126        int            *ima_sir;
00127        unsigned int   fen[5][5];
00128        int            largeur, hauteur;
00129        Byte  * ima1, *ima2;
00130 
00131                /*-----------------------------------------------------*/
00132                /*      CALCUL DES COEFFICIENTS OPTIMAUX A,B,C,D,E.    */
00133                /*-----------------------------------------------------*/
00134 
00135        largeur = im1->nc;
00136        hauteur = im1->nr;
00137        ima1 = im1->p[0];
00138        ima2 = im2->p[0];
00139 
00140        ima_dist=(int *)calloc(largeur*hauteur,sizeof(int));
00141        ima_dist1=(int *)calloc(largeur*hauteur,sizeof(int));
00142        ima_sir=(int *)calloc(largeur*hauteur,sizeof(int)); 
00143          
00144        
00145        tt=sqrt(4.0*l*l+1.0);
00146        vv=sqrt(1.0*l*l+4.0);
00147        s=sqrt(1.0*l*l+1.0); 
00148        delta1=4.0*l*l*(1.0+(tt-2.0*l)*(tt-2.0*l)); 
00149        delta3=l*l+(vv-2.0)*(vv-2.0); 
00150        A=(-2.0*l+sqrt(delta1))/(tt-2.0*l)/(tt-2.0*l);
00151        a1=floor((A*n)+0.5);
00152        C=A*tt/l;
00153        c1=floor((C*n)+0.5);
00154        n1=C*(1.0+2.0*l*l)-2.0*l*l/s;
00155        denom=1.0+4.0*l*l-l*l/s/s;  
00156        n2=C*C*(1.0+l*l)-4.0*l*l;
00157        delta2=n1*n1-n2*denom;
00158        num=n1+sqrt(delta2);
00159        B=num/denom;
00160        b1=floor((B*n)+0.5);
00161        num=2.0*l*sqrt(delta3)-2.0*l*l; 
00162        denom=(vv-2.0)*(vv-2.0);
00163        D=num/denom;
00164        d1=floor((D*n)+0.5);
00165        E=D*vv;
00166        e1=floor((E*n)+0.5);
00167 
00168        printf("Aopt=%d  Bopt=%d  Copt=%d  Dopt=%d   Eopt=%d\n",a1,b1,c1,d1,e1); 
00169        printf("pour n=%d  et L=%f\n",n,l);
00170 
00171 
00172             /*----------------------------------------------*/
00173             /*          MISE EN FORME DE L'IMAGE SOURCE     */
00174             /*----------------------------------------------*/
00175 /* On traite une image binaire: Objet = 0,  Fond = 255   *****/
00176 /* les points du fond initialement a 255 sont mis a l'infini ***/
00177 /* les autres, donc l'objet reste a 0                   ***/
00178    
00179        fin=(largeur)*(hauteur);
00180 
00181            printf("largeur= %d  hauteur= %d\n",largeur,hauteur);       
00182       
00183        for ( x=0 ; x<fin ; x++ )
00184            {
00185            if ( ima1[x]!=0)
00186            ima_sir[x]=20000;
00187            else  ima_sir[x]=0; 
00188            }
00189 
00190   
00191 /* ima_sir = image de reference utiliser pour calculer l'image de distance **/
00192 /* ima_dist1 = image de distance apres le passage du masque_avant     *******/
00193 /* ima_dist  = image de distance finale   *****/      
00194 
00195            /*----------------------------------------------*/
00196            /*               BOUCLE ALLER                   */
00197            /*  Balayage de gche a drte et de haut en bas   */
00198            /*----------------------------------------------*/
00199         
00200        for ( y=2 ; y<hauteur-2 ; y++ )
00201            for ( x=2 ; x<largeur-2 ; x++ )
00202                {
00203                w=x+y*largeur;
00204                if (ima_sir[w]!=0)
00205                {
00206                                 /* comparaison avec le masque avant  ****/                                               
00207                   fen[0][0]=(2*b1)+(ima_sir[w-2*largeur-2]);
00208                   fen[0][1]=(e1)+(ima_sir[w-2*largeur-1]);  
00209                   fen[0][2]=(2*d1)+(ima_sir[w-2*largeur]);  
00210                   fen[0][3]=(e1)+(ima_sir[w-2*largeur+1]);  
00211                   fen[0][4]=(2*b1)+(ima_sir[w-2*largeur+2]);  
00212                    
00213                   fen[1][0]=(c1)+(ima_sir[w-largeur-2]);      
00214                   fen[1][1]=(b1)+(ima_sir[w-largeur-1]);    
00215                   fen[1][2]=(d1)+(ima_sir[w-largeur]);    
00216                   fen[1][3]=(b1)+(ima_sir[w-largeur+1]);   
00217                   fen[1][4]=(c1)+(ima_sir[w-largeur+2]);
00218 
00219                   fen[2][0]=(2*a1)+(ima_sir[w-2]);
00220                   fen[2][1]=(a1)+(ima_sir[w-1]);    
00221                   fen[2][2]=20000;   
00222                   fen[2][3]=20000;                 
00223                   fen[2][4]=20000; 
00224                      
00225                   fen[3][0]=20000;                
00226                   fen[3][1]=20000;                 
00227                   fen[3][3]=20000;                  
00228                   fen[3][4]=20000;
00229                   fen[3][2]=20000;
00230                   fen[4][0]=fen[4][1]=fen[4][2]=fen[4][3]=fen[4][4]=20000;
00231  
00232                   
00233                   ima_dist1[w]=minimum(fen,&x1,&y1);
00234                   ima_sir[w]=ima_dist1[w];
00235                 }
00236                 else ima_dist[w] = 0;
00237                }                        /*    fin du for */
00238 
00239 
00240       /*-------------------------------------------------------*/             
00241       /*                     BOUCLE RETOUR                     */
00242       /*  Balayage de l'image de drte a gche et de bas en haut */
00243       /*-------------------------------------------------------*/
00244         
00245        for ( y=hauteur-3 ; y>1 ; y-- )
00246            for ( x=largeur-3 ; x>1 ; x-- )
00247                {
00248                w=x+(y)*largeur;
00249                if (ima_sir[w]!=0)
00250                {
00251                                 /* comparaison avec le masque arriere  ****/
00252 
00253                   fen[4][0]=(2*b1)+(ima_sir[w+2*largeur-2]);
00254                   fen[4][1]=(e1)+(ima_sir[w+2*largeur-1]);  
00255                   fen[4][2]=(2*d1)+(ima_sir[w+2*largeur]);  
00256                   fen[4][3]=(e1)+(ima_sir[w+2*largeur+1]);  
00257                   fen[4][4]=(2*b1)+(ima_sir[w+2*largeur+2]);  
00258                    
00259                   fen[3][0]=(c1)+(ima_sir[w+largeur-2]);      
00260                   fen[3][1]=(b1)+(ima_sir[w+largeur-1]);    
00261                   fen[3][2]=(d1)+(ima_sir[w+largeur]);    
00262                   fen[3][3]=(b1)+(ima_sir[w+largeur+1]);   
00263                   fen[3][4]=(c1)+(ima_sir[w+largeur+2]);
00264 
00265                   fen[2][4]=(2*a1)+(ima_sir[w+2]);
00266                   fen[2][3]=(a1)+(ima_sir[w+1]);    
00267                   fen[2][2]=20000;   
00268                   fen[2][0]=20000;                 
00269                   fen[2][1]=20000;                      
00270                   fen[0][0]=fen[0][1]=fen[0][2]=fen[0][3]=fen[0][4]=20000;
00271 
00272                   fen[1][0]=20000;                  
00273                   fen[1][1]=20000;
00274                   fen[1][3]=20000;                 
00275                   fen[1][4]=20000;
00276                   fen[1][2]=20000;
00277              
00278                   recop1=minimum(fen,&x1,&y1);
00279                   recop=ima_dist1[w];                 
00280                   ima_dist[w]=min(recop,recop1);
00281                   ima_sir[w]=ima_dist[w];
00282                 }
00283                 else ima_dist[w]=0;        
00284                              
00285               }              /*    fin du for */
00286 
00287 
00288              /*----------------------------------------------------*/   
00289              /*          remplissage de ima_dest                   */
00290              /*   Les valeurs obtenues sont ramenees au Byte (255) */
00291              /*----------------------------------------------------*/
00292       
00293 /* recherche de la valeur maximale, pour la Normalisation  *****/
00294         maximum=ima_dist[0];
00295         for ( x=0 ; x<fin ; x++ )
00296              maximum=max(ima_dist[x],maximum); 
00297 
00298 
00299 /* Pour afficher l'image de DISTANCE il faut que les valeurs  ******/
00300 /*  soient inferieures a 256    ==> normalisation des niveaux    ******/
00301         for ( y=(fin-1) ; y>=0 ; y-- )
00302             ima2[y] = (Byte)(ima_dist[y]*255.0/maximum);
00303       
00304 
00305 
00306 
00307         printf("\nFIN IMAGE DE DISTANCE: \n");
00308         printf("\n");
00309                 
00310         cfree(ima_sir);
00311         cfree(ima_dist);
00312         cfree(ima_dist1);  
00313 
00314 }                      /*    fin de distance    */
00315 
00316 
00328 param *distance_imau1_lect( image_distance_t *des, param * ptp, char * debq)
00329 {
00330   char question[500];
00331 
00332   sprintf(question, "%s Valeur de l (reel)", debq);
00333   lec_param(question, ptp);
00334   des->l = atof(ptp->rep);
00335   ptp = ptp->next;
00336 
00337   sprintf(question, "%s Valeur de n (entier)", debq);
00338   lec_param(question, ptp);
00339   des->n = atoi(ptp->rep);
00340   ptp = ptp->next;
00341 
00342   return(ptp);
00343   printf("sortie lect\n");
00344 }
00345 
00346 
00356 int distance_imau1_init(image_distance_t *des, imau1 *imO, imau1 *imRes)
00357 {
00358         imRes->nr = imO->nr;
00359         imRes->nc = imO->nc;
00360         alloc_imau1(imRes);
00361     
00362 }
00363 
00372 int distance_imau1_calc( image_distance_t *des, imau1 *imO, imau1 *imRes)
00373 {
00374     distance( imO, imRes , des->l, des->n);
00375 }

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