Beispiel #1
0
static MRI_IMAGE * mri_make_xxt( MRI_IMAGE *fim )
{
   MRI_IMAGE *aim ;
   int nn , mm , n1 ; float *xx ;

                if( fim == NULL || fim->kind != MRI_float ) return NULL ;
   nn = fim->nx ; mm = fim->ny ;    if( nn < mm || mm < 2 ) return NULL ;
   xx = MRI_FLOAT_PTR(fim) ;               if( xx == NULL ) return NULL ;
   n1 = nn-1 ;

   aim = mri_new( mm , mm , MRI_double ) ; asym = MRI_DOUBLE_PTR(aim) ;

   /** setup m x m [A] = [X]'[X] matrix to eigensolve **/

 AFNI_OMP_START ;
#pragma omp parallel if( mm > 7 && nn > 999 )
 { int jj , kk , ii ; register double sum ; register float *xj,*xk ;
#pragma omp for
   for( jj=0 ; jj < mm ; jj++ ){
     xj = xx + jj*nn ;               /* j-th column */
     for( kk=0 ; kk <= jj ; kk++ ){
       sum = 0.0 ; xk = xx + kk*nn ; /* k-th column */
       for( ii=0 ; ii < n1 ; ii+=2 ) sum += xj[ii]*xk[ii] + xj[ii+1]*xk[ii+1];
       if( ii == n1 ) sum += xj[ii]*xk[ii] ;
       A(jj,kk) = sum ; if( kk < jj ) A(kk,jj) = sum ;
     }
   }
 } /* end OpenMP */
 AFNI_OMP_END ;

   return aim ;
}
Beispiel #2
0
MRI_IMAGE * mri_bport_contig( float dt , float fbot , float ftop ,
                              int ntime , int nbefore , int nafter )
{
   MRI_IMAGE *fim ; float *far , *fii , *fip ;
   int nfbot , nftop , ff , ii,jj , nev=(ntime%2==0) , ncol,nrow ;
   float df , freq ;

ENTRY("mri_bport_contig") ;

   if( dt   <= 0.0f ) dt   = 1.0f ;
   if( fbot <  0.0f ) fbot = 0.0f ;
   if( ntime < 9 || ftop < fbot ) RETURN(NULL) ;
   if( nbefore < 0 ) nbefore = 0 ;
   if( nafter  < 0 ) nafter  = 0 ;

   df  = 1.0f / (ntime * dt) ;  /* frequency spacing */

   nfbot = (int)rintf(fbot/df+0.1666666f) ;
   if( nfbot > ntime/2    ) nfbot = ntime/2 ;
   if( nfbot < BP_ffbot   ) nfbot = BP_ffbot ;

   nftop = (int)rintf(ftop/df-0.1666666f) ;
   if( nftop < nfbot   ) nftop = nfbot   ;
   if( nftop > ntime/2 ) nftop = ntime/2 ;
#if 1
   ININFO_message("Frequency indexes: blocklen=%d nfbot=%d nftop=%d",ntime,nfbot,nftop) ;
#endif

   ncol = 2*(nftop-nfbot-1) ; if( ncol < 0 ) ncol = 0 ;
   ncol += (nfbot == 0 || (nfbot == ntime/2 && nev==1) ) ? 1 : 2 ;
   if( nftop > nfbot )
     ncol += (nftop == ntime/2 && nev) ? 1 : 2 ;

   if( ncol <= 0 ){
     ININFO_message("Failure :-(") ; RETURN(NULL) ;  /* should never happen */
   }

   nrow = ntime + nbefore + nafter ;
   fim  = mri_new( nrow , ncol , MRI_float ) ;
   far  = MRI_FLOAT_PTR(fim) ;

   for( ii=0,ff=nfbot ; ff <= nftop ; ff++ ){
     fii = far + (ii*nrow + nbefore) ;
     if( ff == 0 ){
       for( jj=0 ; jj < ntime ; jj++ ) fii[jj] = 1.0f ;
       ii++ ;
     } else if( ff == ntime/2 && nev ){
       for( jj=0 ; jj < ntime ; jj++ ) fii[jj] = 2*(jj%2)-1 ;
       ii++ ;
     } else {
       fip = fii + nrow ; freq = ff*df * (2.0f*3.141593f) * dt ;
       for( jj=0 ; jj < ntime ; jj++ ){
         fii[jj] = cos(freq*jj) ; fip[jj] = sin(freq*jj) ;
       }
       ii += 2 ;
     }
   }

   RETURN(fim) ;
}
Beispiel #3
0
MRI_IMAGE * PH_fakeim( int nx , int ny , int code , float val )
{
   MRI_IMAGE * im ;
   float * far ;
   int ii , nvox ;

   im = mri_new( nx , ny , MRI_float ) ;
   far = MRI_FLOAT_PTR(im) ;
   nvox = im->nvox ;

#if 0
fprintf(stderr,"PH_fakeim: code=%d val=%f\n",code,val) ;
#endif

   switch( code ){

      default:
      case CONST:
         for( ii=0 ; ii < nvox ; ii++ ) far[ii] = val ;
      break ;

      case NOISE:
         for( ii=0 ; ii < nvox ; ii++ ) far[ii] = val * drand48() ;
      break ;
   }

   return im ;
}
Beispiel #4
0
MRI_IMAGE * mri_colorsetup( int ngray , int nrr , int ngg , int nbb )
{
   MRI_IMAGE *im ;
   rgbyte *ar ;
   int rr,gg,bb , nn ;
   float rac,gac,bac ;

   im = mri_new( ngray + nrr*ngg*nbb - 1 , 1 , MRI_rgb ) ;
   ar = (rgbyte *) MRI_RGB_PTR(im) ;

   gac = 255.9f / ngray ; nn = 0 ;          /* actually, ngray+1 levels */
   for( gg=0 ; gg <= ngray ; gg++,nn++ ){
     ar[nn].r = ar[nn].g = ar[nn].b = (byte)(gac*gg) ;
   }

   rac = 255.9f/(nrr-1) ; gac = 255.9f/(ngg-1) ; bac=255.9f/(nbb-1) ;

   for( bb=0 ; bb < nbb ; bb++ ){    /* skip the all black and */
    for( gg=0 ; gg < ngg ; gg++ ){   /* the all white colors   */
      for( rr=0 ; rr < nrr ; rr++ ){
        if( rr==0     && gg==0     && bb==0     ) continue ;
        if( rr==nrr-1 && gg==ngg-1 && bb==nbb-1 ) continue ;
        ar[nn].r = (byte)(rac*rr) ;
        ar[nn].g = (byte)(gac*gg) ;
        ar[nn].b = (byte)(bac*bb) ; nn++ ;
   } } }

   return im ;
}
Beispiel #5
0
MRI_IMAGE * mri_fft2D( MRI_IMAGE * im , int mode )
{
   MRI_IMAGE * cxim , * outim ;
   int nx,ny , nxup,nyup , ii,jj ;
   complex * cxar , * outar , * cpt , * opt ;
   float fac ;

   if( im == NULL ) return NULL ;

   /* convert input to complex */

   cxim = mri_to_complex(im) ;
   cxar = MRI_COMPLEX_PTR(cxim) ;

   /* compute size of output */

   nx = cxim->nx ; nxup = csfft_nextup_even(nx) ;
   ny = cxim->ny ; nyup = csfft_nextup_even(ny) ;

   /* create output array */

   outim = mri_new( nxup , nyup , MRI_complex ) ;
   outar = MRI_COMPLEX_PTR(outim) ;

   /* copy input to output, zero padding along the way */

   opt = outar ;
   cpt = cxar  ;
   for( jj=0 ; jj < ny ; jj++ ){
      for( ii=0 ; ii < nx   ; ii++ ){opt->r=cpt->r; opt->i=cpt->i; opt++; cpt++;}
      for(      ; ii < nxup ; ii++ ){opt->r=opt->i=0.0; opt++;}
   }
   for( ; jj < nyup ; jj++ ){opt->r=opt->i=0.0; opt++;}

   mri_free(cxim) ;

   /* row FFTs */

   for( jj=0 ; jj < ny ; jj++ )
      csfft_cox( mode , nxup , outar+jj*nxup ) ;

   /* column FFTs */

   cxar = (complex *) malloc(sizeof(complex)*nyup) ;

   for( ii=0 ; ii < nxup ; ii++ ){
      for( jj=0 ; jj < nyup ; jj++ ) cxar[jj] = outar[ii+jj*nxup] ;
      csfft_cox( mode , nyup , cxar ) ;
      for( jj=0 ; jj < nyup ; jj++ ) outar[ii+jj*nxup] = cxar[jj] ;
   }

   fac = sqrt(1.0/(nxup*nyup)) ;
   for( ii=0 ; ii < nxup*nyup ; ii++ ){
      outar[ii].r *= fac ; outar[ii].i *= fac ;
   }

   free(cxar) ; return outim ;
}
MRI_IMAGE * mri_genARMA11( int nlen, int nvec, float ap, float lm, float sg )
{
   int kk,ii , do_rcmat ;
   double aa=ap, lam=lm , sig=sg ; int do_norm = (sg<=0.0f) ;
   double *rvec ;
   rcmat *rcm=NULL ;
   MRI_IMAGE *outim ;
   float     *outar , *vv ;
#if 0
   long seed=0 ;
   seed = (long)time(NULL)+(long)getpid() ;
   srand48(seed) ;
#endif

ENTRY("mri_genARMA11") ;

   if( nlen      <= 3    ){ ERROR_message("ARMA11 nlen < 4");    RETURN(NULL); }
   if( fabs(aa)  >= 0.98 ){ ERROR_message("ARMA11 a too big");   RETURN(NULL); }
   if( fabs(lam) >= 0.97 ){ ERROR_message("ARMA11 lam too big"); RETURN(NULL); }

   do_rcmat = ( lam != 0.0 ) ;

   /* setup */

   if( do_rcmat ){
     rcm = rcmat_arma11( nlen , NULL , aa , lam ) ;
     if( rcm == NULL ){
       ERROR_message("Can't setup ARMA11 matrix?!"); RETURN(NULL);
     }
     kk = rcmat_choleski( rcm ) ;
     if( kk > 0 ){
       ERROR_message("ARMA11 Choleski fails at row %d",kk); RETURN(NULL);
     }
   }

   /* simulate */

   outim = mri_new( nlen , nvec , MRI_float ) ; outar = MRI_FLOAT_PTR(outim) ;
   rvec  = (double *)malloc(sizeof(double)*nlen) ;

   for( kk=0 ; kk < nvec ; kk++ ){
     for( ii=0 ; ii < nlen ; ii++ ) rvec[ii] = zgaussian() ;
     if( do_rcmat ) rcmat_lowert_vecmul( rcm , rvec ) ;
     vv = outar + kk*nlen ;
     if( do_norm ){
       sig = 0.0 ;
       for( ii=0 ; ii < nlen ; ii++ ) sig += rvec[ii]*rvec[ii] ;
       sig = 1.0 / sqrt(sig) ;
     }
     if( sig != 1.0 ){ for( ii=0 ; ii < nlen ; ii++ ) vv[ii] = sig * rvec[ii]; }
   }

   free(rvec) ;
   if( do_rcmat ) rcmat_destroy(rcm) ;

   RETURN(outim) ;
}
MRI_IMAGE * CORMAT_fetch(void)
{
   MRI_IMAGE *cim ; float *car ; int ii ;
   if( maxlag <= 0 || cor == NULL ) return NULL ;
   cim = mri_new(maxlag,1,MRI_float) ; car = MRI_FLOAT_PTR(cim) ;
   for( ii=0 ; ii < maxlag ; ii++ )
     if( ncor[ii] > 0 ) car[ii] = cor[ii] / ncor[ii] ;
   return cim ;
}
Beispiel #8
0
MRI_IMARR * LSS_mangle_matrix( MRI_IMAGE *ima, int jbot, int jtop )
{
   int ii , jj , jnew , jn , njj , nn,mm ;
   MRI_IMAGE *imb , *imc ; MRI_IMARR *imar ;
   float *aa , *bb , *cc , *acol , *bcol , *ccol ;

ENTRY("LSS_mangle_matrix") ;

   if( ima == NULL || ima->kind != MRI_float ) RETURN(NULL) ;
   nn = ima->nx ; mm = ima->ny ;
   njj = jtop-jbot+1 ; if( njj <= 1 )          RETURN(NULL) ;
   if( jbot < 0 || jtop >= mm )                RETURN(NULL) ;

   imb = mri_new( nn , mm-njj+1 , MRI_float ) ;  /* matrix without jbot..jtop */
   imc = mri_new( nn , njj      , MRI_float ) ;  /* matrix with jbot..jtop */
   aa  = MRI_FLOAT_PTR(ima) ;
   bb  = MRI_FLOAT_PTR(imb) ;
   cc  = MRI_FLOAT_PTR(imc) ;

   /* copy non-excised columns into the new imb */

   for( jn=jj=0 ; jj < mm ; jj++ ){
     if( jj >= jbot && jj <= jtop ) continue ;
     acol = aa + jj*nn ;        /* jj = old column index */
     bcol = bb + jn*nn ; jn++ ; /* jn = new column index */
     for( ii=0 ; ii < nn ; ii++ ) bcol[ii] = acol[ii] ;
   }

   /* copy excised columns into the new imc,
      and also add them up into the last column of imb */

   bcol = bb + (mm-njj)*nn ;  /* last col of imb */
   for( jn=0,jj=jbot ; jj <= jtop ; jj++ ){
     acol = aa + jj*nn ;
     ccol = cc + jn*nn ; jn++ ;
     for( ii=0 ; ii < nn ; ii++ ){
       ccol[ii] = acol[ii] ; bcol[ii] += acol[ii] ;
     }
   }

   INIT_IMARR(imar) ; ADDTO_IMARR(imar,imb) ; ADDTO_IMARR(imar,imc) ; RETURN(imar) ;
}
Beispiel #9
0
/* Implementation Note: Some of the calculations in the loops can be
   factored out, but I choose not to for clarity. This is all O(N) in the
   number of timepoints anyways (I think).
*/
MRI_IMAGE * RIC_ToCardiacPhase(MRI_IMAGE * card, float threshold) {

    int numSamps;            /* Number of samples in vector */
    MRI_IMAGE * cardphase;   /* The cardiac phase vector to return */
    float * cpdata;          /* Pointer to cardiac phase vector data */
    float * cdata;           /* Pointer to cardiac vector data */
    double twoPI = 2 * M_PI; /* 2 * PI  (intermediate value for calculation) */
    double twoPI_t2_t1;      /* 2 * PI / (t_2 - t_1)  (intermediate value) */
    double phase;            /* card phase: 2 * PI / (t_2 - t_1) * (t - t_1) */
    int lastpeakpt = 0;      /* The last cdata timepoint searched for a peak */
    int t = 0;               /* The current time */
    int t_1 = 0;             /* The previous cardiac peak time */
    int t_2;                 /* The next cardiac peak time */

    /* Quick check of arguments */
    if (card == NULL || card->nx < 2 || card->kind != MRI_float) {
	return NULL;
    }

    /* Initialize */
    numSamps = card->nx;
    cardphase = mri_new(numSamps, 1, MRI_float);
    cpdata = MRI_FLOAT_PTR(cardphase);
    cdata = MRI_FLOAT_PTR(card);

    /* Iterate over the cardiac peaks, assuming data start is peak */
    while (_RIC_findNextCardiacPeak(cdata, numSamps, lastpeakpt, &t_2,
				    &lastpeakpt, threshold) == 0) {

	/* Fill in the cardiac phase values between peaks */
	twoPI_t2_t1 = twoPI / (t_2 - t_1);
	phase = 0.0;  /* Since we always have t == t_1 at this point) */
	for ( ; t < t_2; t += 1) {
	    cpdata[t] = phase;
	    phase += twoPI_t2_t1;
	}

	t_1 = t_2;
    }

    /* Fill in any remaining phase values, assuming end of data is peak */
    twoPI_t2_t1 = twoPI / (numSamps - t_1);
    phase = 0.0;
    for ( ; t < numSamps; t += 1) {
	cpdata[t] = phase;
	phase += twoPI_t2_t1;
    }

    return cardphase;
}
Beispiel #10
0
int main( int argc , char * argv[] )
{
    MRI_IMAGE * imbar , * imsdev , * imwt ;
    int ii , nvox , nsum ;
    float * bar , * sdev , * wt ;
    float bmax , smax , bcut , scl , bsum ;
    float hist[11] ;

    if( argc < 4 ){
      printf("Usage: %s mean_image sdev_image wt_image\n",argv[0]) ;
      exit(0) ;
    }

    imbar  = mri_read_just_one( argv[1] ) ; if( imbar == NULL ) exit(1) ;
    imsdev = mri_read_just_one( argv[2] ) ; if( imsdev== NULL ) exit(1) ;

    if( imbar->kind != MRI_float ){
      imwt = mri_to_float(imbar) ; mri_free(imbar) ; imbar = imwt ;
    }

    if( imsdev->kind != MRI_float ){
      imwt = mri_to_float(imsdev) ; mri_free(imsdev) ; imsdev = imwt ;
    }

    nvox = imbar->nvox ;
    imwt = mri_new( imbar->nx , imbar->ny , MRI_float ) ;

    bar  = MRI_FLOAT_PTR(imbar) ;
    sdev = MRI_FLOAT_PTR(imsdev) ;
    wt   = MRI_FLOAT_PTR(imwt) ;

    bcut = 0.05 * mri_maxabs(imbar) ; bsum = 0.0 ; nsum = 0 ;
    for( ii=0 ; ii < nvox ; ii++ ){
      if( bar[ii] > bcut ){ bsum += bar[ii] ; nsum++ ; }
    }
    bcut = 0.25 * bsum / nsum ;

    smax = mri_maxabs(imsdev) ; scl  = 0.25 * bcut*bcut ;

    printf("cutoff value = %f\n",bcut) ;

    for( ii=0 ; ii < nvox ; ii++ ){
      if( bar[ii] < bcut || sdev[ii] <= 0.0 ) wt[ii] = 0.0 ;
      else                                    wt[ii] = scl / SQR(sdev[ii]) ;
    }

    mri_write( argv[3] , imwt ) ;
    exit(0) ;
}
Beispiel #11
0
MRI_IMAGE * DES_get_psinv( int ntim , int nref , float **ref )
{
   MRI_IMAGE *refim , *psinv ; float *refar , *jar ; int ii , jj ;

   refim = mri_new(ntim,nref,MRI_float) ;
   refar = MRI_FLOAT_PTR(refim) ;
   for( jj=0 ; jj < nref ; jj++ ){
     jar = refar + jj*ntim ;
     for( ii=0 ; ii < ntim ; ii++ ) jar[ii] = ref[jj][ii] ;
   }
   mri_matrix_psinv_svd(1) ;
   psinv = mri_matrix_psinv(refim,NULL,0.0f) ;
   mri_free(refim) ;
   return psinv ;
}
Beispiel #12
0
MRI_IMAGE * THD_dset_to_1Dmri( THD_3dim_dataset *dset )
{
   MRI_IMAGE *im ; float *far ;
   int nx , ny , ii ;

ENTRY("THD_dset_to_1D") ;

   if( !ISVALID_DSET(dset) ) RETURN(NULL) ;
   DSET_load(dset) ;
   if( !DSET_LOADED(dset) ) RETURN(NULL) ;

   nx = DSET_NVALS(dset) ;
   ny = DSET_NVOX(dset) ;
   im = mri_new( nx , ny , MRI_float ) ; far = MRI_FLOAT_PTR(im) ;

   for( ii=0 ; ii < ny ; ii++ )
     THD_extract_array( ii , dset , 0 , far + ii*nx ) ;

   RETURN(im) ;
}
Beispiel #13
0
MRI_IMAGE * mri_make_rainbow( int nx , int ny , int ncol , rgbyte *col )
{
   MRI_IMAGE *bim ; byte *bar ; int ii,jj , pp ; float qq,rr ;

   if( ncol < 2 || col == NULL ) return NULL ;
   if( nx < 1      ) nx = 8 ;
   if( ny < 2*ncol ) ny = 2*ncol ;

   bim = mri_new(nx,ny,MRI_rgb) ; bar = MRI_RGB_PTR(bim) ;

   for( jj=0 ; jj < ny ; jj++ ){
     qq = jj*(ncol-1.001f)/(ny-1.0f) ; pp = (int)qq ;
     qq = qq-pp ; rr = 1.0f-qq ;
     for( ii=0 ; ii < nx ; ii++ ){
       bar[3*(ii+jj*nx)+0] = (byte)( rr*col[pp].r + qq*col[pp+1].r ) ;
       bar[3*(ii+jj*nx)+1] = (byte)( rr*col[pp].g + qq*col[pp+1].g ) ;
       bar[3*(ii+jj*nx)+2] = (byte)( rr*col[pp].b + qq*col[pp+1].b ) ;
     }
   }
   return bim ;
}
Beispiel #14
0
MRI_IMAGE * mri_transpose_byte( MRI_IMAGE * im )
{
   MRI_IMAGE * om ;
   byte * iar , * oar ;
   int ii,jj,nx,ny ;

ENTRY("mri_transpose_byte") ;

   if( im == NULL || im->kind != MRI_byte ) RETURN(NULL) ;

   nx  = im->nx ; ny = im->ny ;
   om  = mri_new( ny , nx , MRI_byte ) ;
   iar = MRI_BYTE_PTR(im) ;
   oar = MRI_BYTE_PTR(om) ;

   for( jj=0 ; jj < ny ; jj++ )
      for( ii=0 ; ii < nx ; ii++ )
         oar[jj+ii*ny] = iar[ii+jj*nx] ;

   MRI_COPY_AUX(om,im) ;
   RETURN(om) ;
}
Beispiel #15
0
MRI_IMAGE * mri_jointhist( MRI_IMAGE *imp , MRI_IMAGE *imq , byte *mmm )
{
   int nvox , nmmm=0 ;
   float *rst ;
   byte *par, *qar ;
   float fac ;
   register int ii,jj,kk ;
   MRI_IMAGE *imqq, *impp , *imh ;

   if( imp == NULL || imq == NULL || imp->nvox != imq->nvox ) return NULL;

   nvox = imp->nvox ;

   impp = (imp->kind==MRI_byte) ? imp : mri_to_byte(imp) ;
   imqq = (imq->kind==MRI_byte) ? imq : mri_to_byte(imq) ;
   par  = MRI_BYTE_PTR(impp) ;
   qar  = MRI_BYTE_PTR(imqq) ;
   imh  = mri_new( 256,256,MRI_float ) ;
   rst  = MRI_FLOAT_PTR(imh) ;

   if( mmm != NULL ){
     for( kk=0 ; kk < nvox ; kk++ ) if( mmm[kk] ) nmmm++ ;
     fac = 1.0f / nmmm ;
     for( kk=0 ; kk < nvox ; kk++ ){
       if( mmm[kk] == 0 ) continue ;
       ii = par[kk] ; jj = qar[kk] ; rst[ii+256*jj] += fac ;
     }
   } else {
     fac = 1.0f / nvox ;
     for( kk=0 ; kk < nvox ; kk++ ){
       ii = par[kk] ; jj = qar[kk] ; rst[ii+256*jj] += fac ;
     }
   }

   if( impp != imp ) mri_free(impp) ;
   if( imqq != imq ) mri_free(imqq) ;

   return imh ;
}
Beispiel #16
0
MRI_IMAGE * THD_extract_series( int ind , THD_3dim_dataset *dset , int raw )
{
   int nv , typ , ii ;
   MRI_IMAGE *im ;
   void *imar ;

ENTRY("THD_extract_series") ;

   if( !ISVALID_DSET(dset) ) RETURN(NULL) ;

   nv  = dset->dblk->nvals ;
   if( raw ) typ = DSET_BRICK_TYPE(dset,0) ;  /* type of output array */
   else      typ = MRI_float ;

   im   = mri_new( nv , 1 , typ ) ;           /* output image */
   imar = mri_data_pointer(im) ;

   ii = THD_extract_array( ind , dset , raw , imar ) ; /* get data */

   if( ii != 0 ){ mri_free(im) ; RETURN(NULL) ; }      /* bad */

   if( dset->taxis != NULL ){  /* 21 Oct 1996 */
      float zz , tt ;
      int kz = ind / ( dset->daxes->nxx * dset->daxes->nyy ) ;

      zz = dset->daxes->zzorg + kz * dset->daxes->zzdel ;
      tt = THD_timeof( 0 , zz , dset->taxis ) ;

      im->xo = tt ; im->dx = dset->taxis->ttdel ;   /* origin and delta */

      if( dset->taxis->units_type == UNITS_MSEC_TYPE ){ /* convert to sec */
         im->xo *= 0.001 ; im->dx *= 0.001 ;
      }
   } else {
      im->xo = 0.0 ; im->dx = 1.0 ;  /* 08 Nov 1996 */
   }

   RETURN(im) ;
}
Beispiel #17
0
static MRI_IMAGE * mri_dup2D_rgb_NN( MRI_IMAGE *inim, int nup )
{
   rgbyte *bin , *bout , *bin1 ;
   MRI_IMAGE *outim ;
   int ii,jj,kk,ll , nx,ny , nxup,nyup ;

ENTRY("mri_dup2D_rgb_NN") ;
   if( inim == NULL || inim->kind != MRI_rgb ) RETURN(NULL);

   bin = (rgbyte *) MRI_RGB_PTR(inim); if( bin == NULL ) RETURN(NULL);

   /* make output image **/

   nx = inim->nx ; ny = inim->ny ; nxup = nup*nx ; nyup = nup*ny ;
   outim = mri_new( nxup , nyup , MRI_rgb ) ;
   bout  = (rgbyte *) MRI_RGB_PTR(outim) ;

   for( jj=0 ; jj < ny ; jj++ ){   /* loop over input rows */
     
     for ( kk= 0; kk < nup; kk++ ) { /* do rows nup times */

       bin1 = bin;

       for( ii=0 ; ii < nx ; ii++ ){

         for ( ll= 0; ll < nup; ll++ ) {
	     *bout++ = *bin1;
         }

         bin1++;
       }

     }
     bin += nx ;
   }

   MRI_COPY_AUX(outim,inim) ;
   RETURN(outim) ;
}
Beispiel #18
0
MRI_IMAGE * mri_extract_from_mask( MRI_IMAGE *imin , byte *mask , int invert )
{
   byte bmmm = (invert == 0) ? 1 : 0 ;
   int ii,jj , ngood , nvox ;
   float *iar , *oar ;
   MRI_IMAGE *outim ;

ENTRY("mri_extract_mask") ;

   if( imin == NULL || mask == NULL ) RETURN(NULL) ;  /* bad user == luser */

   /*-- not float?  create a float image and recurse! --*/

   if( imin->kind != MRI_float ){
     MRI_IMAGE *qim = mri_to_float(imin) ;
     outim = mri_extract_from_mask( qim , mask , invert ) ;
     mri_free(qim) ;
     RETURN(outim) ;
   }

   /*-- count up the good voxels --*/

   nvox = imin->nvox ;
   for( ngood=ii=0 ; ii < nvox ; ii++ ) if( GOOD(ii) ) ngood++ ;
   if( ngood == 0 ) RETURN(NULL) ;

   /*-- create the output --*/

   outim = mri_new( ngood , 1 , MRI_float ) ;
   oar   = MRI_FLOAT_PTR(outim) ;
   iar   = MRI_FLOAT_PTR(imin) ;

   /*-- fill the output --*/

   for( jj=ii=0 ; ii < nvox ; ii++ ) if( GOOD(ii) ) oar[jj++] = iar[ii] ;

   RETURN(outim) ;
}
Beispiel #19
0
static MRI_IMAGE * mri_warp3D_align_fitim( MRI_warp3D_align_basis *bas ,
                                           MRI_IMAGE *cim ,
                                           int warp_mode , float delfac )
{
   MRI_IMAGE *fitim , *pim , *mim ;
   float *fitar , *car=MRI_FLOAT_PTR(cim) ;
   int nfree=bas->nfree , *ima=MRI_INT_PTR(bas->imap) , nmap=bas->imap->nx ;
   int npar =bas->nparam ;
   float *pvec , *par , *mar ;
   int ii , pp , cc ;
   float dpar , delta ;

   /*-- create image containing basis columns --*/

   fitim = mri_new( nmap , nfree+1 , MRI_float ) ;
   fitar = MRI_FLOAT_PTR(fitim) ;
   pvec  = (float *)malloc(sizeof(float) * npar) ;

#undef  FMAT
#define FMAT(i,j) fitar[(i)+(j)*nmap]  /* col dim=nmap, row dim=nfree+1 */

   /* column #nfree = base image itself */

   for( ii=0 ; ii < nmap ; ii++ ) FMAT(ii,nfree) = car[ima[ii]] ;

   pvec = (float *)malloc(sizeof(float) * npar) ;

   /* for each free parameter:
       apply inverse transform to base image with param value up and down
       compute central difference to approximate derivative of base
        image wrt parameter
       store as a column in the fitim matrix */

   mri_warp3D_method( warp_mode ) ;  /* set interpolation mode */
   mri_warp3D_set_womask( bas->imsk ) ;

   for( pp=0,cc=0 ; pp < npar ; pp++ ){

     if( bas->param[pp].fixed ) continue ;  /* don't do this one! */

     /* init all params to their identity transform value */

     for( ii=0 ; ii < npar ; ii++ )
       pvec[ii] = (bas->param[ii].fixed) ? bas->param[ii].val_fixed
                                         : bas->param[ii].ident ;

     /* change in the pp-th parameter to use for derivative */

     dpar = delfac * bas->param[pp].delta ;

     if( bas->verb )
       fprintf(stderr,"+   difference base by %f in param#%d [%s]\n",
               dpar , pp+1 , bas->param[pp].name ) ;

     pvec[pp] = bas->param[pp].ident + dpar ;   /* set positive change */
     bas->vwset( npar , pvec ) ;                 /* put into transform */
     pim = mri_warp3D( cim , 0,0,0 , bas->vwinv ) ;      /* warp image */

     pvec[pp] = bas->param[pp].ident - dpar ;   /* set negative change */
     bas->vwset( npar , pvec ) ;
     mim = mri_warp3D( cim , 0,0,0 , bas->vwinv ) ;

     /* compute derivative */

     delta = bas->scale_init / ( 2.0f * dpar ) ;
     par = MRI_FLOAT_PTR(pim) ; mar = MRI_FLOAT_PTR(mim) ;
     for( ii=0 ; ii < nmap ; ii++ )
       FMAT(ii,cc) = delta * ( par[ima[ii]] - mar[ima[ii]] ) ;

#if 0
{ float psum=0.0f,msum=0.0f,dsum=0.0f;
  for( ii=0 ; ii < nmap ; ii++ ){
    psum += fabsf(par[ima[ii]]) ;
    msum += fabsf(mar[ima[ii]]) ;
    dsum += fabsf(FMAT(ii,cc)) ;
  }
  fprintf(stderr,"  pp=%d  psum=%g  msum=%g  dsum=%g\n",pp,psum,msum,dsum) ;
}
#endif

     mri_free(pim) ; mri_free(mim) ;  /* no longer needed */

     cc++ ;  /* oopsie */
   }

   mri_warp3D_set_womask( NULL ) ;
   free((void *)pvec) ;

#if 0
{ int zz , jj ;
  for( jj=0 ; jj <= nfree ; jj++ ){
    zz = 0 ;
    for( ii=0 ; ii < nmap ; ii++ ) if( FMAT(ii,jj) == 0.0 ) zz++ ;
    fprintf(stderr,"  fitim: col#%d has %d zeros out of %d\n",jj,zz,nmap) ;
  }
}
#endif

   return(fitim) ;
}
Beispiel #20
0
static MRI_IMAGE * mri_psinv( MRI_IMAGE *imc , float *wt )
{
   float *rmat=MRI_FLOAT_PTR(imc) ;
   int m=imc->nx , n=imc->ny , ii,jj,kk ;
   double *amat , *umat , *vmat , *sval , *xfac , smax,del,ww ;
   MRI_IMAGE *imp ; float *pmat ;
   register double sum ;
   int do_svd=0 ;

   amat = (double *)calloc( sizeof(double),m*n ) ;  /* input matrix */
   xfac = (double *)calloc( sizeof(double),n   ) ;  /* column norms of [a] */

#define R(i,j) rmat[(i)+(j)*m]   /* i=0..m-1 , j=0..n-1 */
#define A(i,j) amat[(i)+(j)*m]   /* i=0..m-1 , j=0..n-1 */
#define P(i,j) pmat[(i)+(j)*n]   /* i=0..n-1 , j=0..m-1 */

   /* copy input matrix (float) into amat (double) */

   for( ii=0 ; ii < m ; ii++ )
     for( jj=0 ; jj < n ; jj++ ) A(ii,jj) = R(ii,jj) ;

   /* weight rows? */

   if( wt != NULL ){
     for( ii=0 ; ii < m ; ii++ ){
       ww = wt[ii] ;
       if( ww > 0.0 ) for( jj=0 ; jj < n ; jj++ ) A(ii,jj) *= ww ;
     }
   }

   /* scale each column to have norm 1 */

   for( jj=0 ; jj < n ; jj++ ){
     sum = 0.0 ;
     for( ii=0 ; ii < m ; ii++ ) sum += A(ii,jj)*A(ii,jj) ;
     if( sum > 0.0 ) sum = 1.0/sqrt(sum) ;
     else           { do_svd = 1 ; ERROR_message("mri_psinv[%d]=0\n",jj);}
     xfac[jj] = sum ;
     for( ii=0 ; ii < m ; ii++ ) A(ii,jj) *= sum ;
   }

   /*** compute using Choleski or SVD ***/

   if( do_svd || AFNI_yesenv("AFNI_WARPDRIVE_SVD") ){ /***--- SVD method ---***/

#define U(i,j) umat[(i)+(j)*m]
#define V(i,j) vmat[(i)+(j)*n]

     umat = (double *)calloc( sizeof(double),m*n ); /* left singular vectors */
     vmat = (double *)calloc( sizeof(double),n*n ); /* right singular vectors */
     sval = (double *)calloc( sizeof(double),n   ); /* singular values */

     /* compute SVD of scaled matrix */

     svd_double( m , n , amat , sval , umat , vmat ) ;

     free((void *)amat) ;  /* done with this */

     /* find largest singular value */

     smax = sval[0] ;
     for( ii=1 ; ii < n ; ii++ ) if( sval[ii] > smax ) smax = sval[ii] ;

     if( smax <= 0.0 ){                        /* this is bad */
       ERROR_message("SVD fails in mri_warp3D_align_setup!\n");
       free((void *)xfac); free((void *)sval);
       free((void *)vmat); free((void *)umat); return NULL;
     }

     for( ii=0 ; ii < n ; ii++ )
       if( sval[ii] < 0.0 ) sval[ii] = 0.0 ;  /* should not happen */

#define PSINV_EPS 1.e-8

     /* "reciprocals" of singular values:  1/s is actually s/(s^2+del) */

     del = PSINV_EPS * smax*smax ;
     for( ii=0 ; ii < n ; ii++ )
       sval[ii] = sval[ii] / ( sval[ii]*sval[ii] + del ) ;

     /* create pseudo-inverse */

     imp  = mri_new( n , m , MRI_float ) ;   /* recall that m > n */
     pmat = MRI_FLOAT_PTR(imp) ;

     for( ii=0 ; ii < n ; ii++ ){
       for( jj=0 ; jj < m ; jj++ ){
         sum = 0.0 ;
         for( kk=0 ; kk < n ; kk++ ) sum += sval[kk] * V(ii,kk) * U(jj,kk) ;
         P(ii,jj) = (float)sum ;
       }
     }
     free((void *)sval); free((void *)vmat); free((void *)umat);

   } else { /***----- Choleski method -----***/

     vmat = (double *)calloc( sizeof(double),n*n ); /* normal matrix */

     for( ii=0 ; ii < n ; ii++ ){
       for( jj=0 ; jj <= ii ; jj++ ){
         sum = 0.0 ;
         for( kk=0 ; kk < m ; kk++ ) sum += A(kk,ii) * A(kk,jj) ;
         V(ii,jj) = sum ;
       }
       V(ii,ii) += PSINV_EPS ;   /* note V(ii,ii)==1 before this */
     }

     /* Choleski factor */

     for( ii=0 ; ii < n ; ii++ ){
       for( jj=0 ; jj < ii ; jj++ ){
         sum = V(ii,jj) ;
         for( kk=0 ; kk < jj ; kk++ ) sum -= V(ii,kk) * V(jj,kk) ;
         V(ii,jj) = sum / V(jj,jj) ;
       }
       sum = V(ii,ii) ;
       for( kk=0 ; kk < ii ; kk++ ) sum -= V(ii,kk) * V(ii,kk) ;
       if( sum <= 0.0 ){
         ERROR_message("Choleski fails in mri_warp3D_align_setup!\n");
         free((void *)xfac); free((void *)amat); free((void *)vmat); return NULL ;
       }
       V(ii,ii) = sqrt(sum) ;
     }

     /* create pseudo-inverse */

     imp  = mri_new( n , m , MRI_float ) ;   /* recall that m > n */
     pmat = MRI_FLOAT_PTR(imp) ;

     sval = (double *)calloc( sizeof(double),n ) ; /* row #jj of A */

     for( jj=0 ; jj < m ; jj++ ){
       for( ii=0 ; ii < n ; ii++ ) sval[ii] = A(jj,ii) ; /* extract row */

       for( ii=0 ; ii < n ; ii++ ){  /* forward solve */
         sum = sval[ii] ;
         for( kk=0 ; kk < ii ; kk++ ) sum -= V(ii,kk) * sval[kk] ;
         sval[ii] = sum / V(ii,ii) ;
       }
       for( ii=n-1 ; ii >= 0 ; ii-- ){  /* backward solve */
         sum = sval[ii] ;
         for( kk=ii+1 ; kk < n ; kk++ ) sum -= V(kk,ii) * sval[kk] ;
         sval[ii] = sum / V(ii,ii) ;
       }

       for( ii=0 ; ii < n ; ii++ ) P(ii,jj) = (float)sval[ii] ;
     }
     free((void *)amat); free((void *)vmat); free((void *)sval);
   }

   /* rescale rows from norming */

   for( ii=0 ; ii < n ; ii++ ){
     for( jj=0 ; jj < m ; jj++ ) P(ii,jj) *= xfac[ii] ;
   }
   free((void *)xfac);

   /* rescale cols for weight? */

   if( wt != NULL ){
     for( ii=0 ; ii < m ; ii++ ){
       ww = wt[ii] ;
       if( ww > 0.0 ) for( jj=0 ; jj < n ; jj++ ) P(jj,ii) *= ww ;
     }
   }

   return imp;
}
Beispiel #21
0
int main( int argc , char * argv[] )
{
   int lin , kim , kbot,ktop , nx,ny , npix , ii ,
       lbase , lup,ldown ;
   MRI_IMAGE ** stat_ret ;
   MRI_IMAGE * imb=NULL ;
   float     * bar , * bav ;

   printf(
    "MCW SFIM: Stepwise Functional IMages, by RW Cox\n") ;

   if( argc < 2 ) SFIM_syntax("type sfim -help for usage details") ;
   else if( strcmp(argv[1],"-help") == 0 ) SFIM_syntax(NULL) ;

   machdep() ;

   SFIM_getopts( argc , argv ) ;

   /*----- average over each interval -----*/

   nx = SF_imts->imarr[0]->nx ;
   ny = SF_imts->imarr[0]->ny ; npix = nx * ny ;

   lin = 0 ; kbot = 0 ;
   do {
      ktop = kbot + SF_int[lin].count ;
      if( ktop > SF_imts->num ) ktop = SF_imts->num ;

      if( isalpha(SF_int[lin].name[0]) ){     /* average if a good name */
         for( kim=kbot ; kim < ktop ; kim++ )
           (void) mri_stat_seq( SF_imts->imarr[kim] ) ;

         stat_ret         = mri_stat_seq( NULL ) ;
         SF_int[lin].avim = stat_ret[0] ;
         SF_int[lin].sdim = stat_ret[1] ;
      }

      kbot = ktop ; lin ++ ;
   } while( SF_int[lin].count > 0 && kbot < SF_imts->num ) ;
   SF_numint = lin ;

   /*----- find the number of base intervals -----*/

   lbase = 0 ;
   for( lin=0 ; lin < SF_numint ; lin++ )
      if( strcmp(SF_int[lin].name,SF_bname) == 0 ) lbase++ ;

   /* no bases --> write averages out now and quit */

   if( lbase <= 0 ){
      printf("** no 'base' intervals --> task means not adjusted\n") ;
      SFIM_write_avs() ;
      exit(0) ;
   }

   /* bases yes, but not localbase --> compute global average of bases */

   if( ! SF_localbase ){
      int knum = 0 ;

      kbot = 0 ;
      for( lin=0 ; lin < SF_numint ; lin++ ){
         ktop = kbot + SF_int[lin].count ;
         if( ktop > SF_imts->num ) ktop = SF_imts->num ;
         if( strcmp(SF_int[lin].name,SF_bname) == 0 ){  /* if a base */
            for( kim=kbot ; kim < ktop ; kim++ ){
               (void) mri_stat_seq( SF_imts->imarr[kim] ) ; /* average in */
               knum ++ ;
            }
         }
         kbot = ktop ;
      }
      stat_ret = mri_stat_seq( NULL ) ;
      imb      = stat_ret[0] ;           /* average of all bases */
      mri_free( stat_ret[1] ) ;          /* don't keep st. dev.  */

      printf("** global base = average of %d images\n",knum) ;
   }

   /*----- for each non-base interval,
           subtract the relevant base average -----*/

   for( lin=0 ; lin < SF_numint ; lin++ ){
      int free_imb = 0 ;

      if( !isalpha(SF_int[lin].name[0]) ||
          strcmp(SF_int[lin].name,SF_bname) == 0 ) continue ;  /* skip this */

      if( SF_localbase ){
         for( lup=lin+1 ; lup < SF_numint ; lup++ )  /* look for a base above */
            if( strcmp(SF_int[lup].name,SF_bname) == 0 ) break ;

         for( ldown=lin-1 ; ldown >=0 ; ldown-- )    /* look for a base below */
            if( strcmp(SF_int[ldown].name,SF_bname) == 0 ) break ;

         if( ldown < 0 && lup >= SF_numint ){  /* no base?  an error! */
            fprintf(stderr,"*** can't find base above or below at lin=%d\n",lin) ;
            SFIM_syntax("INTERNAL ERROR -- should not occur!") ;
         }

         /* if only have one neighbor, use it, otherwise make average */

         if( ldown <  0         ){
            imb = SF_int[lup].avim ; free_imb = 0 ;
            printf("** local base for %s = average of %d images above\n",
                   SF_int[lin].name , SF_int[lup].count ) ;
         }
         else if( lup   >= SF_numint ){
            imb = SF_int[ldown].avim ; free_imb = 0 ;
            printf("** local base for %s = average of %d images below\n",
                   SF_int[lin].name , SF_int[ldown].count ) ;
         }
         else {
            float * bup , * bdown ;
            bup   = mri_data_pointer( SF_int[lup].avim ) ;
            bdown = mri_data_pointer( SF_int[ldown].avim ) ;
            imb   = mri_new( nx , ny , MRI_float ) ; free_imb = 1 ;
            bar   = mri_data_pointer( imb ) ;
            for( ii=0 ; ii < npix ; ii++ )
               bar[ii] = 0.5 * ( bup[ii] + bdown[ii] ) ;

            printf("** local base for %s = average of %d below, %d above\n",
                   SF_int[lin].name, SF_int[ldown].count, SF_int[lup].count ) ;
         }
      }

      /* subtract imb (base average) from current interval average */

      bar = mri_data_pointer( imb ) ;
      bav = mri_data_pointer( SF_int[lin].avim ) ;
      for( ii=0 ; ii < npix ; ii++ ) bav[ii] -= bar[ii] ;

      if( SF_localbase && free_imb ) mri_free( imb ) ;
   }

   /*----- now write the averages out -----*/

   SFIM_write_avs() ;
   exit(0) ;
}
Beispiel #22
0
int main( int argc , char * argv[] )
{
   int iarg , pos = 0 ;
   float thresh=0.0 ;
   MRI_IMAGE * maskim=NULL , *imin , *imout ;
   float * maskar ;
   int nxim , nyim , ii , npix ;

   if( argc < 3 || strncmp(argv[1],"-help",4) == 0 ){
      printf("Usage: immask [-thresh #] [-mask mask_image] [-pos] input_image output_image\n"
             "* Masks the input_image and produces the output_image;\n"
             "* Use of -thresh # means all pixels with absolute value below # in\n"
             "   input_image will be set to zero in the output_image\n"
             "* Use of -mask mask_image means that only locations that are nonzero\n"
             "   in the mask_image will be nonzero in the output_image\n"
             "* Use of -pos means only positive pixels from input_image will be used\n"
             "* At least one of -thresh, -mask, -pos must be used; more than one is OK.\n"
            ) ;
     exit(0) ;
   }

   machdep() ;

   iarg = 1 ;
   while( iarg < argc && argv[iarg][0] == '-' ){

      /*** -pos ***/

      if( strncmp(argv[iarg],"-pos",4) == 0 ){
         pos = 1 ;
         iarg++ ; continue ;
      }

      /*** -thresh # ***/

      if( strncmp(argv[iarg],"-thresh",5) == 0 ){
         thresh = strtod( argv[++iarg] , NULL ) ;
         if( iarg >= argc || thresh <= 0.0 ){
            fprintf(stderr,"Illegal -thresh!\a\n") ; exit(1) ;
         }
         iarg++ ; continue ;
      }

      if( strncmp(argv[iarg],"-mask",5) == 0 ){
         maskim = mri_read_just_one( argv[++iarg] ) ;
         if( maskim == NULL || iarg >= argc || ! MRI_IS_2D(maskim) ){
            fprintf(stderr,"Illegal -mask!\a\n") ; exit(1) ;
         }
         if( maskim->kind != MRI_float ){
            imin = mri_to_float( maskim ) ;
            mri_free( maskim ) ;
            maskim = imin ;
         }
         iarg++ ; continue ;
      }

      fprintf(stderr,"** Illegal option: %s\a\n",argv[iarg]) ;
      exit(1) ;
   }
   if( thresh <= 0.0 && maskim == NULL && pos == 0 ){
      fprintf(stderr,"No -thresh, -mask, -pos ==> can't go on!\a\n") ; exit(1) ;
   }
   if( iarg+1 >= argc ){
      fprintf(stderr,"Must have input_image and output_image on command line!\a\n") ;
      exit(1) ;
   }

   imin = mri_read_just_one( argv[iarg++] ) ;
   if( imin == NULL ) exit(1) ;
   if( ! MRI_IS_2D(imin) ){
      fprintf(stderr,"can only process 2D images!\a\n") ;
      exit(1) ;
   }

   nxim = imin->nx ;
   nyim = imin->ny ;
   npix = nxim * nyim ;

   if( maskim == NULL ){
      maskim = mri_new( nxim , nyim , MRI_float ) ;
      maskar = MRI_FLOAT_PTR(maskim) ;
      for( ii=0 ; ii < npix ; ii++ ) maskar[ii] = 1.0 ;
   } else if( maskim->nx != nxim || maskim->ny != nyim ){
      fprintf(stderr,"Mask and input image not same size!\a\n") ;
      exit(1) ;
   } else {
      maskar = MRI_FLOAT_PTR(maskim) ;
   }
   imout = mri_new( nxim , nyim , imin->kind ) ;

   switch( imin->kind ){

      default:
         fprintf(stderr,"Unrecognized input image type!\a\n") ;
         exit(1) ;

      case MRI_byte:{
         byte * arin , * arout , val ;
         arin  = mri_data_pointer(imin) ;
         arout = mri_data_pointer(imout) ;
         for( ii=0 ; ii < npix ; ii++ ){
            val = arin[ii] ;
            if( maskar[ii] != 0.0 && ABS(val) >= thresh ) arout[ii] = val ;
            else                                          arout[ii] = 0 ;
         }
      } break ;

      case MRI_short:{
         short * arin , * arout , val ;
         arin  = mri_data_pointer(imin) ;
         arout = mri_data_pointer(imout) ;
         for( ii=0 ; ii < npix ; ii++ ){
            val = arin[ii] ;
            if( maskar[ii] != 0.0 && ABS(val) >= thresh ) arout[ii] = val ;
            else                                          arout[ii] = 0 ;
         }
         if( pos ) for( ii=0 ; ii < npix ; ii++ ) if( arout[ii] < 0 ) arout[ii] = 0 ;
      } break ;

      case MRI_float:{
         float * arin , * arout , val ;
         arin  = mri_data_pointer(imin) ;
         arout = mri_data_pointer(imout) ;
         for( ii=0 ; ii < npix ; ii++ ){
            val = arin[ii] ;
            if( maskar[ii] != 0.0 && ABS(val) >= thresh ) arout[ii] = val ;
            else                                          arout[ii] = 0 ;
         }
         if( pos ) for( ii=0 ; ii < npix ; ii++ ) if( arout[ii] < 0 ) arout[ii] = 0 ;
      } break ;

      case MRI_int:{
         int * arin , * arout , val ;
         arin  = mri_data_pointer(imin) ;
         arout = mri_data_pointer(imout) ;
         for( ii=0 ; ii < npix ; ii++ ){
            val = arin[ii] ;
            if( maskar[ii] != 0.0 && ABS(val) >= thresh ) arout[ii] = val ;
            else                                          arout[ii] = 0 ;
         }
         if( pos ) for( ii=0 ; ii < npix ; ii++ ) if( arout[ii] < 0 ) arout[ii] = 0 ;
      } break ;

      case MRI_double:{
         double * arin , * arout , val ;
         arin  = mri_data_pointer(imin) ;
         arout = mri_data_pointer(imout) ;
         for( ii=0 ; ii < npix ; ii++ ){
            val = arin[ii] ;
            if( maskar[ii] != 0.0 && ABS(val) >= thresh ) arout[ii] = val ;
            else                                          arout[ii] = 0 ;
         }
         if( pos ) for( ii=0 ; ii < npix ; ii++ ) if( arout[ii] < 0 ) arout[ii] = 0 ;
      } break ;

      case MRI_complex:{
         complex * arin , * arout , val ;
         arin  = mri_data_pointer(imin) ;
         arout = mri_data_pointer(imout) ;
         for( ii=0 ; ii < npix ; ii++ ){
            val = arin[ii] ;
            if( maskar[ii] != 0.0 && CABS(val) >= thresh ) arout[ii] = val ;
            else                                           arout[ii] = CMPLX(0,0) ;
         }
      } break ;
   }

   mri_write( argv[iarg] , imout ) ;
   exit(0) ;
}
int main( int argc , char *argv[] )
{
   THD_3dim_dataset *inset=NULL , *outset=NULL ;
   MCW_cluster *nbhd=NULL ;
   byte *mask=NULL ; int mask_nx,mask_ny,mask_nz , automask=0 ;
   char *prefix="./LocalCormat" ;
   int iarg=1 , verb=1 , ntype=0 , kk,nx,ny,nz,nxy,nxyz,nt , xx,yy,zz, vstep ;
   float na,nb,nc , dx,dy,dz ;
   MRI_IMARR *imar=NULL ; MRI_IMAGE *pim=NULL ;
   int mmlag=10 , ii,jj , do_arma=0 , nvout ;
   MRI_IMAGE *concim=NULL ; float *concar=NULL ;

   if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
     printf(
       "Usage: 3dLocalCORMAT [options] inputdataset\n"
       "\n"
       "Compute the correlation matrix (in time) of the input dataset,\n"
       "up to lag given by -maxlag.  The matrix is averaged over the\n"
       "neighborhood specified by the -nbhd option, and then the entries\n"
       "are output at each voxel in a new dataset.\n"
       "\n"
       "Normally, the input to this program would be the -errts output\n"
       "from 3dDeconvolve, or the equivalent residuals from some other\n"
       "analysis.  If you input a non-residual time series file, you at\n"
       "least should use an appropriate -polort level for detrending!\n"
       "\n"
       "Options:\n"
       "  -input inputdataset\n"
       "  -prefix ppp\n"
       "  -mask mset    {these 2 options are}\n"
       "  -automask     {mutually exclusive.}\n"
       "  -nbhd nnn     [e.g., 'SPHERE(9)' for 9 mm radius]\n"
       "  -polort ppp   [default = 0, which is reasonable for -errts output]\n"
       "  -concat ccc   [as in 3dDeconvolve]\n"
       "  -maxlag mmm   [default = 10]\n"
       "  -ARMA         [estimate ARMA(1,1) parameters into last 2 sub-bricks]\n"
       "\n"
       "A quick hack for my own benignant purposes -- RWCox -- June 2008\n"
     ) ;
     PRINT_COMPILE_DATE ; exit(0) ;
   }

   /*---- official startup ---*/

   PRINT_VERSION("3dLocalCormat"); mainENTRY("3dLocalCormat main"); machdep();
   AFNI_logger("3dLocalCormat",argc,argv); AUTHOR("Zhark the Toeplitzer");

   /*---- loop over options ----*/

   while( iarg < argc && argv[iarg][0] == '-' ){

#if 0
fprintf(stderr,"argv[%d] = %s\n",iarg,argv[iarg]) ;
#endif

     if( strcmp(argv[iarg],"-ARMA") == 0 ){
       do_arma = 1 ; iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-polort") == 0 ){
       char *cpt ;
       if( ++iarg >= argc )
         ERROR_exit("Need argument after option %s",argv[iarg-1]) ;
       pport = (int)strtod(argv[iarg],&cpt) ;
       if( *cpt != '\0' )
         WARNING_message("Illegal non-numeric value after -polort") ;
       if( pport > 3 ){
         pport = 3 ; WARNING_message("-polort set to 3 == max implemented") ;
       } else if( pport < 0 ){
         pport = 0 ; WARNING_message("-polort set to 0 == min implemented") ;
       }
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-input") == 0 ){
       if( inset != NULL  ) ERROR_exit("Can't have two -input options") ;
       if( ++iarg >= argc ) ERROR_exit("Need argument after '-input'") ;
       inset = THD_open_dataset( argv[iarg] ) ;
       CHECK_OPEN_ERROR(inset,argv[iarg]) ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-prefix") == 0 ){
       if( ++iarg >= argc ) ERROR_exit("Need argument after '-prefix'") ;
       prefix = strdup(argv[iarg]) ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-mask") == 0 ){
       THD_3dim_dataset *mset ; int mmm ;
       if( ++iarg >= argc ) ERROR_exit("Need argument after '-mask'") ;
       if( mask != NULL || automask ) ERROR_exit("Can't have two mask inputs") ;
       mset = THD_open_dataset( argv[iarg] ) ;
       CHECK_OPEN_ERROR(mset,argv[iarg]) ;
       DSET_load(mset) ; CHECK_LOAD_ERROR(mset) ;
       mask_nx = DSET_NX(mset); mask_ny = DSET_NY(mset); mask_nz = DSET_NZ(mset);
       mask = THD_makemask( mset , 0 , 0.5f, 0.0f ) ; DSET_delete(mset) ;
       if( mask == NULL ) ERROR_exit("Can't make mask from dataset '%s'",argv[iarg]) ;
       mmm = THD_countmask( mask_nx*mask_ny*mask_nz , mask ) ;
       INFO_message("Number of voxels in mask = %d",mmm) ;
       if( mmm < 2 ) ERROR_exit("Mask is too small to process") ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-automask") == 0 ){
       if( mask != NULL ) ERROR_exit("Can't have -automask and -mask") ;
       automask = 1 ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-nbhd") == 0 ){
       char *cpt ;
       if( ntype  >  0    ) ERROR_exit("Can't have 2 '-nbhd' options") ;
       if( ++iarg >= argc ) ERROR_exit("Need argument after '-nbhd'") ;

       cpt = argv[iarg] ;
       if( strncasecmp(cpt,"SPHERE",6) == 0 ){
         sscanf( cpt+7 , "%f" , &na ) ;
         if( na == 0.0f ) ERROR_exit("Can't have a SPHERE of radius 0") ;
         ntype = NTYPE_SPHERE ;
       } else if( strncasecmp(cpt,"RECT",4) == 0 ){
         sscanf( cpt+5 , "%f,%f,%f" , &na,&nb,&nc ) ;
         if( na == 0.0f && nb == 0.0f && nc == 0.0f )
           ERROR_exit("'RECT(0,0,0)' is not a legal neighborhood") ;
         ntype = NTYPE_RECT ;
       } else if( strncasecmp(cpt,"RHDD",4) == 0 ){
         sscanf( cpt+5 , "%f" , &na ) ;
         if( na == 0.0f ) ERROR_exit("Can't have a RHDD of radius 0") ;
         ntype = NTYPE_RHDD ;
       } else {
          ERROR_exit("Unknown -nbhd shape: '%s'",cpt) ;
       }
       iarg++ ; continue ;
     }
       
     if( strcmp(argv[iarg],"-maxlag") == 0 ){
       if( ++iarg >= argc )
         ERROR_exit("Need argument after option %s",argv[iarg-1]) ;
       mmlag = (int)strtod(argv[iarg],NULL) ;
       iarg++ ; continue ;
     }   

     if( strcmp(argv[iarg],"-concat") == 0 ){
       if( concim != NULL )
         ERROR_exit("Can't have two %s options!",argv[iarg]) ;
       if( ++iarg >= argc )
         ERROR_exit("Need argument after option %s",argv[iarg-1]) ;
       concim = mri_read_1D( argv[iarg] ) ;
       if( concim == NULL )
         ERROR_exit("Can't read -concat file '%s'",argv[iarg]) ;
       if( concim->nx < 2 )
         ERROR_exit("-concat file '%s' must have at least 2 entries!",
                    argv[iarg]) ;
       concar = MRI_FLOAT_PTR(concim) ;
       for( ii=1 ; ii < concim->nx ; ii++ )
         if( (int)concar[ii-1] >= (int)concar[ii] )
           ERROR_exit("-concat file '%s' is not ordered increasingly!",
                      argv[iarg]) ;
       iarg++ ; continue ;
     }

     ERROR_exit("Unknown option '%s'",argv[iarg]) ;

   } /*--- end of loop over options ---*/

   if( do_arma && mmlag > 0 && mmlag < 5 )
     ERROR_exit("Can't do -ARMA with -maxlag %d",mmlag) ;

   /*---- deal with input dataset ----*/

   if( inset == NULL ){
     if( iarg >= argc ) ERROR_exit("No input dataset on command line?") ;
     inset = THD_open_dataset( argv[iarg] ) ;
     CHECK_OPEN_ERROR(inset,argv[iarg]) ;
   }
   ntime = DSET_NVALS(inset) ;
   if( ntime < 9 )
     ERROR_exit("Must have at least 9 values per voxel") ;

   DSET_load(inset) ; CHECK_LOAD_ERROR(inset) ;

   if( mask != NULL ){
     if( mask_nx != DSET_NX(inset) ||
         mask_ny != DSET_NY(inset) ||
         mask_nz != DSET_NZ(inset)   )
       ERROR_exit("-mask dataset grid doesn't match input dataset") ;

   } else if( automask ){
     int mmm ;
     mask = THD_automask( inset ) ;
     if( mask == NULL )
       ERROR_message("Can't create -automask from input dataset?") ;
     mmm = THD_countmask( DSET_NVOX(inset) , mask ) ;
     INFO_message("Number of voxels in automask = %d",mmm) ;
     if( mmm < 2 ) ERROR_exit("Automask is too small to process") ;
   }

   /*-- set up blocks of continuous time data --*/
       
   if( DSET_IS_TCAT(inset) ){
     if( concim != NULL ){
       WARNING_message("Ignoring -concat, since dataset is auto-catenated") ;
       mri_free(concim) ;
     }
     concim = mri_new(inset->tcat_num,1,MRI_float) ;
     concar = MRI_FLOAT_PTR(concim) ;
     concar[0] = 0.0 ;
     for( ii=0 ; ii < inset->tcat_num-1 ; ii++ )
       concar[ii+1] = concar[ii] + inset->tcat_len[ii] ;
   } else if( concim == NULL ){ 
     concim = mri_new(1,1,MRI_float) ;
     concar = MRI_FLOAT_PTR(concim)  ; concar[0] = 0 ;
   }
   nbk = concim->nx ;
   bk  = (int *)malloc(sizeof(int)*(nbk+1)) ;
   for( ii=0 ; ii < nbk ; ii++ ) bk[ii] = (int)concar[ii] ;
   bk[nbk] = ntime ;
   mri_free(concim) ;
   mlag = DSET_NVALS(inset) ;
   for( ii=0 ; ii < nbk ; ii++ ){
     jj = bk[ii+1]-bk[ii] ; if( jj < mlag ) mlag = jj ;
     if( bk[ii] < 0 || jj < 9 )
       ERROR_exit("something is rotten in the dataset run lengths") ;
   }
   mlag-- ;
   if( mmlag > 0 && mlag > mmlag ) mlag = mmlag ;
   else                            INFO_message("Max lag set to %d",mlag) ;

   if( do_arma && mlag < 5 )
     ERROR_exit("Can't do -ARMA with maxlag=%d",mlag) ;

   /*---- create neighborhood (as a cluster) -----*/

   if( ntype <= 0 ){         /* default neighborhood */
     ntype = NTYPE_SPHERE ; na = -1.01f ;
     INFO_message("Using default neighborhood = self + 6 neighbors") ;
   }

   switch( ntype ){
     default:
       ERROR_exit("WTF?  ntype=%d",ntype) ;

     case NTYPE_SPHERE:{
       if( na < 0.0f ){ dx = dy = dz = 1.0f ; na = -na ; }
       else           { dx = fabsf(DSET_DX(inset)) ;
                        dy = fabsf(DSET_DY(inset)) ;
                        dz = fabsf(DSET_DZ(inset)) ; }
       nbhd = MCW_spheremask( dx,dy,dz , na ) ;
     }
     break ;

     case NTYPE_RECT:{
       if( na < 0.0f ){ dx = 1.0f; na = -na; } else dx = fabsf(DSET_DX(inset));
       if( nb < 0.0f ){ dy = 1.0f; nb = -nb; } else dy = fabsf(DSET_DY(inset));
       if( nc < 0.0f ){ dz = 1.0f; nc = -nc; } else dz = fabsf(DSET_DZ(inset));
       nbhd = MCW_rectmask( dx,dy,dz , na,nb,nc ) ;
     }
     break ;

     case NTYPE_RHDD:{
       if( na < 0.0f ){ dx = dy = dz = 1.0f ; na = -na ; }
       else           { dx = fabsf(DSET_DX(inset)) ;
                        dy = fabsf(DSET_DY(inset)) ;
                        dz = fabsf(DSET_DZ(inset)) ; }
       nbhd = MCW_rhddmask( dx,dy,dz , na ) ;
     }
     break ;
   }
   MCW_radsort_cluster( nbhd , dx,dy,dz ) ;  /* 26 Feb 2008 */

   INFO_message("Neighborhood comprises %d voxels",nbhd->num_pt) ;

   /** create output dataset **/

   outset = EDIT_empty_copy(inset) ;
   nvout  = mlag ; if( do_arma ) nvout += 2 ;
   EDIT_dset_items( outset,
                      ADN_prefix   , prefix,
                      ADN_brick_fac, NULL  ,
                      ADN_nvals    , nvout ,
                      ADN_ntt      , nvout ,
                    ADN_none );
   tross_Copy_History( inset , outset ) ;
   tross_Make_History( "3dLocalCormat" , argc,argv , outset ) ;
   for( kk=0 ; kk < nvout ; kk++ )
     EDIT_substitute_brick( outset , kk , MRI_float , NULL ) ;

   nx = DSET_NX(outset) ;
   ny = DSET_NY(outset) ; nxy  = nx*ny  ;
   nz = DSET_NZ(outset) ; nxyz = nxy*nz ;
   vstep = (verb && nxyz > 999) ? nxyz/50 : 0 ;
   if( vstep ) fprintf(stderr,"++ voxel loop: ") ;

   /** actually do the long long slog through all voxels **/

   for( kk=0 ; kk < nxyz ; kk++ ){
     if( vstep && kk%vstep==vstep-1 ) vstep_print() ;
     if( !INMASK(kk) ) continue ;
     IJK_TO_THREE( kk , xx,yy,zz , nx,nxy ) ;
     imar = THD_get_dset_nbhd_array( inset , mask , xx,yy,zz , nbhd ) ;
     if( imar == NULL ) continue ;
     pim = mri_cormat_vector(imar) ; DESTROY_IMARR(imar) ;
     if( pim == NULL ) continue ;
     THD_insert_series( kk, outset, pim->nx, MRI_float, MRI_FLOAT_PTR(pim), 0 ) ;

     if( do_arma ){  /* estimate ARMA(1,1) params and store those, too */
       float_pair ab ;
       float *aa=DSET_ARRAY(outset,mlag), *bb=DSET_ARRAY(outset,mlag+1) ;
       ab = estimate_arma11( pim->nx , MRI_FLOAT_PTR(pim) ) ;
       aa[kk] = ab.a ; bb[kk] = ab.b ;
     }

     mri_free(pim) ;
   }
   if( vstep ) fprintf(stderr,"\n") ;

   DSET_delete(inset) ;
   DSET_write(outset) ;
   WROTE_DSET(outset) ;

   exit(0) ;
}
Beispiel #24
0
MRI_IMAGE *mri_rota( MRI_IMAGE *im, float aa, float bb, float phi )
{
   float rot_dx , rot_dy , rot_cph , rot_sph , top,bot,val ;
   MRI_IMAGE *imfl , *newImg ;
   MRI_IMARR *impair ;
   float *far , *nar ;
   float xx,yy , fx,fy ;
   int ii,jj, nx,ny , ix,jy , ifx,jfy ;
   float f_jm1,f_j00,f_jp1,f_jp2 , wt_m1,wt_00,wt_p1,wt_p2 ;

#ifdef USE_CGRID
   if( p_first ){
      p_first = 0 ;
      xx      = 1.0 / CGRID ;
      for( ii=0 ; ii <= CGRID ; ii++ ){
         yy       = ii * xx ;
         p_m1[ii] = P_M1(yy) ;
         p_00[ii] = P_00(yy) ;
         p_p1[ii] = P_P1(yy) ;
         p_p2[ii] = P_P2(yy) ;
      }
   }
#endif

   if( im == NULL || ! MRI_IS_2D(im) ){
      fprintf(stderr,"*** mri_rota only works on 2D images!\n") ; EXIT(1) ;
   }

   /** if complex image, break into pairs, do each separately, put back together **/

   if( im->kind == MRI_complex ){
      MRI_IMARR *impair ;
      MRI_IMAGE * rim , * iim , * tim ;
      impair = mri_complex_to_pair( im ) ;
      if( impair == NULL ){
         fprintf(stderr,"*** mri_complex_to_pair fails in mri_rota!\n") ; EXIT(1) ;
      }
      rim = IMAGE_IN_IMARR(impair,0) ;
      iim = IMAGE_IN_IMARR(impair,1) ;  FREE_IMARR(impair) ;
      tim = mri_rota( rim , aa,bb,phi ) ; mri_free( rim ) ; rim = tim ;
      tim = mri_rota( iim , aa,bb,phi ) ; mri_free( iim ) ; iim = tim ;
      newImg = mri_pair_to_complex( rim , iim ) ;
      mri_free( rim ) ; mri_free( iim ) ;
      MRI_COPY_AUX(newImg,im) ;
      return newImg ;
   }

   /** rotation params **/

   rot_cph = cos(phi) ; rot_sph = sin(phi) ;

   rot_dx  = (0.5 * im->nx) * (1.0-rot_cph) - aa*rot_cph - bb*rot_sph
            -(0.5 * im->ny) * rot_sph ;

   rot_dy  = (0.5 * im->nx) * rot_sph + aa*rot_sph - bb*rot_cph
            +(0.5 * im->ny) * (1.0-rot_cph) ;

   /** other initialization **/

   nx = im->nx ;  /* image dimensions */
   ny = im->ny ;

   if( im->kind == MRI_float ) imfl = im ;
   else                        imfl = mri_to_float( im ) ;

   far = MRI_FLOAT_PTR(imfl) ;              /* access to float data */
   newImg = mri_new( nx , nx , MRI_float ) ;   /* output image */
   nar = MRI_FLOAT_PTR(newImg) ;               /* output image data */

   bot = top = far[0] ;
   for( ii=0 ; ii < nx*ny ; ii++ )
           if( far[ii] < bot ) bot = far[ii] ;
      else if( far[ii] > top ) top = far[ii] ;

   /*** loop over output points and warp to them ***/

   for( jj=0 ; jj < nx ; jj++ ){
      xx = rot_sph * jj + rot_dx - rot_cph ;
      yy = rot_cph * jj + rot_dy + rot_sph ;
      for( ii=0 ; ii < nx ; ii++ ){

         xx += rot_cph ;  /* get x,y in original image */
         yy -= rot_sph ;

         ix = (xx >= 0.0) ? ((int) xx) : ((int) xx)-1 ;  /* floor */
         jy = (yy >= 0.0) ? ((int) yy) : ((int) yy)-1 ;

#ifdef USE_CGRID
         ifx   = (xx-ix)*CGRID + 0.499 ;
         wt_m1 = p_m1[ifx] ; wt_00 = p_00[ifx] ;
         wt_p1 = p_p1[ifx] ; wt_p2 = p_p2[ifx] ;
#else
         fx    = xx-ix ;
         wt_m1 = P_M1(fx) ; wt_00 = P_00(fx) ;
         wt_p1 = P_P1(fx) ; wt_p2 = P_P2(fx) ;
#endif

         if( ix > 0 && ix < nx-2 && jy > 0 && jy < ny-2 ){
            float * fym1, *fy00 , *fyp1 , *fyp2 ;

            fym1 = far + (ix-1 + (jy-1)*nx) ;
            fy00 = fym1 + nx ;
            fyp1 = fy00 + nx ;
            fyp2 = fyp1 + nx ;

            f_jm1 =  wt_m1 * fym1[0] + wt_00 * fym1[1]
                   + wt_p1 * fym1[2] + wt_p2 * fym1[3] ;

            f_j00 =  wt_m1 * fy00[0] + wt_00 * fy00[1]
                   + wt_p1 * fy00[2] + wt_p2 * fy00[3] ;

            f_jp1 =  wt_m1 * fyp1[0] + wt_00 * fyp1[1]
                   + wt_p1 * fyp1[2] + wt_p2 * fyp1[3] ;

            f_jp2 =  wt_m1 * fyp2[0] + wt_00 * fyp2[1]
                   + wt_p1 * fyp2[2] + wt_p2 * fyp2[3] ;

         } else {

            f_jm1 =  wt_m1 * FINS(ix-1,jy-1)
                   + wt_00 * FINS(ix  ,jy-1)
                   + wt_p1 * FINS(ix+1,jy-1)
                   + wt_p2 * FINS(ix+2,jy-1) ;

            f_j00 =   wt_m1 * FINS(ix-1,jy)
                    + wt_00 * FINS(ix  ,jy)
                    + wt_p1 * FINS(ix+1,jy)
                    + wt_p2 * FINS(ix+2,jy) ;

            f_jp1 =   wt_m1 * FINS(ix-1,jy+1)
                    + wt_00 * FINS(ix  ,jy+1)
                    + wt_p1 * FINS(ix+1,jy+1)
                    + wt_p2 * FINS(ix+2,jy+1) ;

            f_jp2 =   wt_m1 * FINS(ix-1,jy+2)
                    + wt_00 * FINS(ix  ,jy+2)
                    + wt_p1 * FINS(ix+1,jy+2)
                    + wt_p2 * FINS(ix+2,jy+2) ;
         }

#define THIRTYSIX 2.7777778e-2  /* 1./36.0, actually */

#ifdef USE_CGRID
         jfy = (yy-jy)*CGRID + 0.499 ;
         val = (  p_m1[jfy] * f_jm1 + p_00[jfy] * f_j00
                + p_p1[jfy] * f_jp1 + p_p2[jfy] * f_jp2 ) * THIRTYSIX ;
#else
         fy  = yy-jy ;
         val = (  P_M1(fy) * f_jm1 + P_00(fy) * f_j00
                + P_P1(fy) * f_jp1 + P_P2(fy) * f_jp2 ) * THIRTYSIX ;
#endif

              if( val < bot ) nar[ii+jj*nx] = bot ;  /* too small! */
         else if( val > top ) nar[ii+jj*nx] = top ;  /* too big!   */
         else                 nar[ii+jj*nx] = val ;  /* just right */

      }
   }

   /*** cleanup and return ***/

   if( im != imfl ) mri_free(imfl) ;  /* throw away unneeded workspace */
   MRI_COPY_AUX(newImg,im) ;
   return newImg ;
}
Beispiel #25
0
MRI_IMAGE *mri_rota_bilinear( MRI_IMAGE *im, float aa, float bb, float phi )
{
   float rot_dx , rot_dy , rot_cph , rot_sph ;
   MRI_IMAGE *imfl , *newImg ;
   MRI_IMARR *impair ;
   float *far , *nar ;
   float xx,yy , fx,fy ;
   int ii,jj, nx,ny , ix,jy ;
   float f_j00,f_jp1 , wt_00,wt_p1 ;

   if( im == NULL || ! MRI_IS_2D(im) ){
      fprintf(stderr,"*** mri_rota_bilinear only works on 2D images!\n") ; EXIT(1) ;
   }

   /** if complex image, break into pairs, do each separately, put back together **/

   if( im->kind == MRI_complex ){
      MRI_IMARR *impair ;
      MRI_IMAGE * rim , * iim , * tim ;
      impair = mri_complex_to_pair( im ) ;
      if( impair == NULL ){
         fprintf(stderr,"*** mri_complex_to_pair fails in mri_rota!\n") ; EXIT(1) ;
      }
      rim = IMAGE_IN_IMARR(impair,0) ;
      iim = IMAGE_IN_IMARR(impair,1) ;  FREE_IMARR(impair) ;
      tim = mri_rota_bilinear( rim , aa,bb,phi ) ; mri_free( rim ) ; rim = tim ;
      tim = mri_rota_bilinear( iim , aa,bb,phi ) ; mri_free( iim ) ; iim = tim ;
      newImg = mri_pair_to_complex( rim , iim ) ;
      mri_free( rim ) ; mri_free( iim ) ;
      MRI_COPY_AUX(newImg,im) ;
      return newImg ;
   }

   /** rotation params **/

   rot_cph = cos(phi) ; rot_sph = sin(phi) ;

   rot_dx  = (0.5 * im->nx) * (1.0-rot_cph) - aa*rot_cph - bb*rot_sph
            -(0.5 * im->ny) * rot_sph ;

   rot_dy  = (0.5 * im->nx) * rot_sph + aa*rot_sph - bb*rot_cph
            +(0.5 * im->ny) * (1.0-rot_cph) ;

   /** other initialization **/

   nx = im->nx ;  /* image dimensions */
   ny = im->ny ;

   if( im->kind == MRI_float ) imfl = im ;
   else                        imfl = mri_to_float( im ) ;

   far = MRI_FLOAT_PTR(imfl) ;              /* access to float data */
   newImg = mri_new( nx , nx , MRI_float ) ;   /* output image */
   nar = MRI_FLOAT_PTR(newImg) ;               /* output image data */

   /*** loop over output points and warp to them ***/

   for( jj=0 ; jj < nx ; jj++ ){
      xx = rot_sph * jj + rot_dx - rot_cph ;
      yy = rot_cph * jj + rot_dy + rot_sph ;
      for( ii=0 ; ii < nx ; ii++ ){

         xx += rot_cph ;  /* get x,y in original image */
         yy -= rot_sph ;

         ix = (xx >= 0.0) ? ((int) xx) : ((int) xx)-1 ;  /* floor */
         jy = (yy >= 0.0) ? ((int) yy) : ((int) yy)-1 ;

         fx = xx-ix ; wt_00 = 1.0 - fx ; wt_p1 = fx ;

         if( ix >= 0 && ix < nx-1 && jy >= 0 && jy < ny-1 ){
            float *fy00 , *fyp1 ;

            fy00 = far + (ix + jy*nx) ; fyp1 = fy00 + nx ;

            f_j00 = wt_00 * fy00[0] + wt_p1 * fy00[1] ;
            f_jp1 = wt_00 * fyp1[0] + wt_p1 * fyp1[1] ;

         } else {
            f_j00 = wt_00 * FINS(ix,jy  ) + wt_p1 * FINS(ix+1,jy  ) ;
            f_jp1 = wt_00 * FINS(ix,jy+1) + wt_p1 * FINS(ix+1,jy+1) ;
         }

         fy  = yy-jy ; nar[ii+jj*nx] = (1.0-fy) * f_j00 + fy * f_jp1 ;

      }
   }

   /*** cleanup and return ***/

   if( im != imfl ) mri_free(imfl) ;  /* throw away unneeded workspace */
   MRI_COPY_AUX(newImg,im) ;
   return newImg ;
}
Beispiel #26
0
int mri_warp3D_align_setup( MRI_warp3D_align_basis *bas )
{
   MRI_IMAGE *cim , *fitim ;
   int nx, ny, nz, nxy, nxyz , ii,jj,kk , nmap, *im ;
   float *wf , *wtar , clip , clip2 ;
   int   *ima , pp , wtproc , npar , nfree ;
   byte  *msk ;
   int ctstart ;

ENTRY("mri_warp3D_align_setup") ;

   ctstart = NI_clock_time() ;

   /*- check for good inputs -*/

   if( bas == NULL     || bas->imbase == NULL ) RETURN(1) ;
   if( bas->nparam < 1 || bas->param  == NULL ) RETURN(1) ;
   if( bas->vwfor == NULL ||
       bas->vwinv == NULL || bas->vwset == NULL ) RETURN(1) ;

   /*- set defaults in bas, if values weren't set by user -*/

   if( bas->scale_init <= 0.0f ) bas->scale_init = 1.0f ;
   if( bas->delfac     <= 0.0f ) bas->delfac     = 1.0f ;
   if( bas->regmode    <= 0    ) bas->regmode    = MRI_LINEAR ;
   if( bas->max_iter   <= 0    ) bas->max_iter   = 9 ;

   /* process the weight image? */

   wtproc = (bas->imwt == NULL) ? 1 : bas->wtproc ;
   npar   = bas->nparam ;

   nfree = npar ;
   for( pp=0 ; pp < npar ; pp++ )
     if( bas->param[pp].fixed ) nfree-- ;
   if( nfree <= 0 ) RETURN(1) ;
   bas->nfree = nfree ;

   /*- clean out anything from last call -*/

   mri_warp3D_align_cleanup( bas ) ;

   /*-- need local copy of input base image --*/

   cim = mri_to_float( bas->imbase ) ;
   nx=cim->nx ; ny=cim->ny ; nz=cim->nz ; nxy = nx*ny ; nxyz=nxy*nz ;

   /*-- make weight image up from the base image if it isn't supplied --*/

   if( bas->verb ) fprintf(stderr,"++ mri_warp3D_align_setup ENTRY\n") ;

   if( bas->imwt == NULL   ||
       bas->imwt->nx != nx ||
       bas->imwt->ny != ny ||
       bas->imwt->nz != nz   ) bas->imww = mri_copy( cim ) ;
   else                        bas->imww = mri_to_float( bas->imwt ) ;

   if( bas->twoblur > 0.0f ){
     float bmax = cbrt((double)nxyz) * 0.03 ;
     if( bmax < bas->twoblur ){
       if( bas->verb )
         fprintf(stderr,"+   shrink bas->twoblur from %.3f to %.3f\n",
                        bas->twoblur , bmax ) ;
       bas->twoblur = bmax ;
     }
   }

   if( bas->verb ) fprintf(stderr,"+   processing weight:") ;

   /* make sure weight is non-negative */

   wf = MRI_FLOAT_PTR(bas->imww) ;
   for( ii=0 ; ii < nxyz ; ii++ ) wf[ii] = fabs(wf[ii]) ;

   /* trim off edges of weight */

   if( wtproc ){
     int ff ;
     int xfade=bas->xedge , yfade=bas->yedge , zfade=bas->zedge ;

     if( xfade < 0 || yfade < 0 || zfade < 0 )
       mri_warp3D_align_edging_default(nx,ny,nz,&xfade,&yfade,&zfade) ;

     if( bas->twoblur > 0.0f ){
       xfade += (int)rint(1.5*bas->twoblur) ;
       yfade += (int)rint(1.5*bas->twoblur) ;
       zfade += (int)rint(1.5*bas->twoblur) ;
     }

     if( 3*zfade >= nz ) zfade = (nz-1)/3 ;
     if( 3*xfade >= nx ) xfade = (nx-1)/3 ;
     if( 3*yfade >= ny ) yfade = (ny-1)/3 ;

     if( bas->verb ) fprintf(stderr," [edge(%d,%d,%d)]",xfade,yfade,zfade) ;

     for( jj=0 ; jj < ny ; jj++ )
      for( ii=0 ; ii < nx ; ii++ )
       for( ff=0 ; ff < zfade ; ff++ )
         WW(ii,jj,ff) = WW(ii,jj,nz-1-ff) = 0.0f ;

     for( kk=0 ; kk < nz ; kk++ )
      for( jj=0 ; jj < ny ; jj++ )
       for( ff=0 ; ff < xfade ; ff++ )
         WW(ff,jj,kk) = WW(nx-1-ff,jj,kk) = 0.0f ;

     for( kk=0 ; kk < nz ; kk++ )
      for( ii=0 ; ii < nx ; ii++ )
       for( ff=0 ; ff < yfade ; ff++ )
        WW(ii,ff,kk) = WW(ii,ny-1-ff,kk) = 0.0f ;

   }

   /* spatially blur weight a little */

   if( wtproc ){
     float blur ;
     blur = 1.0f + MAX(1.5f,bas->twoblur) ;
     if( bas->verb ) fprintf(stderr," [blur(%.1f)]",blur) ;
     EDIT_blur_volume_3d( nx,ny,nz ,       1.0f,1.0f,1.0f ,
                          MRI_float , wf , blur,blur,blur  ) ;
   }

   /* get rid of low-weight voxels */

   clip  = 0.035 * mri_max(bas->imww) ;
   clip2 = 0.5*THD_cliplevel(bas->imww,0.4) ;
   if( clip2 > clip ) clip = clip2 ;
   if( bas->verb ) fprintf(stderr," [clip(%.1f)]",clip) ;
   for( ii=0 ; ii < nxyz ; ii++ ) if( wf[ii] < clip ) wf[ii] = 0.0f ;

   /* keep only the largest cluster of nonzero voxels */

   { byte *mmm = (byte *)malloc( sizeof(byte)*nxyz ) ;
     for( ii=0 ; ii < nxyz ; ii++ ) mmm[ii] = (wf[ii] > 0.0f) ;
     THD_mask_clust( nx,ny,nz, mmm ) ;
     THD_mask_erode( nx,ny,nz, mmm, 1 ) ;  /* cf. thd_automask.c */
     THD_mask_clust( nx,ny,nz, mmm ) ;
     for( ii=0 ; ii < nxyz ; ii++ ) if( !mmm[ii] ) wf[ii] = 0.0f ;
     free((void *)mmm) ;
   }

   if( bas->verb ) fprintf(stderr,"\n") ;

   /*-- make integer index map of weight > 0 voxels --*/

   nmap = 0 ;
   for( ii=0 ; ii < nxyz ; ii++ ) if( wf[ii] > 0.0f ) nmap++ ;

   if( bas->verb )
     fprintf(stderr,"+   using %d [%.3f%%] voxels\n",nmap,(100.0*nmap)/nxyz);

   if( nmap < 7*nfree+13 ){
     fprintf(stderr,"** mri_warp3D_align error: weight image too zero-ish!\n") ;
     mri_warp3D_align_cleanup( bas ) ; mri_free(cim) ;
     RETURN(1) ;
   }

   bas->imap = mri_new( nmap , 1 , MRI_int ) ;
   ima       = MRI_INT_PTR(bas->imap) ;
   bas->imsk = mri_new_conforming( bas->imww , MRI_byte ) ;
   msk       = MRI_BYTE_PTR(bas->imsk) ;
   for( ii=jj=0 ; ii < nxyz ; ii++ ){
     if( wf[ii] > 0.0f ){ ima[jj++] = ii; msk[ii] = 1; }
   }

   /* make copy of sqrt(weight), but only at mapped indexes */

   wtar = (float *)malloc(sizeof(float)*nmap) ;
   for( ii=0 ; ii < nmap ; ii++ ) wtar[ii] = sqrt(wf[ima[ii]]) ;

   /*-- for parameters that don't come with a step size, find one --*/

   clip = bas->tolfac ; if( clip <= 0.0f ) clip = 0.03f ;

   for( ii=0 ; ii < npar ; ii++ ){
     if( bas->param[ii].fixed ) continue ; /* don't need this */
     if( bas->param[ii].delta <= 0.0f )
       mri_warp3D_get_delta( bas , ii ) ;  /* find step size */
     if( bas->param[ii].toler <= 0.0f ){   /* and set default tolerance */
       bas->param[ii].toler = clip * bas->param[ii].delta ;
       if( bas->verb )
         fprintf(stderr,"+   set toler param#%d [%s] = %f\n",
                 ii+1,bas->param[ii].name,bas->param[ii].toler) ;
     }
   }

   /* don't need the computed weight image anymore */

   mri_free(bas->imww) ; bas->imww = NULL ; wf = NULL ;

   /*-- create image containing basis columns, then pseudo-invert it --*/

   if( bas->verb ) fprintf(stderr,"+  Compute Derivatives of Base\n") ;
   fitim = mri_warp3D_align_fitim( bas , cim , bas->regmode , bas->delfac ) ;
   if( bas->verb ) fprintf(stderr,"+   calculate pseudo-inverse\n") ;
   bas->imps = mri_psinv( fitim , wtar ) ;
   mri_free(fitim) ;

   if( bas->imps == NULL ){  /* bad bad bad */
     fprintf(stderr,"** mri_warp3D_align error: can't invert Base matrix!\n") ;
     free((void *)wtar) ; mri_warp3D_align_cleanup( bas ) ; mri_free(cim) ;
     RETURN(1) ;
   }

   /*--- twoblur? ---*/

   if( bas->twoblur > 0.0f ){
     float *car=MRI_FLOAT_PTR(cim) ;
     float blur = bas->twoblur ;
     float bfac = blur ;
          if( bfac < 1.1234f ) bfac = 1.1234f ;
     else if( bfac > 1.3456f ) bfac = 1.3456f ;

     if( bas->verb ) fprintf(stderr,"+  Compute Derivatives of Blurred Base\n") ;
     EDIT_blur_volume_3d( nx,ny,nz ,       1.0f,1.0f,1.0f ,
                          MRI_float , car, blur,blur,blur  ) ;
     fitim = mri_warp3D_align_fitim( bas , cim , MRI_LINEAR , bfac*bas->delfac ) ;
     if( bas->verb ) fprintf(stderr,"+   calculate pseudo-inverse\n") ;
     bas->imps_blur = mri_psinv( fitim , wtar ) ;
     mri_free(fitim) ;
     if( bas->imps_blur == NULL ){  /* bad */
       fprintf(stderr,"** mri_warp3D_align error: can't invert Blur matrix!\n") ;
     }
   }

   /*--- done ---*/

   mri_free(cim) ; free((void *)wtar) ;

   if( bas->verb ){
     double st = (NI_clock_time()-ctstart) * 0.001 ;
     fprintf(stderr,"++ mri_warp3D_align_setup EXIT: %.2f seconds elapsed\n",st);
   }

   RETURN(0);
}
Beispiel #27
0
static MRI_IMAGE * mri_dup2D_rgb3( MRI_IMAGE *inim )
{
   rgbyte *bin , *bout , *bin1,*bin2 , *bout1,*bout2,*bout3 ;
   MRI_IMAGE *outim ;
   int ii,jj , nx,ny , nxup,nyup ;

ENTRY("mri_dup2D_rgb3") ;
   if( inim == NULL || inim->kind != MRI_rgb ) RETURN(NULL) ;

   bin = (rgbyte *) MRI_RGB_PTR(inim); if( bin == NULL ) RETURN(NULL);

   /* make output image **/

   nx = inim->nx ; ny = inim->ny ; nxup = 3*nx ; nyup = 3*ny ;
   outim = mri_new( nxup , nyup , MRI_rgb ) ;
   bout  = (rgbyte *) MRI_RGB_PTR(outim) ;

   /** macros for the 9 different interpolations
       between the four corners:   ul  ur >   00 10 20
                                          >=> 01 11 21
                                   ll  lr >   02 12 22 **/

#define COUT_00(ul,ur,ll,lr) (     ul                              )
#define COUT_10(ul,ur,ll,lr) ((171*ul + 85*ur                ) >> 8)
#define COUT_20(ul,ur,ll,lr) (( 85*ul +171*ur                ) >> 8)

#define COUT_01(ul,ur,ll,lr) ((171*ul +         85*ll        ) >> 8)
#define COUT_11(ul,ur,ll,lr) ((114*ul + 57*ur + 57*ll + 28*lr) >> 8)
#define COUT_21(ul,ur,ll,lr) (( 57*ul +114*ur + 28*ll + 57*lr) >> 8)

#define COUT_02(ul,ur,ll,lr) (( 85*ul +        171*ll        ) >> 8)
#define COUT_12(ul,ur,ll,lr) (( 57*ul + 28*ur +114*ll + 57*lr) >> 8)
#define COUT_22(ul,ur,ll,lr) (( 28*ul + 57*ur + 57*ll +114*lr) >> 8)

  /** do 9 interpolations between  ul ur
                                   ll lr  for index #k, color #c **/

#define THREE_ROWS(k,c,ul,ur,ll,lr)                  \
   { bout1[3*k+1].c = COUT_00(ul.c,ur.c,ll.c,lr.c) ; \
     bout1[3*k+2].c = COUT_10(ul.c,ur.c,ll.c,lr.c) ; \
     bout1[3*k+3].c = COUT_20(ul.c,ur.c,ll.c,lr.c) ; \
     bout2[3*k+1].c = COUT_01(ul.c,ur.c,ll.c,lr.c) ; \
     bout2[3*k+2].c = COUT_11(ul.c,ur.c,ll.c,lr.c) ; \
     bout2[3*k+3].c = COUT_21(ul.c,ur.c,ll.c,lr.c) ; \
     bout3[3*k+1].c = COUT_02(ul.c,ur.c,ll.c,lr.c) ; \
     bout3[3*k+2].c = COUT_12(ul.c,ur.c,ll.c,lr.c) ; \
     bout3[3*k+3].c = COUT_22(ul.c,ur.c,ll.c,lr.c) ;  }

  /** do the above for all 3 colors **/

#define THREE_RGB(k,ul,ur,ll,lr)  { THREE_ROWS(k,r,ul,ur,ll,lr) ; \
                                    THREE_ROWS(k,g,ul,ur,ll,lr) ; \
                                    THREE_ROWS(k,b,ul,ur,ll,lr) ;  }

   bin1  = bin       ; bin2  = bin+nx    ;  /* 2 input rows */
   bout1 = bout +nxup; bout2 = bout1+nxup;  /* 3 output rows */
   bout3 = bout2+nxup;

   for( jj=0 ; jj < ny-1 ; jj++ ){   /* loop over input rows */

     for( ii=0 ; ii < nx-1 ; ii++ ){
        THREE_RGB(ii,bin1[ii],bin1[ii+1],bin2[ii],bin2[ii+1]) ;
     }

     /* here, ii=nx-1; can't use ii+1 */
     /* do the 3*ii+1 output only,    */
     /* and copy into 3*ii+2 column   */

     bout1[3*ii+1].r = COUT_00(bin1[ii].r,0,bin2[ii].r,0) ;
     bout2[3*ii+1].r = COUT_01(bin1[ii].r,0,bin2[ii].r,0) ;
     bout3[3*ii+1].r = COUT_02(bin1[ii].r,0,bin2[ii].r,0) ;

     bout1[3*ii+1].g = COUT_00(bin1[ii].g,0,bin2[ii].g,0) ;
     bout2[3*ii+1].g = COUT_01(bin1[ii].g,0,bin2[ii].g,0) ;
     bout3[3*ii+1].g = COUT_02(bin1[ii].g,0,bin2[ii].g,0) ;

     bout1[3*ii+1].b = COUT_00(bin1[ii].b,0,bin2[ii].b,0) ;
     bout2[3*ii+1].b = COUT_01(bin1[ii].b,0,bin2[ii].b,0) ;
     bout3[3*ii+1].b = COUT_02(bin1[ii].b,0,bin2[ii].b,0) ;

     bout1[3*ii+2] = bout1[3*ii+1] ;
     bout2[3*ii+2] = bout2[3*ii+1] ;
     bout3[3*ii+2] = bout3[3*ii+1] ;

     /* also copy [0] column output from column [1] */

     bout1[0] = bout1[1] ; bout2[0] = bout2[1] ; bout3[0] = bout3[1] ;

     /* advance input and output rows */

     bin1 = bin2; bin2 += nx ;
     bout1 = bout3+nxup; bout2 = bout1+nxup;
     bout3 = bout2+nxup;
   }

   /* here, jj=ny-1, so can't use jj+1 (bin2) */
   /* do the bout1 output row only, copy into bout2 */

   for( ii=0 ; ii < nx-1 ; ii++ ){
     bout1[3*ii+1].r = COUT_00(bin1[ii].r,bin1[ii+1].r,0,0) ;
     bout1[3*ii+2].r = COUT_10(bin1[ii].r,bin1[ii+1].r,0,0) ;
     bout1[3*ii+3].r = COUT_20(bin1[ii].r,bin1[ii+1].r,0,0) ;

     bout1[3*ii+1].g = COUT_00(bin1[ii].g,bin1[ii+1].g,0,0) ;
     bout1[3*ii+2].g = COUT_10(bin1[ii].g,bin1[ii+1].g,0,0) ;
     bout1[3*ii+3].g = COUT_20(bin1[ii].g,bin1[ii+1].g,0,0) ;

     bout1[3*ii+1].b = COUT_00(bin1[ii].b,bin1[ii+1].b,0,0) ;
     bout1[3*ii+2].b = COUT_10(bin1[ii].b,bin1[ii+1].b,0,0) ;
     bout1[3*ii+3].b = COUT_20(bin1[ii].b,bin1[ii+1].b,0,0) ;

     bout2[3*ii+1] = bout1[3*ii+1] ;
     bout2[3*ii+2] = bout1[3*ii+2] ;
     bout2[3*ii+3] = bout1[3*ii+3] ;
   }

   /* do bottom corners */

   bout1[0] = bout2[0] = bout2[1] = bout1[1] ;
   bout1[nxup-2] = bout1[nxup-1] = bout2[nxup-2] = bout2[nxup-1] = bout1[nxup-3] ;

   /* do first row of output as well */

   bout3 = bout+nxup ;
   for( ii=0 ; ii < nxup ; ii++ ) bout[ii] = bout3[ii] ;

   MRI_COPY_AUX(outim,inim) ;
   RETURN(outim) ;
}
Beispiel #28
0
static MRI_IMAGE * mri_dup2D_rgb2( MRI_IMAGE *inim )
{
   rgbyte *bin , *bout , *bin1,*bin2 , *bout1,*bout2 ;
   MRI_IMAGE *outim ;
   int ii,jj , nx,ny , nxup,nyup ;

ENTRY("mri_dup2D_rgb2") ;
   if( inim == NULL || inim->kind != MRI_rgb ) RETURN(NULL) ;

   bin = (rgbyte *) MRI_RGB_PTR(inim); if( bin == NULL ) RETURN(NULL);

   /* make output image **/

   nx = inim->nx ; ny = inim->ny ; nxup = 2*nx ; nyup = 2*ny ;
   outim = mri_new( nxup , nyup , MRI_rgb ) ;
   bout  = (rgbyte *) MRI_RGB_PTR(outim) ;

   /** macros for the 4 different interpolations
       between the four corners:   ul  ur >=> 00 10
                                   ll  lr >=> 01 11  **/

#define DOUT(ul,ur,ll,lr,a,b,c,d) ((a*ul+b*ur+c*ll+d*lr) >> 4)

#define DOUT_00(ul,ur,ll,lr) DOUT(ul,ur,ll,lr,9,3,3,1)
#define DOUT_10(ul,ur,ll,lr) DOUT(ul,ur,ll,lr,3,9,1,3)

#define DOUT_01(ul,ur,ll,lr) DOUT(ul,ur,ll,lr,3,1,9,3)
#define DOUT_11(ul,ur,ll,lr) DOUT(ul,ur,ll,lr,1,3,3,9)

  /** do r interpolations between  ul ur
                                   ll lr  for index #k, color #c **/

#define TWO_ROWS(k,c,ul,ur,ll,lr)                     \
   { bout1[2*k+1].c = DOUT_00(ul.c,ur.c,ll.c,lr.c) ;  \
     bout1[2*k+2].c = DOUT_10(ul.c,ur.c,ll.c,lr.c) ;  \
     bout2[2*k+1].c = DOUT_01(ul.c,ur.c,ll.c,lr.c) ;  \
     bout2[2*k+2].c = DOUT_11(ul.c,ur.c,ll.c,lr.c) ; }

  /** do the above for all 3 colors */

#define TWO_RGB(k,ul,ur,ll,lr)  { TWO_ROWS(k,r,ul,ur,ll,lr) ;  \
                                  TWO_ROWS(k,g,ul,ur,ll,lr) ;  \
                                  TWO_ROWS(k,b,ul,ur,ll,lr) ; }

   bin1  = bin    ;                 /* 2 input rows */
   bin2  = bin+nx ;

   bout1 = bout +nxup ;             /* 2 output rows */
   bout2 = bout1+nxup  ;

   for( jj=0 ; jj < ny-1 ; jj++ ){   /* loop over input rows */

     for( ii=0 ; ii < nx-1 ; ii++ ){
        TWO_RGB(ii,bin1[ii],bin1[ii+1],bin2[ii],bin2[ii+1]) ;
     }

     /* at this point, output rows have elements [1..2*nx-2] filled;
        now copy [1] into [0] and [2*nx-2] into [2*nx-1]            */

     bout1[0] = bout1[1] ;
     bout2[0] = bout2[1] ;

     bout1[nxup-1] = bout1[nxup-2] ;
     bout2[nxup-1] = bout2[nxup-2] ;

     /* advance input and output rows */

     bin1 = bin2; bin2 += nx ;
     bout1 = bout2+nxup; bout2 = bout1+nxup;
   }

   /* copy row 1 into row 0 */

   bout1 = bout ; bout2 = bout1+nxup ;
   for( ii=0 ; ii < nxup ; ii++ )
      bout1[ii] = bout2[ii] ;

   /* copy rown nyup-2 into row nyup-1 */

   bout1 = bout + (nyup-2)*nxup ; bout2 = bout1+nxup ;
   for( ii=0 ; ii < nxup ; ii++ )
      bout2[ii] = bout1[ii] ;

   MRI_COPY_AUX(outim,inim) ;
   RETURN(outim) ;
}
Beispiel #29
0
int main( int argc , char * argv[] )
{
   THD_3dim_dataset * dset ;
   THD_dataxes      * daxes ;
   FD_brick        ** brarr , * baxi , * bsag , * bcor ;

   int iarg , ii ;
   Boolean ok ;
   MRI_IMAGE * pim , * flim , * slim ;
   float * flar ;
   dset_range dr ;
   float val , fimfac ;
   int  ival,ityp , kk ;

   float xbot=BIGG,xtop=BIGG , ybot=BIGG,ytop=BIGG , zbot=BIGG,ztop=BIGG ;
   int   xgood=0 , ygood=0 , zgood=0 ,
         proj_code=PROJ_SUM , mirror_code=MIRR_NO , nsize=0 ;
   char  root[THD_MAX_NAME] = "proj." ;
   char  fname[THD_MAX_NAME] ;

   int ixbot=0,ixtop=0 , jybot=0,jytop=0 , kzbot=0,kztop=0 ;
   THD_fvec3 fv ;
   THD_ivec3 iv ;

   /*--- read command line arguments ---*/

   if( argc < 2 || strncmp(argv[1],"-help",6) == 0 ) Syntax() ;

   INIT_EDOPT( &PRED_edopt ) ;
   iarg = 1 ;
   while( iarg < argc && argv[iarg][0] == '-' ){

DB("new arg:",argv[iarg]) ;

      /**** check for editing option ****/

      ii = EDIT_check_argv( argc , argv , iarg , &PRED_edopt ) ;
      if( ii > 0 ){
         iarg += ii ;
         continue ;
      }

      /**** -sum or -max ****/

      if( strncmp(argv[iarg],"-sum",6) == 0 ){
         proj_code = PROJ_SUM ;
         iarg++ ; continue ;
      }

      if( strncmp(argv[iarg],"-max",6) == 0 ){
         proj_code = PROJ_MMAX ;
         iarg++ ; continue ;
      }

      if( strncmp(argv[iarg],"-amax",6) == 0 ){
         proj_code = PROJ_AMAX ;
         iarg++ ; continue ;
      }

      if( strncmp(argv[iarg],"-smax",6) == 0 ){
         proj_code = PROJ_SMAX ;
         iarg++ ; continue ;
      }

      if( strcmp(argv[iarg],"-first") == 0 ){  /* 02 Nov 2000 */
         proj_code = PROJ_FIRST ;
         first_thresh = strtod( argv[++iarg] , NULL ) ;
         iarg++ ; continue ;
      }

      /**** -mirror ****/

      if( strncmp(argv[iarg],"-mirror",6) == 0 ){
         mirror_code = MIRR_YES ;
         iarg++ ; continue ;
      }

      /**** -nsize ****/

      if( strncmp(argv[iarg],"-nsize",6) == 0 ){
         nsize = 1 ;
         iarg++ ; continue ;
      }

      /**** -output root ****/

      if( strncmp(argv[iarg],"-output",6) == 0 ||
          strncmp(argv[iarg],"-root",6)   == 0   ){

         if( iarg+1 >= argc ){
            fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ;
            exit(-1) ;
         }

         MCW_strncpy( root , argv[++iarg] , THD_MAX_NAME-1 ) ;
         ii = strlen(root) ;
         if( ii == 0 ){
            fprintf(stderr,"\n*** illegal rootname!\n") ; exit(-1) ;
         }
         if( root[ii-1] != '.' ){ root[ii] = '.' ; root[ii+1] = '\0' ; }
         iarg++ ; continue ;
      }

      /**** -ALL ****/

      if( strncmp(argv[iarg],"-ALL",6) == 0 ||
          strncmp(argv[iarg],"-all",6) == 0   ){

         xgood = ygood = zgood = 1 ;
         xbot  = ybot  = zbot  = -BIGG ;
         xtop  = ytop  = ztop  =  BIGG ;
         iarg++ ; continue ;
      }

      /**** -RL {all | x1 x2} ****/

      if( strncmp(argv[iarg],"-RL",6) == 0 ||
          strncmp(argv[iarg],"-LR",6) == 0 ||
          strncmp(argv[iarg],"-rl",6) == 0 ||
          strncmp(argv[iarg],"-lr",6) == 0 ||
          strncmp(argv[iarg],"-sag",6)== 0  ){

         char * cerr ; float tf ;

         xgood = 1 ;  /* mark for x projection */

         if( iarg+1 >= argc ){
            fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ;
            exit(-1) ;
         }

         if( strncmp(argv[iarg+1],"all",6) == 0 ||
             strncmp(argv[iarg+1],"ALL",6) == 0   ){

            xbot = -BIGG;
            xtop =  BIGG ;
            iarg += 2 ; continue ;
         }

         if( iarg+2 >= argc ){
            fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ;
            exit(-1) ;
         }

         xbot = strtod( argv[iarg+1] , &cerr ) ;
         if( cerr == argv[iarg+1] ){
            fprintf(stderr,"\n*** illegal argument after %s: %s\n",
                    argv[iarg],argv[iarg+1] ) ; exit(-1) ;
         }
         if( *cerr == 'R' && xbot > 0.0 ) xbot = -xbot ;

         xtop = strtod( argv[iarg+2] , &cerr ) ;
         if( cerr == argv[iarg+2] ){
            fprintf(stderr,"\n*** illegal argument after %s: %s\n",
                    argv[iarg],argv[iarg+2] ) ; exit(-1) ;
         }
         if( *cerr == 'R' && xtop > 0.0 ) xtop = -xtop ;

         if( xbot > xtop ){ tf = xbot ; xbot = xtop ; xtop = tf ; }
         iarg +=3 ; continue ;
      }

      /**** -AP {all | y1 y2} ****/

      if( strncmp(argv[iarg],"-AP",6) == 0 ||
          strncmp(argv[iarg],"-PA",6) == 0 ||
          strncmp(argv[iarg],"-ap",6) == 0 ||
          strncmp(argv[iarg],"-pa",6) == 0 ||
          strncmp(argv[iarg],"-cor",6)== 0  ){

         char * cerr ; float tf ;

         ygood = 1 ;  /* mark for y projection */

         if( iarg+1 >= argc ){
            fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ;
            exit(-1) ;
         }

         if( strncmp(argv[iarg+1],"all",6) == 0 ||
             strncmp(argv[iarg+1],"ALL",6) == 0   ){

            ybot = -BIGG ;
            ytop =  BIGG ;
            iarg += 2 ; continue ;
         }

         if( iarg+2 >= argc ){
            fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ;
            exit(-1) ;
         }

         ybot = strtod( argv[iarg+1] , &cerr ) ;
         if( cerr == argv[iarg+1] ){
            fprintf(stderr,"\n*** illegal argument after %s: %s\n",
                    argv[iarg],argv[iarg+1] ) ; exit(-1) ;
         }
         if( *cerr == 'A' && ybot > 0.0 ) ybot = -ybot ;

         ytop = strtod( argv[iarg+2] , &cerr ) ;
         if( cerr == argv[iarg+2] ){
            fprintf(stderr,"\n*** illegal argument after %s: %s\n",
                    argv[iarg],argv[iarg+2] ) ; exit(-1) ;
         }
         if( *cerr == 'A' && ytop > 0.0 ) ytop = -ytop ;

         if( ybot > ytop ){ tf = ybot ; ybot = ytop ; ytop = tf ; }
         iarg +=3 ; continue ;
      }

      /**** -IS {all | z1 z2} ****/

      if( strncmp(argv[iarg],"-IS",6) == 0 ||
          strncmp(argv[iarg],"-SI",6) == 0 ||
          strncmp(argv[iarg],"-is",6) == 0 ||
          strncmp(argv[iarg],"-si",6) == 0 ||
          strncmp(argv[iarg],"-axi",6)== 0   ){

         char * cerr ; float tf ;

         zgood = 1 ;  /* mark for y projection */

         if( iarg+1 >= argc ){
            fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ;
            exit(-1) ;
         }

         if( strncmp(argv[iarg+1],"all",6) == 0 ||
             strncmp(argv[iarg+1],"ALL",6) == 0   ){

            zbot = -BIGG ;
            ztop =  BIGG ;
            iarg += 2 ; continue ;
         }

         if( iarg+2 >= argc ){
            fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ;
            exit(-1) ;
         }

         zbot = strtod( argv[iarg+1] , &cerr ) ;
         if( cerr == argv[iarg+1] ){
            fprintf(stderr,"\n*** illegal argument after %s: %s\n",
                    argv[iarg],argv[iarg+1] ) ; exit(-1) ;
         }
         if( *cerr == 'I' && zbot > 0.0 ) zbot = -zbot ;

         ztop = strtod( argv[iarg+2] , &cerr ) ;
         if( cerr == argv[iarg+2] ){
            fprintf(stderr,"\n*** illegal argument after %s: %s\n",
                    argv[iarg],argv[iarg+2] ) ; exit(-1) ;
         }
         if( *cerr == 'I' && ztop > 0.0 ) ztop = -ztop ;

         if( zbot > ztop ){ tf = zbot ; zbot = ztop ; ztop = tf ; }
         iarg +=3 ; continue ;
      }

      /**** unknown option ****/

      fprintf(stderr,"\n*** Unknown option: %s\n",argv[iarg]) ;
      exit(-1) ;
   }  /* end of loop over input options */

   if( ! xgood && ! ygood && ! zgood ){
      fprintf(stderr,"\n*** No projections ordered!?\n") ; exit(-1) ;
   }

   /*--- open dataset and set up to extract data slices ---*/

   dset = THD_open_dataset( argv[iarg] ) ;
   if( dset == NULL ){
      fprintf(stderr,"\n*** Can't open dataset file %s\n",argv[iarg]) ;
      exit(-1) ;
   }
   if( DSET_NUM_TIMES(dset) > 1 ){
      fprintf(stderr,"\n*** Can't project time-dependent dataset!\n") ;
      exit(1) ;
   }
   EDIT_one_dataset( dset, &PRED_edopt ) ;
   daxes = dset->daxes ;
   brarr = THD_setup_bricks( dset ) ;
   baxi  = brarr[0] ; bsag = brarr[1] ; bcor = brarr[2] ;

   /*--- determine index range for each direction ---*/

   dr = PR_get_range( dset ) ;

   if( xgood ){
      if( xbot < dr.xbot ) xbot = dr.xbot ;
      if( xtop > dr.xtop ) xtop = dr.xtop ;

      fv = THD_dicomm_to_3dmm( dset , TEMP_FVEC3(xbot,0,0) ) ;
      iv = THD_3dmm_to_3dind ( dset , fv ) ;
      iv = THD_3dind_to_fdind( bsag , iv ) ; ixbot = iv.ijk[2] ;

      fv = THD_dicomm_to_3dmm( dset , TEMP_FVEC3(xtop,0,0) ) ;
      iv = THD_3dmm_to_3dind ( dset , fv ) ;
      iv = THD_3dind_to_fdind( bsag , iv ) ; ixtop = iv.ijk[2] ;

      if( ixbot > ixtop ) { ii = ixbot ; ixbot = ixtop ; ixtop = ii ; }

      if( ixbot <  0        ) ixbot = 0 ;
      if( ixtop >= bsag->n3 ) ixtop = bsag->n3 - 1 ;
   }

   if( ygood ){
      if( ybot < dr.ybot ) ybot = dr.ybot ;
      if( ytop > dr.ytop ) ytop = dr.ytop ;

      fv = THD_dicomm_to_3dmm( dset , TEMP_FVEC3(0,ybot,0) ) ;
      iv = THD_3dmm_to_3dind ( dset , fv ) ;
      iv = THD_3dind_to_fdind( bcor , iv ) ; jybot = iv.ijk[2] ;

      fv = THD_dicomm_to_3dmm( dset , TEMP_FVEC3(0,ytop,0) ) ;
      iv = THD_3dmm_to_3dind ( dset , fv ) ;
      iv = THD_3dind_to_fdind( bcor , iv ) ; jytop = iv.ijk[2] ;

      if( jybot > jytop ) { ii = jybot ; jybot = jytop ; jytop = ii ; }

      if( jybot <  0        ) jybot = 0 ;
      if( jytop >= bcor->n3 ) jytop = bcor->n3 - 1 ;
   }

   if( zgood ){
      if( zbot < dr.zbot ) zbot = dr.zbot ;
      if( ztop > dr.ztop ) ztop = dr.ztop ;

      fv = THD_dicomm_to_3dmm( dset , TEMP_FVEC3(0,0,zbot) ) ;
      iv = THD_3dmm_to_3dind ( dset , fv ) ;
      iv = THD_3dind_to_fdind( baxi , iv ) ; kzbot = iv.ijk[2] ;

      fv = THD_dicomm_to_3dmm( dset , TEMP_FVEC3(0,0,ztop) ) ;
      iv = THD_3dmm_to_3dind ( dset , fv ) ;
      iv = THD_3dind_to_fdind( baxi , iv ) ; kztop = iv.ijk[2] ;

      if( kzbot > kztop ) { ii = kzbot ; kzbot = kztop ; kztop = ii ; }

      if( kzbot <  0        ) kzbot = 0 ;
      if( kztop >= baxi->n3 ) kztop = baxi->n3 - 1 ;
   }

   ival   = DSET_PRINCIPAL_VALUE(dset) ;    /* index to project */
   ityp   = DSET_BRICK_TYPE(dset,ival) ;    /* type of this data */
   fimfac = DSET_BRICK_FACTOR(dset,ival) ;  /* scale factor of this data */

   /*--- project the x direction, if desired ---*/

   if( xgood ){
      int n1 = bsag->n1 , n2 = bsag->n2 ;
      int ss , npix ;
      float fmax , fmin , scl ;

      /*-- set up --*/

      npix = n1*n2 ;
      flim = mri_new( n1 , n2 , MRI_float ) ;
      flar = mri_data_pointer( flim ) ;
      for( ii=0 ; ii < npix ; ii++ ) flar[ii] = 0.0 ;

      /*-- actually project --*/

      for( ss=ixbot ; ss <= ixtop ; ss++ ){
         slim = FD_brick_to_mri( ss , ival , bsag ) ;
         if( slim->kind != MRI_float ){
            pim = mri_to_float( slim ) ;
            mri_free( slim ) ; slim = pim ;
         }
         PR_one_slice( proj_code , slim , flim ) ;
         mri_free( slim ) ;
      }

      /*-- form output --*/

      if( fimfac != 0.0 && fimfac != 1.0 ){
         slim = mri_scale_to_float( 1.0/fimfac , flim ) ;
         mri_free(flim) ; flim = slim ;
      }

      scl = PR_type_scale( ityp , flim ) ;
      pim = mri_to_mri_scl( ityp , scl , flim ) ; mri_free( flim ) ;
      if( nsize ){
         slim = mri_nsize( pim ) ;
         if( slim != NULL && slim != pim ) { mri_free(pim) ; pim = slim ; }
      }

      if( scl != 1.0 )
         printf("Sagittal projection pixels scaled by %g to avoid overflow!\n",
                scl ) ;

      fmax = mri_max(pim) ; fmin = mri_min(pim) ;
      printf("Sagittal projection min = %g  max = %g\n",fmin,fmax) ;

      strcpy(fname,root) ; strcat(fname,"sag") ;
      mri_write( fname, pim ) ;
      mri_free(pim) ;
   }

   /*--- project the y direction, if desired ---*/

   if( ygood ){
      int n1 = bcor->n1 , n2 = bcor->n2 ;
      int ss , npix ;
      float fmax , fmin , scl ;

      /*-- set up --*/

      npix = n1*n2 ;
      flim = mri_new( n1 , n2 , MRI_float ) ;
      flar = mri_data_pointer( flim ) ;
      for( ii=0 ; ii < npix ; ii++ ) flar[ii] = 0.0 ;

      /*-- actually project --*/

      for( ss=jybot ; ss <= jytop ; ss++ ){
         slim = FD_brick_to_mri( ss , ival , bcor ) ;
         if( slim->kind != MRI_float ){
            pim = mri_to_float( slim ) ;
            mri_free( slim ) ; slim = pim ;
         }
         PR_one_slice( proj_code , slim , flim ) ;
         mri_free( slim ) ;
      }

      /*-- form output --*/

      if( fimfac != 0.0 && fimfac != 1.0 ){
         slim = mri_scale_to_float( 1.0/fimfac , flim ) ;
         mri_free(flim) ; flim = slim ;
      }

      scl = PR_type_scale( ityp , flim ) ;
      pim = mri_to_mri_scl( ityp , scl , flim ) ; mri_free( flim ) ;
      if( nsize ){
         slim = mri_nsize( pim ) ;
         if( slim != NULL && slim != pim ) { mri_free(pim) ; pim = slim ; }
      }

      if( scl != 1.0 )
         printf("Coronal projection pixels scaled by %g to avoid overflow!\n",
                scl ) ;

      fmax = mri_max(pim) ; fmin = mri_min(pim) ;
      printf("Coronal projection min = %g  max = %g\n",fmin,fmax) ;

      if( mirror_code == MIRR_YES ){
         slim = mri_flippo( MRI_ROT_0 , TRUE , pim ) ;
         mri_free(pim) ; pim = slim ;
      }
      strcpy(fname,root) ; strcat(fname,"cor") ;
      mri_write( fname, pim ) ;
      mri_free(pim) ;
   }

   /*--- project the z direction, if desired ---*/

   if( zgood ){
      int n1 = baxi->n1 , n2 = baxi->n2 ;
      int ss , npix ;
      float fmax , fmin , scl ;

      /*-- set up --*/

      npix = n1*n2 ;
      flim = mri_new( n1 , n2 , MRI_float ) ;
      flar = mri_data_pointer( flim ) ;
      for( ii=0 ; ii < npix ; ii++ ) flar[ii] = 0.0 ;

      /*-- actually project --*/

      for( ss=kzbot ; ss <= kztop ; ss++ ){
         slim = FD_brick_to_mri( ss , ival , baxi ) ;
         if( slim->kind != MRI_float ){
            pim = mri_to_float( slim ) ;
            mri_free( slim ) ; slim = pim ;
         }
         PR_one_slice( proj_code , slim , flim ) ;
         mri_free( slim ) ;
      }

      /*-- form output --*/

      if( fimfac != 0.0 && fimfac != 1.0 ){
         slim = mri_scale_to_float( 1.0/fimfac , flim ) ;
         mri_free(flim) ; flim = slim ;
      }

      scl = PR_type_scale( ityp , flim ) ;
      pim = mri_to_mri_scl( ityp , scl , flim ) ; mri_free( flim ) ;
      if( nsize ){
         slim = mri_nsize( pim ) ;
         if( slim != NULL && slim != pim ) { mri_free(pim) ; pim = slim ; }
      }

      if( scl != 1.0 )
         printf("Axial projection pixels scaled by %g to avoid overflow!\n",
                scl ) ;

      fmax = mri_max(pim) ; fmin = mri_min(pim) ;
      printf("Axial projection min = %g  max = %g\n",fmin,fmax) ;

      if( mirror_code == MIRR_YES ){
         slim = mri_flippo( MRI_ROT_0 , TRUE , pim ) ;
         mri_free(pim) ; pim = slim ;
      }
      strcpy(fname,root) ; strcat(fname,"axi") ;
      mri_write( fname, pim ) ;
      mri_free(pim) ;
   }

   exit(0) ;
}
Beispiel #30
0
static MRI_IMAGE * mri_dup2D_rgb4( MRI_IMAGE *inim )
{
   rgbyte *bin , *bout , *bin1,*bin2 , *bout1,*bout2,*bout3,*bout4 ;
   MRI_IMAGE *outim ;
   int ii,jj , nx,ny , nxup,nyup ;

ENTRY("mri_dup2D_rgb4") ;
   if( inim == NULL || inim->kind != MRI_rgb ) RETURN(NULL);

   bin = (rgbyte *) MRI_RGB_PTR(inim); if( bin == NULL ) RETURN(NULL);

   /* make output image **/

   nx = inim->nx ; ny = inim->ny ; nxup = 4*nx ; nyup = 4*ny ;
   outim = mri_new( nxup , nyup , MRI_rgb ) ;
   bout  = (rgbyte *) MRI_RGB_PTR(outim) ;

   /** macros for the 16 different interpolations
       between the four corners:   ul    ur >   00 10 20 30
                                            >=> 01 11 21 31
                                            >=> 02 12 22 32
                                   ll    lr >   03 13 23 33 **/

#define BOUT(ul,ur,ll,lr,a,b,c,d) ((a*ul+b*ur+c*ll+d*lr) >> 6)

#define BOUT_00(ul,ur,ll,lr) BOUT(ul,ur,ll,lr,49, 7, 7, 1)
#define BOUT_10(ul,ur,ll,lr) BOUT(ul,ur,ll,lr,35,21, 5, 3)
#define BOUT_20(ul,ur,ll,lr) BOUT(ul,ur,ll,lr,21,35, 3, 5)
#define BOUT_30(ul,ur,ll,lr) BOUT(ul,ur,ll,lr, 7,49, 1, 7)

#define BOUT_01(ul,ur,ll,lr) BOUT(ul,ur,ll,lr,35, 5,21, 3)
#define BOUT_11(ul,ur,ll,lr) BOUT(ul,ur,ll,lr,25,15,15, 9)
#define BOUT_21(ul,ur,ll,lr) BOUT(ul,ur,ll,lr,15,25, 9,15)
#define BOUT_31(ul,ur,ll,lr) BOUT(ul,ur,ll,lr, 5,35, 3,21)

#define BOUT_02(ul,ur,ll,lr) BOUT(ul,ur,ll,lr,21, 3,35, 5)
#define BOUT_12(ul,ur,ll,lr) BOUT(ul,ur,ll,lr,15, 9,25,15)
#define BOUT_22(ul,ur,ll,lr) BOUT(ul,ur,ll,lr, 9,15,15,25)
#define BOUT_32(ul,ur,ll,lr) BOUT(ul,ur,ll,lr, 3,21, 5,35)

#define BOUT_03(ul,ur,ll,lr) BOUT(ul,ur,ll,lr, 7, 1,49, 7)
#define BOUT_13(ul,ur,ll,lr) BOUT(ul,ur,ll,lr, 5, 3,35,21)
#define BOUT_23(ul,ur,ll,lr) BOUT(ul,ur,ll,lr, 3, 5,21,35)
#define BOUT_33(ul,ur,ll,lr) BOUT(ul,ur,ll,lr, 1, 7, 7,49)


  /** do 16 interpolations between  ul ur
                                    ll lr  for index #k, color #c **/

#define FOUR_ROWS(k,c,ul,ur,ll,lr)                    \
   { bout1[4*k+2].c = BOUT_00(ul.c,ur.c,ll.c,lr.c) ;  \
     bout1[4*k+3].c = BOUT_10(ul.c,ur.c,ll.c,lr.c) ;  \
     bout1[4*k+4].c = BOUT_20(ul.c,ur.c,ll.c,lr.c) ;  \
     bout1[4*k+5].c = BOUT_30(ul.c,ur.c,ll.c,lr.c) ;  \
     bout2[4*k+2].c = BOUT_01(ul.c,ur.c,ll.c,lr.c) ;  \
     bout2[4*k+3].c = BOUT_11(ul.c,ur.c,ll.c,lr.c) ;  \
     bout2[4*k+4].c = BOUT_21(ul.c,ur.c,ll.c,lr.c) ;  \
     bout2[4*k+5].c = BOUT_31(ul.c,ur.c,ll.c,lr.c) ;  \
     bout3[4*k+2].c = BOUT_02(ul.c,ur.c,ll.c,lr.c) ;  \
     bout3[4*k+3].c = BOUT_12(ul.c,ur.c,ll.c,lr.c) ;  \
     bout3[4*k+4].c = BOUT_22(ul.c,ur.c,ll.c,lr.c) ;  \
     bout3[4*k+5].c = BOUT_32(ul.c,ur.c,ll.c,lr.c) ;  \
     bout4[4*k+2].c = BOUT_03(ul.c,ur.c,ll.c,lr.c) ;  \
     bout4[4*k+3].c = BOUT_13(ul.c,ur.c,ll.c,lr.c) ;  \
     bout4[4*k+4].c = BOUT_23(ul.c,ur.c,ll.c,lr.c) ;  \
     bout4[4*k+5].c = BOUT_33(ul.c,ur.c,ll.c,lr.c) ; }

  /** do the above for all 3 colors */

#define FOUR_RGB(k,ul,ur,ll,lr)  { FOUR_ROWS(k,r,ul,ur,ll,lr) ; \
                                   FOUR_ROWS(k,g,ul,ur,ll,lr) ; \
                                   FOUR_ROWS(k,b,ul,ur,ll,lr) ;  }

   bin1  = bin    ;                  /* 2 input rows */
   bin2  = bin+nx ;

   bout1 = bout+2*nxup ;             /* 4 output rows */
   bout2 = bout1+nxup  ;
   bout3 = bout2+nxup  ;
   bout4 = bout3+nxup  ;

   for( jj=0 ; jj < ny-1 ; jj++ ){   /* loop over input rows */

     for( ii=0 ; ii < nx-1 ; ii++ ){
        FOUR_RGB(ii,bin1[ii],bin1[ii+1],bin2[ii],bin2[ii+1]) ;
     }

     /* at this point, output rows have elements [2..4*nx-3] filled;
        now copy [2] into [0..1] and [4*nx-3] into [4*nx-2..4*nx-1] */

     bout1[0] = bout1[1] = bout1[2] ;
     bout2[0] = bout2[1] = bout2[2] ;
     bout3[0] = bout3[1] = bout3[2] ;
     bout4[0] = bout4[1] = bout4[2] ;

     bout1[nxup-2] = bout1[nxup-1] = bout1[nxup-2] ;
     bout2[nxup-2] = bout2[nxup-1] = bout2[nxup-2] ;
     bout3[nxup-2] = bout3[nxup-1] = bout3[nxup-2] ;
     bout4[nxup-2] = bout4[nxup-1] = bout4[nxup-2] ;

     /* advance input and output rows */

     bin1 = bin2; bin2 += nx ;
     bout1 = bout4+nxup; bout2 = bout1+nxup;
     bout3 = bout2+nxup; bout4 = bout3+nxup;
   }

   /* copy row 2 into rows 0 and row 1 */

   bout1 = bout ; bout2 = bout1+nxup ; bout3 = bout2+nxup ;
   for( ii=0 ; ii < nxup ; ii++ )
      bout1[ii] = bout2[ii] = bout3[ii] ;

   /* copy rown nyup-3 into rows nyup-2 and nyup-1 */

   bout1 = bout + (nyup-3)*nxup ; bout2 = bout1+nxup ; bout3 = bout2+nxup ;
   for( ii=0 ; ii < nxup ; ii++ )
      bout2[ii] = bout3[ii] = bout1[ii] ;

   MRI_COPY_AUX(outim,inim) ;
   RETURN(outim) ;
}