Doxygen Source Code Documentation
Intracranial.c File Reference
Go to the source code of this file.
Defines | |
| #define | AR(i, j) ar[(i)+(j)*nx] |
| #define | MAXLAT 90 |
| #define | MAXLNG 180 |
| #define | AIZE |
Functions | |
| int | verify_inputs () |
| void | draw_2dfiller (int nx, int ny, int ix, int jy, byte *ar) |
| void | center_of_mass (int *cx, int *cy, int *cz) |
| void | segment_x_slices (short *cv, int cx, Boolean axial_slice) |
| void | segment_y_slices (short *cv, int cy, Boolean axial_slice) |
| void | segment_z_slices (short *cv, int cz, Boolean axial_slice) |
| void | segment_envelope (short *cv, int cx, int cy, int cz) |
| void | segment_volume (short *cv) |
| int | connectivity_tests (short *cv) |
Define Documentation
|
|
|
|
|
|
|
|
|
|
|
|
Function Documentation
|
||||||||||||||||
|
Definition at line 163 of file Intracranial.c. References DSET_BRICK_ARRAY, DSET_NX, DSET_NY, DSET_NZ, and nz. Referenced by segment_volume().
00165 {
00166 int nx, ny, nz, nxy, nxyz; /* dataset dimensions in voxels */
00167 int ix, jy, kz, ixyz; /* voxel indices */
00168 short * anat_data = NULL; /* data from anatomical image */
00169 float f, sum, sumx, sumy, sumz; /* sums for calculating means */
00170
00171
00172 /*----- Progress report -----*/
00173 if (! quiet) printf ("\nCalculating center of mass \n");
00174
00175
00176 /*----- Initialize local variables -----*/
00177 anat_data = (short *) DSET_BRICK_ARRAY(anat,0) ;
00178 nx = DSET_NX(anat); ny = DSET_NY(anat); nz = DSET_NZ(anat);
00179 nxy = nx * ny; nxyz = nxy * nz;
00180
00181
00182 /*----- Sum over all voxels -----*/
00183 sum = 0.0; sumx = 0.0; sumy = 0.0; sumz = 0.0;
00184 for (kz = 0; kz < nz; kz++)
00185 for (jy = 0; jy < ny; jy++)
00186 for (ix = 0; ix < nx; ix++)
00187 {
00188 ixyz = ix + jy*nx + kz*nxy;
00189 f = anat_data[ixyz];
00190 sum += f; sumx += ix*f; sumy += jy*f; sumz += kz*f;
00191 }
00192
00193
00194 /*----- Calculate center of mass -----*/
00195 *cx = sumx / sum;
00196 *cy = sumy / sum;
00197 *cz = sumz / sum;
00198
00199 if (! quiet) printf ("Center of mass: ix = %d jy = %d kz = %d \n",
00200 *cx, *cy, *cz);
00201
00202 }
|
|
|
Definition at line 988 of file Intracranial.c. References DSET_NX, DSET_NY, DSET_NZ, free, IJK_TO_THREE, malloc, MTEST, nz, and THREE_TO_IJK. Referenced by SEGMENT_auto().
00990 {
00991 int nx, ny, nz, nxy, nxyz; /* voxel counters */
00992 int ix, jy, kz, ixyz; /* voxel indices */
00993 byte * dv = NULL; /* volume for intermediate data */
00994
00995
00996 /*----- Progress report -----*/
00997 if (! quiet) printf ("\nPerforming voxel connectivity tests \n");
00998
00999
01000 /*----- Initialize local variables -----*/
01001 nx = DSET_NX(anat); ny = DSET_NY(anat); nz = DSET_NZ(anat);
01002 nxy = nx*ny; nxyz = nxy*nz;
01003
01004
01005 /*----- Initialize voxel classification indicators -----*/
01006 dv = (byte *) malloc (nxyz * sizeof(byte));
01007 MTEST (dv); if (dv == NULL) return (0);
01008 for (ixyz = 0; ixyz < nxyz; ixyz++)
01009 dv[ixyz] = 0;
01010
01011
01012 /*----- Determine which voxels will leave the target structure -----*/
01013 if (max_conn_int > -1)
01014 {
01015 for (ixyz = 0; ixyz < nxyz; ixyz++)
01016 {
01017 if (! cv[ixyz])
01018 {
01019 IJK_TO_THREE (ixyz, ix, jy, kz, nx, nxy);
01020 if (ix > 1) dv[THREE_TO_IJK(ix-1,jy,kz,nx,nxy)]++;
01021 if (ix < nx-1) dv[THREE_TO_IJK(ix+1,jy,kz,nx,nxy)]++;
01022 if (jy > 1) dv[THREE_TO_IJK(ix,jy-1,kz,nx,nxy)]++;
01023 if (jy < ny-1) dv[THREE_TO_IJK(ix,jy+1,kz,nx,nxy)]++;
01024 if (kz > 1) dv[THREE_TO_IJK(ix,jy,kz-1,nx,nxy)]++;
01025 if (kz < nz-1) dv[THREE_TO_IJK(ix,jy,kz+1,nx,nxy)]++;
01026 }
01027 }
01028
01029 for (ixyz = 0; ixyz < nxyz; ixyz++)
01030 {
01031 if (dv[ixyz] <= max_conn_int) cv[ixyz] = 1;
01032 dv[ixyz] = 0;
01033 }
01034 }
01035
01036
01037 /*----- Determine which voxels will enter the target structure -----*/
01038 if (min_conn_int < 7)
01039 {
01040 for (ixyz = 0; ixyz < nxyz; ixyz++)
01041 {
01042 if (! cv[ixyz])
01043 {
01044 IJK_TO_THREE (ixyz, ix, jy, kz, nx, nxy);
01045 if (ix > 1) dv[THREE_TO_IJK(ix-1,jy,kz,nx,nxy)]++;
01046 if (ix < nx-1) dv[THREE_TO_IJK(ix+1,jy,kz,nx,nxy)]++;
01047 if (jy > 1) dv[THREE_TO_IJK(ix,jy-1,kz,nx,nxy)]++;
01048 if (jy < ny-1) dv[THREE_TO_IJK(ix,jy+1,kz,nx,nxy)]++;
01049 if (kz > 1) dv[THREE_TO_IJK(ix,jy,kz-1,nx,nxy)]++;
01050 if (kz < nz-1) dv[THREE_TO_IJK(ix,jy,kz+1,nx,nxy)]++;
01051 }
01052 }
01053
01054 for (ixyz = 0; ixyz < nxyz; ixyz++)
01055 if (dv[ixyz] >= min_conn_int) cv[ixyz] = 0;
01056 }
01057
01058
01059 /*----- Deallocate memory -----*/
01060 free (dv); dv = NULL;
01061
01062
01063 return (1);
01064 }
|
|
||||||||||||||||||||||||
|
Definition at line 118 of file Intracranial.c. Referenced by segment_x_slices(), segment_y_slices(), and segment_z_slices().
00119 {
00120 int ii,jj , ip,jp , num ;
00121
00122 #define AR(i,j) ar[(i)+(j)*nx]
00123
00124
00125 /*----- Test for early termination -----*/
00126 if (AR(ix,jy) != 0) return;
00127
00128
00129 /* fill out in cross from 1st point */
00130
00131 ip = ix ; jp = jy ; AR(ip,jp) = 2 ;
00132
00133 for( ii=ip+1; ii < nx && AR(ii,jp) == 0; ii++ ) AR(ii,jp) = 2;
00134 for( ii=ip-1; ii >= 0 && AR(ii,jp) == 0; ii-- ) AR(ii,jp) = 2;
00135 for( jj=jp+1; jj < ny && AR(ip,jj) == 0; jj++ ) AR(ip,jj) = 2;
00136 for( jj=jp-1; jj >= 0 && AR(ip,jj) == 0; jj-- ) AR(ip,jj) = 2;
00137
00138 /* brute force repetition of the cross technique */
00139
00140 do {
00141 num = 0 ;
00142 for( jp=0 ; jp < ny ; jp++ ){
00143 for( ip=0 ; ip < nx ; ip++ ){
00144 if( AR(ip,jp) == 2 ){
00145 for( ii=ip+1; ii < nx && AR(ii,jp) == 0; ii++ ){ AR(ii,jp) = 2; num++; }
00146 for( ii=ip-1; ii >= 0 && AR(ii,jp) == 0; ii-- ){ AR(ii,jp) = 2; num++; }
00147 for( jj=jp+1; jj < ny && AR(ip,jj) == 0; jj++ ){ AR(ip,jj) = 2; num++; }
00148 for( jj=jp-1; jj >= 0 && AR(ip,jj) == 0; jj-- ){ AR(ip,jj) = 2; num++; }
00149 }
00150 }
00151 }
00152 } while( num > 0 ) ;
00153
00154 return ;
00155 }
|
|
||||||||||||||||||||
|
Definition at line 760 of file Intracranial.c. References DSET_NX, DSET_NY, DSET_NZ, free, i, malloc, nr, nz, and r. Referenced by segment_volume().
00765 {
00766 #define MAXLAT 90
00767 #define MAXLNG 180
00768
00769 int nx, ny, nz, nxy, nxz, nyz, nxyz; /* dataset dimensions in voxels */
00770 int ix, jy, kz, ixy, ixz, iyz, ixyz; /* voxel indices */
00771
00772 /* 24 Mar 2004: on Mac OS X, the compiler generates incorrect code
00773 for these large arrays when optimization is turned on;
00774 instead, use malloc() to get them if AIZE is not defined */
00775
00776 #undef AIZE
00777 #ifndef DARWIN
00778 # define AIZE
00779 #endif
00780
00781 #ifdef AIZE
00782 float radius[MAXLAT][MAXLNG]; /* max. radius vector to brain voxel */
00783 float smradius[MAXLAT][MAXLNG]; /* array of smoothed radius vectors */
00784 #else
00785 float **radius , **smradius ;
00786 #endif
00787
00788 int ilat, jlat; /* radius array latitude index */
00789 int ilng, jlng; /* radius array longitude index */
00790 float deltalat, deltalng; /* increments in latitude and longitude */
00791 float lat, clat, slat; /* voxel latitude */
00792 float lng, clng, slng; /* voxel longitude */
00793 int ir, i, j; /* indices */
00794 float rxy; /* radius to voxel in xy-plane */
00795 float r; /* radius to voxel from center of brain */
00796 int nr; /* maximum test radius */
00797 float maxr; /* maximum radius to voxel inside the brain */
00798
00799
00800 /*----- Progress report -----*/
00801 if (! quiet) printf ("\nCreating envelope for segmented image \n");
00802
00803 #ifndef AIZE
00804 radius = (float **) malloc(sizeof(float)*MAXLAT) ;
00805 smradius = (float **) malloc(sizeof(float)*MAXLAT) ;
00806 for (ilat = 0; ilat < MAXLAT; ilat++){
00807 radius[ilat] = (float *)malloc(sizeof(float)*MAXLNG) ;
00808 smradius[ilat] = (float *)malloc(sizeof(float)*MAXLNG) ;
00809 }
00810 #endif
00811
00812
00813 /*----- Initialize local variables -----*/
00814 nx = DSET_NX(anat); ny = DSET_NY(anat); nz = DSET_NZ(anat);
00815 nxy = nx*ny; nxz = nx*nz; nyz = ny*nz; nxyz = nxy*nz;
00816 deltalat = PI / MAXLAT;
00817 deltalng = 2.0 * PI / MAXLNG;
00818 nr = nx;
00819 if (ny > nr) nr = ny;
00820 if (nz > nr) nr = nz;
00821
00822
00823
00824 /*----- Calculate the radius vector -----*/
00825 for (ilat = 0; ilat < MAXLAT; ilat++)
00826 {
00827 lat = ilat * deltalat - PI/2;
00828 slat = sin(lat);
00829 clat = cos(lat);
00830
00831 for (ilng = 0; ilng < MAXLNG; ilng++)
00832 {
00833 lng = ilng * deltalng;
00834 clng = cos(lng);
00835 slng = sin(lng);
00836
00837 radius[ilat][ilng] = 0.0;
00838 for (ir = 0; ir < nr; ir++)
00839 {
00840 ix = cx + ir*clat*clng;
00841 jy = cy + ir*clat*slng;
00842 kz = cz + ir * slat;
00843
00844 if ((ix >= 0) && (ix < nx) && (jy >= 0) && (jy < ny)
00845 && (kz >= 0) && (kz < nz))
00846 {
00847 ixyz = ix + jy*nx + kz*nxy;
00848 if (! cv[ixyz]) radius[ilat][ilng] = (float) ir;
00849 }
00850 }
00851 }
00852 }
00853
00854 /*----- Smooth the radius vectors -----*/
00855 for (ilat = 0; ilat < MAXLAT; ilat++)
00856 {
00857 for (ilng = 0; ilng < MAXLNG; ilng++)
00858 {
00859 smradius[ilat][ilng] = 0.0;
00860
00861 for (i = -1; i <= 1; i++)
00862 {
00863 jlat = (ilat + i + MAXLAT) % MAXLAT;
00864
00865 if (ilat == 0) jlat = 0;
00866 if (ilat == MAXLAT-1) jlat = MAXLAT-1;
00867
00868 for (j = -2; j <= 2; j++)
00869 {
00870 jlng = (ilng + j + MAXLNG) % MAXLNG;
00871 smradius[ilat][ilng] += radius[jlat][jlng] / 15.0;
00872 }
00873 }
00874 }
00875 }
00876
00877 /*----- Find maximum radius to a brain voxel -----*/
00878 maxr = 0.0;
00879 for (ilat = 0; ilat < MAXLAT; ilat++)
00880 for (ilng = 0; ilng < MAXLNG; ilng++)
00881 if (maxr < smradius[ilat][ilng]) maxr = smradius[ilat][ilng];
00882
00883 /*----- Smooth the brain mask -----*/
00884 for (ix = 0; ix < nx; ix++){
00885 for (jy = 0; jy < ny; jy++)
00886 {
00887 rxy = hypot ((float) (ix-cx), (float) (jy-cy));
00888 lng = atan2 (jy-cy, ix-cx);
00889 ilng = (int) ((lng/deltalng) + MAXLNG) % MAXLNG;
00890
00891 for (kz = 0; kz < nz; kz++)
00892 {
00893 ixyz = ix + jy*nx + kz*nxy;
00894
00895 r = hypot (rxy, (float) (kz-cz));
00896
00897 if (r < maxr)
00898 {
00899 lat = atan2 (kz-cz, rxy);
00900 ilat = (int) (((lat+PI/2)/deltalat) + MAXLAT) % MAXLAT;
00901
00902 if (r < smradius[ilat][ilng]) cv[ixyz] = 0;
00903 }
00904
00905 }
00906 }
00907 }
00908
00909 #ifndef AIZE
00910 for (ilat = 0; ilat < MAXLAT; ilat++){
00911 free( radius[ilat]) ; free(smradius[ilat]) ;
00912 }
00913 free(smradius); free(radius);
00914 #endif
00915 }
|
|
|
Definition at line 924 of file Intracranial.c. References center_of_mass(), DSET_NX, DSET_NY, DSET_NZ, segment_envelope(), segment_x_slices(), segment_y_slices(), segment_z_slices(), SI_error(), THD_dataxes::xxorient, THD_dataxes::yyorient, and THD_dataxes::zzorient. Referenced by SEGMENT_auto().
00928 {
00929 THD_dataxes * daxes; /* dataset axes */
00930 char xxorient, yyorient, zzorient; /* dataset axes orientations */
00931 int nxyz; /* dataset dimension in voxels */
00932 int ixyz; /* voxel indices */
00933 int cx, cy, cz; /* location of center of mass */
00934
00935
00936 /*----- Initialize local variables -----*/
00937 daxes = anat->daxes;
00938 xxorient = ORIENT_typestr[daxes->xxorient][0];
00939 yyorient = ORIENT_typestr[daxes->yyorient][0];
00940 zzorient = ORIENT_typestr[daxes->zzorient][0];
00941 nxyz = DSET_NX(anat) * DSET_NY(anat) * DSET_NZ(anat);
00942
00943
00944 /*----- Calculate center of mass of brain image -----*/
00945 center_of_mass (&cx, &cy, &cz);
00946
00947
00948 /*----- Initialize mask for non-brain voxels -----*/
00949 for (ixyz = 0; ixyz < nxyz; ixyz++)
00950 cv[ixyz] = 1;
00951
00952
00953 /*----- Segment the axial slices -----*/
00954 if ((xxorient == 'S') || (xxorient == 'I')) segment_x_slices (cv,cx,1);
00955 else if ((yyorient == 'S') || (yyorient == 'I')) segment_y_slices (cv,cy,1);
00956 else if ((zzorient == 'S') || (zzorient == 'I')) segment_z_slices (cv,cz,1);
00957 else SI_error ("Unable to determine dataset orientation");
00958
00959
00960 /*----- Segment the sagittal slices -----*/
00961 if ((xxorient == 'L') || (xxorient == 'R')) segment_x_slices (cv,cx,0);
00962 else if ((yyorient == 'L') || (yyorient == 'R')) segment_y_slices (cv,cy,0);
00963 else if ((zzorient == 'L') || (zzorient == 'R')) segment_z_slices (cv,cz,0);
00964 else SI_error ("Unable to determine dataset orientation");
00965
00966
00967 /*----- Segment the coronal slices -----*/
00968 if ((xxorient == 'A') || (xxorient == 'P')) segment_x_slices (cv,cx,0);
00969 else if ((yyorient == 'A') || (yyorient == 'P')) segment_y_slices (cv,cy,0);
00970 else if ((zzorient == 'A') || (zzorient == 'P')) segment_z_slices (cv,cz,0);
00971 else SI_error ("Unable to determine dataset orientation");
00972
00973
00974 /*----- Create envelope for segmented image -----*/
00975 if (! nosmooth)
00976 segment_envelope (cv, cx, cy, cz);
00977
00978
00979 return;
00980 }
|
|
||||||||||||||||
|
Definition at line 211 of file Intracranial.c. References draw_2dfiller(), DSET_BRICK_ARRAY, DSET_NX, DSET_NY, DSET_NZ, free, malloc, nz, and rand_uniform(). Referenced by segment_volume().
00217 {
00218 const int MAXNPTS = 1000; /* max. number of random initial test points */
00219 const int MAXFOUND = 10; /* max. number of initial search points */
00220
00221 int nx, ny, nz, nxy, nxz, nyz, nxyz; /* dataset dimensions in voxels */
00222 int ix, jy, kz, ixy, ixz, iyz, ixyz; /* voxel indices */
00223
00224 int m; /* slice index */
00225 short * anat_data = NULL; /* data from anatomical image */
00226 float z; /* voxel gray-scale intensity */
00227 int nmpts, found; /* random search counters */
00228 byte * slice = NULL; /* current slice brain mask */
00229 byte * pslice = NULL; /* previous slice non-brain mask */
00230
00231 int count; /* count of brain voxels in current slice */
00232 int maxcount = 0; /* maximum number of brain voxels in a slice */
00233 float threshold = 0.05; /* stop if count falls below 5% of maximum */
00234
00235
00236 /*----- Progress report -----*/
00237 if (! quiet) printf ("\nSegmenting slices perpendicular to x-axis \n");
00238
00239
00240 /*----- Initialize local variables -----*/
00241 anat_data = (short *) DSET_BRICK_ARRAY(anat,0) ;
00242 nx = DSET_NX(anat); ny = DSET_NY(anat); nz = DSET_NZ(anat);
00243 nxy = nx*ny; nxz = nx*nz; nyz = ny*nz; nxyz = nxy*nz;
00244
00245
00246 /*----- Allocate memory -----*/
00247 slice = (byte *) malloc (nyz * sizeof(byte));
00248 pslice = (byte *) malloc (nyz * sizeof(byte));
00249
00250
00251 /*----- Loop over x-slices -----*/
00252 m = 0;
00253 while (m <= nx)
00254 {
00255 /*----- Start from center slice -----*/
00256 if (m <= cx) ix = cx - m;
00257 else ix = m-1;
00258
00259
00260 /*----- Initialize mask -----*/
00261 if (ix == cx)
00262 {
00263 if (axial_slice)
00264 for (iyz = 0; iyz < nyz; iyz++) pslice[iyz] = 0;
00265 else
00266 {
00267 for (kz = 0; kz < nz; kz++)
00268 for (jy = 0; jy < ny; jy++)
00269 {
00270 iyz = jy + kz*ny;
00271 ixyz = ix + jy*nx + kz*nxy;
00272 if (cv[ixyz]) pslice[iyz] = 2;
00273 else pslice[iyz] = 0;
00274 }
00275 }
00276 }
00277
00278
00279 /*----- Examine each voxel for possible inclusion in brain -----*/
00280 for (kz = 0; kz < nz; kz++)
00281 for (jy = 0; jy < ny; jy++)
00282 {
00283 iyz = jy + kz*ny;
00284 ixyz = ix + jy*nx + kz*nxy;
00285 z = anat_data[ixyz];
00286
00287 if (pslice[iyz] == 2) slice[iyz] = 1;
00288 else if (z < min_val_float) slice[iyz] = 1;
00289 else if (z > max_val_float) slice[iyz] = 1;
00290 else slice[iyz] = 0;
00291 }
00292
00293
00294 /*----- Fill brain voxels from center out -----*/
00295 draw_2dfiller (ny, nz, ny/2, nz/2, slice);
00296
00297
00298 /*----- Use additional random starting points for robustness -----*/
00299 nmpts = 0; found = 0;
00300 while ((nmpts < MAXNPTS) && (found < MAXFOUND))
00301 {
00302 nmpts++;
00303 if ((ix == cx) && axial_slice)
00304 {
00305 jy = (3*ny/8) + (int) (rand_uniform(0.0,1.0) * ny/4);
00306 kz = (3*nz/8) + (int) (rand_uniform(0.0,1.0) * nz/4);
00307 }
00308 else
00309 {
00310 jy = (int) (rand_uniform(0.0,1.0) * ny);
00311 kz = (int) (rand_uniform(0.0,1.0) * nz);
00312 }
00313 if (slice[jy+kz*ny] != 1) found++;
00314 draw_2dfiller (ny, nz, jy, kz, slice);
00315 }
00316
00317
00318 /*----- Filled brain voxels become barriers -----*/
00319 for (iyz = 0; iyz < nyz; iyz++)
00320 if (slice[iyz] == 2) pslice[iyz] = 1;
00321 else pslice[iyz] = 0;
00322
00323
00324 /*----- Now fill non-brain voxels from outside in -----*/
00325 draw_2dfiller (ny, nz, 0, 0, pslice);
00326 draw_2dfiller (ny, nz, ny-1, 0, pslice);
00327 draw_2dfiller (ny, nz, 0, nz-1, pslice);
00328 draw_2dfiller (ny, nz, ny-1, nz-1, pslice);
00329
00330
00331 /*----- Save results for this slice -----*/
00332 count = 0;
00333 for (kz = 0; kz < nz; kz++)
00334 for (jy = 0; jy < ny; jy++)
00335 {
00336 iyz = jy + kz*ny;
00337 ixyz = ix + jy*nx + kz*nxy;
00338 if (pslice[iyz] != 2)
00339 {
00340 cv[ixyz] = 0;
00341 count++;
00342 }
00343 }
00344
00345
00346 /*----- Slightly increase size of brain mask for next slice -----*/
00347 for (kz = 1; kz < nz-1; kz++)
00348 for (jy = 1; jy < ny-1; jy++)
00349 {
00350 iyz = jy + kz*ny;
00351 ixyz = ix + jy*nx + kz*nxy;
00352 if (!cv[ixyz])
00353 {
00354 pslice[iyz] = 0;
00355 pslice[iyz+1] = 0;
00356 pslice[iyz-1] = 0;
00357 pslice[iyz-ny] = 0;
00358 pslice[iyz+ny] = 0;
00359 }
00360 }
00361
00362
00363 /*----- Examine count of brain voxels for this slice -----*/
00364 if (count > maxcount) maxcount = count;
00365 if (count < threshold * maxcount)
00366 {
00367 if (m <= cx) m = cx;
00368 else m = nx;
00369 }
00370
00371
00372 /*----- Increment slice index -----*/
00373 m++;
00374
00375 } /* Loop over x-slices */
00376
00377
00378 /*----- Release memory -----*/
00379 free (pslice); pslice = NULL;
00380 free (slice); slice = NULL;
00381
00382
00383 return;
00384
00385 }
|
|
||||||||||||||||
|
Definition at line 394 of file Intracranial.c. References draw_2dfiller(), DSET_BRICK_ARRAY, DSET_NX, DSET_NY, DSET_NZ, free, malloc, nz, and rand_uniform(). Referenced by segment_volume().
00400 {
00401 const int MAXNPTS = 1000; /* max. number of random initial test points */
00402 const int MAXFOUND = 10; /* max. number of initial search points */
00403
00404 int nx, ny, nz, nxy, nxz, nyz, nxyz; /* dataset dimensions in voxels */
00405 int ix, jy, kz, ixy, ixz, iyz, ixyz; /* voxel indices */
00406
00407 int m; /* slice index */
00408 short * anat_data = NULL; /* data from anatomical image */
00409 float z; /* voxel gray-scale intensity */
00410 int nmpts, found; /* random search counters */
00411 byte * slice = NULL; /* current slice brain mask */
00412 byte * pslice = NULL; /* previous slice non-brain mask */
00413
00414 int count; /* count of brain voxels in current slice */
00415 int maxcount = 0; /* maximum number of brain voxels in a slice */
00416 float threshold = 0.05; /* stop if count falls below 5% of maximum */
00417
00418
00419 /*----- Progress report -----*/
00420 if (! quiet) printf ("\nSegmenting slices perpendicular to y-axis \n");
00421
00422
00423 /*----- Initialize local variables -----*/
00424 anat_data = (short *) DSET_BRICK_ARRAY(anat,0) ;
00425 nx = DSET_NX(anat); ny = DSET_NY(anat); nz = DSET_NZ(anat);
00426 nxy = nx*ny; nxz = nx*nz; nyz = ny*nz; nxyz = nxy*nz;
00427
00428
00429 /*----- Allocate memory -----*/
00430 slice = (byte *) malloc (nxz * sizeof(byte));
00431 pslice = (byte *) malloc (nxz * sizeof(byte));
00432
00433
00434 /*----- Loop over y-slices -----*/
00435 m = 0;
00436 while (m <= ny)
00437 {
00438 /*----- Start from center slice -----*/
00439 if (m <= cy) jy = cy - m;
00440 else jy = m-1;
00441
00442
00443 /*----- Initialize mask -----*/
00444 if (jy == cy)
00445 {
00446 if (axial_slice)
00447 for (ixz = 0; ixz < nxz; ixz++) pslice[ixz] = 0;
00448 else
00449 {
00450 for (kz = 0; kz < nz; kz++)
00451 for (ix = 0; ix < nx; ix++)
00452 {
00453 ixz = ix + kz*nx;
00454 ixyz = ix + jy*nx + kz*nxy;
00455 if (cv[ixyz]) pslice[ixz] = 2;
00456 else pslice[ixz] = 0;
00457 }
00458 }
00459 }
00460
00461
00462 /*----- Examine each voxel for possible inclusion in brain -----*/
00463 for (kz = 0; kz < nz; kz++)
00464 for (ix = 0; ix < nx; ix++)
00465 {
00466 ixz = ix + kz*nx;
00467 ixyz = ix + jy*nx + kz*nxy;
00468 z = anat_data[ixyz];
00469
00470 if (pslice[ixz] == 2) slice[ixz] = 1;
00471 else if (z < min_val_float) slice[ixz] = 1;
00472 else if (z > max_val_float) slice[ixz] = 1;
00473 else slice[ixz] = 0;
00474 }
00475
00476
00477 /*----- Fill brain voxels from center out -----*/
00478 draw_2dfiller (nx, nz, nx/2, nz/2, slice);
00479
00480
00481 /*----- Use additional random starting points for robustness -----*/
00482 nmpts = 0; found = 0;
00483 while ((nmpts < MAXNPTS) && (found < MAXFOUND))
00484 {
00485 nmpts++;
00486 if ((jy == cy) && axial_slice)
00487 {
00488 ix = (3*nx/8) + (int) (rand_uniform(0.0,1.0) * nx/4);
00489 kz = (3*nz/8) + (int) (rand_uniform(0.0,1.0) * nz/4);
00490 }
00491 else
00492 {
00493 ix = (int) (rand_uniform(0.0,1.0) * nx);
00494 kz = (int) (rand_uniform(0.0,1.0) * nz);
00495 }
00496 if (slice[ix+kz*nx] != 1) found++;
00497 draw_2dfiller (nx, nz, ix, kz, slice);
00498 }
00499
00500
00501 /*----- Filled brain voxels become barriers -----*/
00502 for (ixz = 0; ixz < nxz; ixz++)
00503 if (slice[ixz] == 2) pslice[ixz] = 1;
00504 else pslice[ixz] = 0;
00505
00506
00507 /*----- Now fill non-brain voxels from outside in -----*/
00508 draw_2dfiller (nx, nz, 0, 0, pslice);
00509 draw_2dfiller (nx, nz, nx-1, 0, pslice);
00510 draw_2dfiller (nx, nz, 0, nz-1, pslice);
00511 draw_2dfiller (nx, nz, nx-1, nz-1, pslice);
00512
00513
00514 /*----- Save results for this slice -----*/
00515 count = 0;
00516 for (kz = 0; kz < nz; kz++)
00517 for (ix = 0; ix < nx; ix++)
00518 {
00519 ixz = ix + kz*nx;
00520 ixyz = ix + jy*nx + kz*nxy;
00521 if (pslice[ixz] != 2)
00522 {
00523 cv[ixyz] = 0;
00524 count++;
00525 }
00526 }
00527
00528
00529 /*----- Slightly increase size of brain mask for next slice -----*/
00530 for (kz = 1; kz < nz-1; kz++)
00531 for (ix = 1; ix < nx-1; ix++)
00532 {
00533 ixz = ix + kz*nx;
00534 ixyz = ix + jy*nx + kz*nxy;
00535 if (!cv[ixyz])
00536 {
00537 pslice[ixz] = 0;
00538 pslice[ixz+1] = 0;
00539 pslice[ixz-1] = 0;
00540 pslice[ixz-nx] = 0;
00541 pslice[ixz+nx] = 0;
00542 }
00543 }
00544
00545
00546 /*----- Examine count of brain voxels for this slice -----*/
00547 if (count > maxcount) maxcount = count;
00548 if (count < threshold * maxcount)
00549 {
00550 if (m <= cy) m = cy;
00551 else m = ny;
00552 }
00553
00554
00555 /*----- Increment slice index -----*/
00556 m++;
00557
00558 } /* Loop over y-slices */
00559
00560
00561 /*----- Release memory -----*/
00562 free (pslice); pslice = NULL;
00563 free (slice); slice = NULL;
00564
00565
00566 return;
00567
00568 }
|
|
||||||||||||||||
|
Definition at line 577 of file Intracranial.c. References draw_2dfiller(), DSET_BRICK_ARRAY, DSET_NX, DSET_NY, DSET_NZ, free, malloc, nz, and rand_uniform(). Referenced by segment_volume().
00583 {
00584 const int MAXNPTS = 1000; /* max. number of random initial test points */
00585 const int MAXFOUND = 10; /* max. number of initial search points */
00586
00587 int nx, ny, nz, nxy, nxz, nyz, nxyz; /* dataset dimensions in voxels */
00588 int ix, jy, kz, ixy, ixz, iyz, ixyz; /* voxel indices */
00589
00590 int m; /* slice index */
00591 short * anat_data = NULL; /* data from anatomical image */
00592 float z; /* voxel gray-scale intensity */
00593 int nmpts, found; /* random search counters */
00594 byte * slice = NULL; /* current slice brain mask */
00595 byte * pslice = NULL; /* previous slice non-brain mask */
00596
00597 int count; /* count of brain voxels in current slice */
00598 int maxcount = 0; /* maximum number of brain voxels in a slice */
00599 float threshold = 0.05; /* stop if count falls below 5% of maximum */
00600
00601
00602 /*----- Progress report -----*/
00603 if (! quiet) printf ("\nSegmenting slices perpendicular to z-axis \n");
00604
00605
00606 /*----- Initialize local variables -----*/
00607 anat_data = (short *) DSET_BRICK_ARRAY(anat,0) ;
00608 nx = DSET_NX(anat); ny = DSET_NY(anat); nz = DSET_NZ(anat);
00609 nxy = nx*ny; nxz = nx*nz; nyz = ny*nz; nxyz = nxy*nz;
00610
00611
00612 /*----- Allocate memory -----*/
00613 slice = (byte *) malloc (nxy * sizeof(byte));
00614 pslice = (byte *) malloc (nxy * sizeof(byte));
00615
00616
00617 /*----- Loop over z-slices -----*/
00618 m = 0;
00619 while (m <= nz)
00620 {
00621 /*----- Start from center slice -----*/
00622 if (m <= cz) kz = cz - m;
00623 else kz = m-1;
00624
00625
00626 /*----- Initialize mask -----*/
00627 if (kz == cz)
00628 {
00629 if (axial_slice)
00630 for (ixy = 0; ixy < nxy; ixy++) pslice[ixy] = 0;
00631 else
00632 {
00633 for (ix = 0; ix < nx; ix++)
00634 for (jy = 0; jy < ny; jy++)
00635 {
00636 ixy = ix + jy*nx;
00637 ixyz = ix + jy*nx + kz*nxy;
00638 if (cv[ixyz]) pslice[ixy] = 2;
00639 else pslice[ixy] = 0;
00640 }
00641 }
00642 }
00643
00644
00645 /*----- Examine each voxel for possible inclusion in brain -----*/
00646 for (jy = 0; jy < ny; jy++)
00647 for (ix = 0; ix < nx; ix++)
00648 {
00649 ixy = ix + jy*nx;
00650 ixyz = ix + jy*nx + kz*nxy;
00651 z = anat_data[ixyz];
00652
00653 if (pslice[ixy] == 2) slice[ixy] = 1;
00654 else if (z < min_val_float) slice[ixy] = 1;
00655 else if (z > max_val_float) slice[ixy] = 1;
00656 else slice[ixy] = 0;
00657 }
00658
00659
00660 /*----- Fill brain voxels from center out -----*/
00661 draw_2dfiller (nx, ny, nx/2, ny/2, slice);
00662
00663
00664 /*----- Use additional random starting points for robustness -----*/
00665 nmpts = 0; found = 0;
00666 while ((nmpts < MAXNPTS) && (found < MAXFOUND))
00667 {
00668 nmpts++;
00669 if ((kz == cz) && axial_slice)
00670 {
00671 ix = (3*nx/8) + (int) (rand_uniform(0.0,1.0) * nx/4);
00672 jy = (3*ny/8) + (int) (rand_uniform(0.0,1.0) * ny/4);
00673 }
00674 else
00675 {
00676 ix = (int) (rand_uniform(0.0,1.0) * nx);
00677 jy = (int) (rand_uniform(0.0,1.0) * ny);
00678 }
00679 if (slice[ix+jy*nx] != 1) found++;
00680 draw_2dfiller (nx, ny, ix, jy, slice);
00681 }
00682
00683
00684 /*----- Filled brain voxels become barriers -----*/
00685 for (ixy = 0; ixy < nxy; ixy++)
00686 if (slice[ixy] == 2) pslice[ixy] = 1;
00687 else pslice[ixy] = 0;
00688
00689
00690 /*----- Now fill non-brain voxels from outside in -----*/
00691 draw_2dfiller (nx, ny, 0, 0, pslice);
00692 draw_2dfiller (nx, ny, nx-1, 0, pslice);
00693 draw_2dfiller (nx, ny, 0, ny-1, pslice);
00694 draw_2dfiller (nx, ny, nx-1, ny-1, pslice);
00695
00696
00697 /*----- Save results for this slice -----*/
00698 count = 0;
00699 for (jy = 0; jy < ny; jy++)
00700 for (ix = 0; ix < nx; ix++)
00701 {
00702 ixy = ix + jy*nx;
00703 ixyz = ix + jy*nx + kz*nxy;
00704 if (pslice[ixy] != 2)
00705 {
00706 cv[ixyz] = 0;
00707 count++;
00708 }
00709 }
00710
00711
00712 /*----- Slightly increase size of brain mask for next slice -----*/
00713 for (jy = 1; jy < ny-1; jy++)
00714 for (ix = 1; ix < nx-1; ix++)
00715 {
00716 ixy = ix + jy*nx;
00717 ixyz = ix + jy*nx + kz*nxy;
00718 if (!cv[ixyz])
00719 {
00720 pslice[ixy] = 0;
00721 pslice[ixy+1] = 0;
00722 pslice[ixy-1] = 0;
00723 pslice[ixy-nx] = 0;
00724 pslice[ixy+nx] = 0;
00725 }
00726 }
00727
00728
00729 /*----- Examine count of brain voxels for this slice -----*/
00730 if (count > maxcount) maxcount = count;
00731 if (count < threshold * maxcount)
00732 {
00733 if (m <= cz) m = cz;
00734 else m = nz;
00735 }
00736
00737
00738 /*----- Increment slice index -----*/
00739 m++;
00740
00741 } /* Loop over z-slices */
00742
00743
00744 /*----- Release memory -----*/
00745 free (pslice); pslice = NULL;
00746 free (slice); slice = NULL;
00747
00748
00749 return;
00750
00751 }
|
|
|
Definition at line 28 of file Intracranial.c. References check_one_output_file(), DSET_BRICK_TYPE, EQUIV_DATAXES, ISANAT, and SI_error(). Referenced by initialize_program().
00029 {
00030 char message[MAX_STRING_LENGTH]; /* error message */
00031
00032
00033 /*----- Check for required datasets -----*/
00034 if (anat == NULL)
00035 {
00036 sprintf (message, "No anatomical image");
00037 SI_error (message);
00038 return (0);
00039 }
00040 if (! ISANAT(anat))
00041 {
00042 sprintf (message, "Input dataset must be anatomical image");
00043 SI_error (message);
00044 return (0);
00045 }
00046 if (DSET_BRICK_TYPE(anat,0) != MRI_short)
00047 {
00048 sprintf (message, "Anatomical image must have data type: short integer");
00049 SI_error (message);
00050 return (0);
00051 }
00052
00053 #ifdef PLUG_INTRACRANIAL
00054 if (dset == NULL)
00055 {
00056 sprintf (message, "No output dataset");
00057 SI_error (message);
00058 return (0);
00059 }
00060 if (DSET_BRICK_TYPE(dset,0) != MRI_short)
00061 {
00062 sprintf (message, "Output dataset must have data type: short integer");
00063 SI_error (message);
00064 return (0);
00065 }
00066 #else
00067 if (prefix_filename == NULL)
00068 {
00069 sprintf (message, "Must specify output prefix filename");
00070 SI_error (message);
00071 return (0);
00072 }
00073
00074 /*----- Check whether output file already exists -----*/
00075 check_one_output_file (prefix_filename);
00076 #endif
00077
00078
00079 /*----- Check compatibility of datasets -----*/
00080 #ifdef PLUG_INTRACRANIAL
00081 if (! EQUIV_DATAXES (anat->daxes, dset->daxes))
00082 {
00083 sprintf (message,
00084 "Anatomical image and output dataset are incompatible");
00085 SI_error (message);
00086 return (0);
00087 }
00088 #endif
00089
00090
00091 /*----- Check allowed range of intensity values -----*/
00092 if (min_val_float >= max_val_float)
00093 {
00094 sprintf (message, "min_val >= max_val ???");
00095 SI_error (message);
00096 return (0);
00097 }
00098
00099 return (1);
00100
00101 }
|