00001
00015 #include "interpolation.h"
00016 #include "utils.h"
00017 #include <inrimage/image.h>
00018
00019 extern void imerror ( int code, char * format, ...);
00020 float mediane(char * famille,int j,int buff_length,int dim_x,Fort_int nb_octets,float next);
00021
00033 void dist2isosurf(char *distances,char * famille,float marge,int nb_fam,int time_flag)
00034 {
00035 struct nf_fmt gfmt_in,gfmt_out;
00036
00037 struct image * img_distances;
00038 struct image * img_famille;
00039
00040
00041 char ** buff_famille=NULL;
00042
00043 clock_t t0=0,t1=0;
00044
00045 int i,k,z_in,z_out,nv_zero;
00046
00047
00048 if (time_flag)
00049 t0 = clock();
00050
00051
00052
00053 for (i=0;i<9;i++)
00054 gfmt_in.lfmt[i]=0;
00055 for (i=0;i<3;i++)
00056 gfmt_in.offsets[i]=0;
00057 gfmt_in.maille=0;
00058 gfmt_in.bias=0;
00059 gfmt_in.scale=1;
00060
00061
00062 img_distances=image_(distances,"e","",&gfmt_in);
00063
00064
00065 if ((gfmt_in.lfmt[I_NDIMZ]<2))
00066 imerror(6,"dist2isosurf: Erreur: image en 3D requise pour %s, valeur lue: %d\n",distances,gfmt_in.lfmt[I_NDIMZ]);
00067
00068 z_in = gfmt_in.lfmt[I_NDIMZ];
00069
00070 buff_famille=separation(img_distances,gfmt_in,&gfmt_out,marge,nb_fam,&nv_zero,max(time_flag-1,0));
00071
00072 z_out = gfmt_out.lfmt[I_NDIMZ];
00073
00074 img_famille=image_(famille,"c","a",&gfmt_out);
00075
00076
00077
00078 switch(gfmt_out.lfmt[I_BSIZE])
00079 {
00080 case 1:
00081 for (k=0;k<z_out;k++)
00082 ecr_(&img_famille,&(gfmt_in.lfmt[I_NDIMY]),buff_famille[k]);
00083 break;
00084 case 4:
00085 for (k=0;k<z_out;k++)
00086 ecrflt_(&img_famille,&(gfmt_in.lfmt[I_NDIMY]),buff_famille[k]);
00087 break;
00088 }
00089
00090
00091 for (k=0;k<z_out;k++)
00092 i_Free(&(buff_famille[k]));
00093 free(buff_famille);
00094 buff_famille=NULL;
00095
00096 fermnf_(&img_distances);
00097 fermnf_(&img_famille);
00098
00099 if (time_flag)
00100 {
00101 t1=clock()-t0;
00102 printf("dist2isosurf: temps mis: %f secondes\n",t1/(float)CLOCKS_PER_SEC);
00103 }
00104 }
00105
00121 char ** separation(struct image * img_distances,struct nf_fmt gfmt_in,struct nf_fmt * gfmt_out,float marge,int nb_fam,int * nv_zero,int time_flag)
00122 {
00123 char * buff_distances=NULL;
00124 char ** famille=NULL;
00125
00126 float minDist=0,maxDist=0;
00127 float epsilon;
00128
00129 int i,j,k;
00130 int z_in,z_out,dim_x;
00131 int buff_size,buff_length=0;
00132 int num_plan;
00133
00134 clock_t t0=0,t1=0;
00135
00136
00137 if (time_flag)
00138 t0 = clock();
00139
00140 z_in = gfmt_in.lfmt[I_NDIMZ];
00141
00142
00143 for (i=0;i<9;i++)
00144 gfmt_out->lfmt[i]=gfmt_in.lfmt[i];
00145 for (i=0;i<3;i++)
00146 gfmt_out->offsets[i]=gfmt_in.offsets[i];
00147 gfmt_out->maille=gfmt_in.maille;
00148 gfmt_out->bias=gfmt_in.bias;
00149 gfmt_out->scale=gfmt_in.scale;
00150
00151
00152
00153 extrema3D(img_distances,gfmt_in.lfmt,&minDist,&maxDist);
00154
00155
00156
00157 if (nb_fam!=0)
00158 {
00159
00160 gfmt_out->lfmt[I_NDIMZ]=nb_fam;
00161 }
00162 else if ((maxDist-minDist)<marge)
00163 {
00164 gfmt_out->lfmt[I_NDIMZ]=1;
00165 }
00166 else
00167 {
00168 gfmt_out->lfmt[I_NDIMZ]=(int)((maxDist-minDist)/marge);
00169 }
00170
00171 gfmt_out->lfmt[I_DIMY]=gfmt_out->lfmt[I_NDIMY]*gfmt_out->lfmt[I_NDIMZ];
00172
00173 z_out = gfmt_out->lfmt[I_NDIMZ];
00174 epsilon=(maxDist-minDist)/(float)(z_out);
00175
00176 famille=(char **)malloc (z_out*sizeof(char*));
00177
00178
00179 buff_size = buffer_size(gfmt_out->lfmt,gfmt_out->lfmt[I_NDIMY]);
00180
00181 switch(gfmt_in.lfmt[I_BSIZE])
00182 {
00183 case 1:
00184 buff_length = buff_size/sizeof(char);
00185
00186
00187 for(k=0;k<z_out;k++)
00188 {
00189 famille[k]=i_malloc(buff_size);
00190 for (j=0;j<buff_length;j++)
00191 famille[k][j]=0;
00192 }
00193 break;
00194 case 4:
00195 buff_length = buff_size/sizeof(float);
00196
00197
00198 for(k=0;k<z_out;k++)
00199 {
00200 famille[k]=i_malloc(buff_size);
00201 for (j=0;j<buff_length;j++)
00202 ((float *)(famille[k]))[j]=0;
00203 }
00204 break;
00205 default:
00206 imerror(6,"separation: format non reconnu, codage ni sur 1 ni sur 4 octets\n");
00207 break;
00208 }
00209
00210 buff_distances = i_malloc(buff_size);
00211
00212 *nv_zero=(int)min(z_out-1,(-minDist)/epsilon);
00213
00214
00215
00216 switch(gfmt_in.lfmt[I_BSIZE])
00217 {
00218 case 1:
00219 for (k=0;k<z_in;k++)
00220 {
00221 lect_(&img_distances,&(gfmt_out->lfmt[I_NDIMY]),buff_distances);
00222 for (j=0;j<buff_length;j++)
00223 {
00224 num_plan = (int)min(z_out-1,(((float)(buff_distances[j])-minDist)/epsilon));
00225 famille[num_plan][j]=(char)max((float)(famille[num_plan][j]),255*(float)k/(float)z_in);
00226 }
00227 }
00228 break;
00229 case 4:
00230 for (k=0;k<z_in;k++)
00231 {
00232 lect_(&img_distances,&(gfmt_out->lfmt[I_NDIMY]),buff_distances);
00233 for (j=0;j<buff_length;j++)
00234 {
00235 num_plan = (int)min(z_out-1,((((float *)buff_distances)[j]-minDist)/epsilon));
00236 ((float *)(famille[num_plan]))[j]=max(((float *)(famille[num_plan]))[j],(float)k/(float)z_in);
00237 }
00238 }
00239 break;
00240 }
00241
00242
00243 dim_x=gfmt_out->lfmt[I_NDIMX];
00244
00245 switch(gfmt_in.lfmt[I_BSIZE])
00246 {
00247 case 1:
00248 for (k=*nv_zero;k<z_out;k++)
00249
00250 for (j=0;j<buff_length;j++)
00251 if (famille[k][j]==0)
00252 famille[k][j]=(char)mediane(famille[k],j,buff_length,dim_x,gfmt_out->lfmt[I_BSIZE],(float)(famille[(int)max(k-1,0)][j]));
00253
00254 for (k=*nv_zero-1;k>=0;k--)
00255
00256 for (j=0;j<buff_length;j++)
00257 if (famille[k][j]==0)
00258 famille[k][j]=(char)mediane(famille[k],j,buff_length,dim_x,gfmt_out->lfmt[I_BSIZE],(float)(famille[(int)min(k+1,z_out)][j]));
00259 break;
00260 case 4:
00261 for (k=*nv_zero;k<z_out;k++)
00262
00263 for (j=0;j<buff_length;j++)
00264 if (((float *)(famille[k]))[j]==0)
00265 ((float *)(famille[k]))[j]=mediane(famille[k],j,buff_length,dim_x,gfmt_out->lfmt[I_BSIZE],((float *)(famille[(int)max(k-1,0)]))[j]);
00266
00267 for (k=*nv_zero-1;k>=0;k--)
00268
00269 for (j=0;j<buff_length;j++)
00270 if (((float *)(famille[k]))[j]==0)
00271 ((float *)(famille[k]))[j]=mediane(famille[k],j,buff_length,dim_x,gfmt_out->lfmt[I_BSIZE],((float *)(famille[(int)min(k+1,z_out)]))[j]);
00272 break;
00273 }
00274 i_Free(&buff_distances);
00275 if (time_flag)
00276 {
00277 t1=clock()-t0;
00278 printf("separation: temps mis: %f secondes\n",t1/(float)CLOCKS_PER_SEC);
00279 }
00280
00281 return famille;
00282 }
00283
00284 float moyenne(float a,float b,float c,float d,float e,float f,float g,float h,float i);
00285
00286 float mediane(char * famille,int j,int buff_length,int dim_x,Fort_int nb_octets,float next)
00287 {
00288
00289
00290 if (j<dim_x)
00291 {
00292
00293 if (j == 0)
00294 switch(nb_octets)
00295 {
00296 case 1:
00297 return moyenne(next,famille[1],famille[dim_x],famille[dim_x+1],0,0,0,0,0);
00298
00299
00300 break;
00301 case 4:
00302 return moyenne(next,((float *)famille)[1],((float *)famille)[dim_x],((float *)famille)[dim_x+1],0,0,0,0,0);
00303
00304
00305 break;
00306 }
00307
00308 if (j + 1 == dim_x )
00309 switch(nb_octets)
00310 {
00311 case 1:
00312 return moyenne(next,famille[j-1],famille[j+dim_x],famille[j+dim_x-1],0,0,0,0,0);
00313
00314
00315 break;
00316 case 4:
00317 return moyenne(next,((float *)famille)[j-1],((float *)famille)[j+dim_x],((float *)famille)[j+dim_x-1],0,0,0,0,0);
00318
00319
00320 break;
00321 }
00322
00323 switch(nb_octets)
00324 {
00325 case 1:
00326 return moyenne(next,famille[j-1],famille[j+1],famille[j+dim_x-1],famille[j+dim_x],famille[j+dim_x+1],0,0,0);
00327
00328
00329 break;
00330 case 4:
00331 return moyenne(next,((float *)famille)[j-1],((float *)famille)[j+1],((float *)famille)[j+dim_x-1],((float *)famille)[j+dim_x],((float *)famille)[j+dim_x+1],0,0,0);
00332
00333
00334 break;
00335 }
00336 }
00337
00338
00339
00340 if (j>buff_length-dim_x)
00341 {
00342
00343 if (j%dim_x == 0)
00344 switch(nb_octets)
00345 {
00346 case 1:
00347 return moyenne(next,famille[j+1],famille[j-dim_x],famille[j-dim_x+1],0,0,0,0,0);
00348
00349
00350 break;
00351 case 4:
00352 return moyenne(next,((float *)famille)[j+1],((float *)famille)[j-dim_x],((float *)famille)[j-dim_x+1],0,0,0,0,0);
00353
00354
00355 break;
00356 }
00357
00358
00359 if ((j + 1) % dim_x == 0 )
00360 switch(nb_octets)
00361 {
00362 case 1:
00363 return moyenne(next,famille[j-1],famille[j-1-dim_x],famille[j-dim_x],0,0,0,0,0);
00364
00365
00366 break;
00367 case 4:
00368 return moyenne(next,((float *)famille)[j-1],((float *)famille)[j-1-dim_x],((float *)famille)[j-dim_x],0,0,0,0,0);
00369
00370
00371 break;
00372 }
00373
00374 switch(nb_octets)
00375 {
00376 case 1:
00377 return moyenne(next,famille[j-1],famille[j+1],famille[j-1-dim_x],famille[j-dim_x],famille[j+1-dim_x],0,0,0);
00378
00379
00380 break;
00381 case 4:
00382 return moyenne(next,((float *)famille)[j-1],((float *)famille)[j+1],((float *)famille)[j-1-dim_x],((float *)famille)[j-dim_x],((float *)famille)[j+1-dim_x],0,0,0);
00383
00384
00385 break;
00386 }
00387 }
00388
00389
00390
00391
00392 if (j%dim_x == 0)
00393 switch(nb_octets)
00394 {
00395 case 1:
00396 return moyenne(famille[j-dim_x],famille[j-dim_x+1],next,famille[j+1],famille[j+dim_x],famille[j+dim_x+1],0,0,0);
00397
00398
00399
00400 break;
00401 case 4:
00402 return moyenne(((float *)famille)[j-dim_x],((float *)famille)[j-dim_x+1],next,((float *)famille)[j+1],((float *)famille)[j+dim_x],((float *)famille)[j+dim_x+1],0,0,0);
00403
00404
00405
00406 break;
00407 }
00408
00409 if ((j+1)%dim_x == 0)
00410 switch(nb_octets)
00411 {
00412 case 1:
00413 return moyenne(famille[j-dim_x-1],famille[j-dim_x],famille[j-1],next,famille[j-1+dim_x],famille[j+dim_x],0,0,0);
00414
00415
00416
00417 break;
00418 case 4:
00419 return moyenne(((float *)famille)[j-dim_x-1],((float *)famille)[j-dim_x],((float *)famille)[j-1],next,((float *)famille)[j-1+dim_x],((float *)famille)[j+dim_x],0,0,0);
00420
00421
00422
00423 break;
00424 }
00425 switch(nb_octets)
00426 {
00427 case 1:
00428 return moyenne(famille[j-dim_x-1],famille[j-dim_x],famille[j-dim_x+1],famille[j-1],next,famille[j+1],famille[j+dim_x-1],famille[j+dim_x],famille[j+dim_x+1]);
00429
00430
00431
00432 break;
00433 case 4:
00434 return moyenne(((float *)famille)[j-dim_x-1],((float *)famille)[j-dim_x],((float *)famille)[j-dim_x+1],((float *)famille)[j-1],next,((float *)famille)[j+1],((float *)famille)[j+dim_x-1],((float *)famille)[j+dim_x],((float *)famille)[j+dim_x+1]);
00435
00436
00437
00438 break;
00439 }
00440 return 0;
00441 }
00442
00443 float moyenne(float a,float b,float c,float d,float e,float f,float g,float h,float i)
00444 {
00445 int nb_non_nuls=0;
00446 if (a!=0)
00447 nb_non_nuls++;
00448 if (b!=0)
00449 nb_non_nuls++;
00450 if (c!=0)
00451 nb_non_nuls++;
00452 if (d!=0)
00453 nb_non_nuls++;
00454 if (e!=0)
00455 nb_non_nuls++;
00456 if (f!=0)
00457 nb_non_nuls++;
00458 if (g!=0)
00459 nb_non_nuls++;
00460 if (h!=0)
00461 nb_non_nuls++;
00462 if (i!=0)
00463 nb_non_nuls++;
00464 if (nb_non_nuls)
00465 return ((a+b+c+d+e+f+g+h+i)/nb_non_nuls);
00466 else
00467 return (0);
00468 }