1 #include "mrilib.h"
2 
3 /*----------------------------------------------------------------------------*/
4 
mri_streakize(MRI_IMAGE * im,MRI_IMAGE * sxim,MRI_IMAGE * syim)5 MRI_IMAGE * mri_streakize( MRI_IMAGE *im , MRI_IMAGE *sxim , MRI_IMAGE *syim )
6 {
7    MRI_IMAGE *qim ; byte *qar , *iar ;
8    float *sxar , *syar ;
9    int nx,ny,nxy , kk,dk , ii,jj,sk, dd,di,dj , ei,ej , ns ;
10    float strk , sx,sy , rr,gg,bb ;
11 
12    nx = im->nx ; ny = im->ny ; nxy = nx*ny ;
13 
14    qim = mri_copy(im) ; qar = MRI_RGB_PTR(qim) ; iar = MRI_RGB_PTR(im) ;
15    sxar = MRI_FLOAT_PTR(sxim) ; syar = MRI_FLOAT_PTR(syim) ;
16 
17 /* ININFO_message("mri_streakize") ; */
18 
19    for( kk=0 ; kk < nxy ; kk++ ){
20      sx = sxar[kk] ; sy = syar[kk] ; if( sx == 0.0f && sy == 0.0f ) continue ;
21      strk = sqrtf(sx*sx+sy*sy) ;     if( strk < 2.0f              ) continue ;
22      sx /= strk ; sy /= strk ;       if( strk > 20.0f ) strk = 20.0f ;
23      sk = (int)(strk+0.499f) ;
24      rr = iar[3*kk+0] ; gg = iar[3*kk+1] ; bb = iar[3*kk+2] ; ns = 1 ;
25      ii = kk % nx ; jj = kk / nx ;
26      for( dd=1 ; dd <= sk ; dd++ ){
27        di = (int)(dd*sx+0.499f) ; dj = (int)(dd*sy+0.499f) ;
28        if( di == 0.0f && dj == 0.0f ) continue ;
29        ei = ii+di ; ej = jj+dj ;
30        if( ei >= 0 && ei < nx && ej >= 0 && ej < ny ){
31          dk = ei + ej*nx ;
32          rr += iar[3*dk+0] ; gg += iar[3*dk+1] ; bb += iar[3*dk+2] ; ns++ ;
33        }
34        ei = ii-di ; ej = jj-dj ;
35        if( ei >= 0 && ei < nx && ej >= 0 && ej < ny ){
36          dk = ei + ej*nx ;
37          rr += iar[3*dk+0] ; gg += iar[3*dk+1] ; bb += iar[3*dk+2] ; ns++ ;
38        }
39      }
40      if( ns > 1 ){
41        rr /= ns ; gg /= ns ; bb /= ns ;
42        qar[3*kk+0] = BYTEIZE(rr) ; qar[3*kk+1] = BYTEIZE(gg) ; qar[3*kk+2] = BYTEIZE(bb) ;
43      }
44    }
45 
46    return qim ;
47 }
48 
49 /*----------------------------------------------------------------------------*/
50 
51 static float sigfac = 0.01f ;
52 
mri_vgize(MRI_IMAGE * im)53 MRI_IMAGE * mri_vgize( MRI_IMAGE *im )
54 {
55    MRI_IMAGE *blim , *gxim,*gyim , *bxim,*byim ;
56    float     *bar , *gxar,*gyar , *bxar,*byar ;
57    int nx,ny,nxy , ii,jj,kk,joff ;
58    float bsig , bmax , gsiz , blen , bx,by , slen , cc,ss ;
59 
60    if( im == NULL || im->kind != MRI_rgb ) return NULL ;
61 
62    nx = im->nx ; ny = im->ny ; nxy = nx*ny ;
63 
64    bsig = sqrtf(nx*(float)ny) * sigfac ;
65    if( bsig < 1.5f ) bsig = 1.5f ;
66 /* INFO_message("mri_vgize: nx=%d ny=%d bsig=%.3f",nx,ny,bsig) ; */
67 
68    bxim = mri_to_float(im) ;
69    blim = mri_float_blur2D( bsig , bxim ) ; mri_free(bxim) ;
70    bar  = MRI_FLOAT_PTR(blim) ;
71 
72    gxim = mri_copy(blim) ; gxar = MRI_FLOAT_PTR(gxim) ;
73    gyim = mri_copy(blim) ; gyar = MRI_FLOAT_PTR(gyim) ;
74 
75 /* ININFO_message("compute gradients") ; */
76    for( jj=0 ; jj < ny ; jj++ ){
77     joff = jj*nx ;
78     for( ii=0 ; ii < nx ; ii++ ){
79       if( jj==0 || jj==ny-1 || ii==0 || ii==nx-1 ){
80         gxar[ii+joff] = gyar[ii+joff] = 0.0f ;
81       } else {
82         gxar[ii+joff] = bar[ii+joff+1 ] - bar[ii+joff-1 ] ;
83         gyar[ii+joff] = bar[ii+joff+nx] - bar[ii+joff-nx] ;
84       }
85    }}
86 /* ININFO_message("blur gradients") ; */
87    bxim = mri_float_blur2D(0.5f*bsig,gxim); mri_free(gxim); bxar = MRI_FLOAT_PTR(bxim);
88    byim = mri_float_blur2D(0.5f*bsig,gyim); mri_free(gyim); byar = MRI_FLOAT_PTR(byim);
89 /* ININFO_message("find gradient max") ; */
90    bmax = 0.0f ;
91    for( kk=0 ; kk < nxy ; kk++ ){
92      gsiz = bxar[kk]*bxar[kk] + byar[kk]*byar[kk] ;
93      if( gsiz > bmax ) bmax = gsiz ;
94    }
95    bmax = sqrtf(bmax) ;
96 /* ININFO_message("bmax=%g",bmax) ; */
97    if( bmax == 0.0f ){ mri_free(bxim); mri_free(byim) ; return NULL ; }
98    bmax = 1.0f / bmax ;
99    slen = 1.3f * bsig ;
100    for( kk=0 ; kk < nxy ; kk++ ){
101      bx = bxar[kk]*bmax ; by = byar[kk]*bmax ; gsiz = sqrtf(bx*bx+by*by) ;
102      if( gsiz < 0.03f && gsiz > 0.0f ){
103        bx *= (0.111f*slen/gsiz) ; by *= (0.111f*slen/gsiz) ;
104      } else if( gsiz < 0.30f ){
105        bx *= (0.333f*slen/gsiz) ; by *= (0.333f*slen/gsiz) ;
106      } else {
107        bx *= (slen/gsiz) ; by *= (slen/gsiz) ;
108      }
109      bxar[kk] = by ; byar[kk] = -bx ;
110      bar[kk]  = (float)(30.0*drand48()-15.0) ;
111    }
112 /* ININFO_message("blur angles") ; */
113    gxim = mri_float_blur2D(0.5f*bsig,blim); mri_free(blim); gxar = MRI_FLOAT_PTR(gxim);
114    bmax = 0.0f ;
115    for( kk=0 ; kk < nxy ; kk++ ){
116      gsiz = fabsf(gxar[kk]) ; if( gsiz > bmax ) bmax = gsiz ;
117    }
118 /* ININFO_message("max angle=%g",bmax) ; */
119    if( bmax > 0.0f ){
120      bmax = (40.0f * PI/180.0f) / bmax ;
121      for( kk=0 ; kk < nxy ; kk++ ){
122        bx = bxar[kk] ; by = byar[kk] ; if( bx==0.0f && by==0.0f ) continue ;
123        cc = cosf(bmax*gxar[kk]) ;
124        ss = sinf(bmax*gxar[kk]) ;
125        bxar[kk] =  cc*bx + ss*by ;
126        byar[kk] = -ss*bx + cc*by ;
127      }
128    }
129    mri_free(gxim) ;
130 
131    blim = mri_streakize( im , bxim , byim ) ;
132 
133    mri_free(bxim) ; mri_free(byim) ;
134 
135    return blim ;
136 }
137 
138 /*----------------------------------------------------------------------------*/
139 
main(int argc,char * argv[])140 int main( int argc , char *argv[] )
141 {
142    MRI_IMAGE *inim , *outim ;
143    int iarg=1 ;
144    char *fname="vgize.png" ;
145 
146    if( argc < 2 || strcasecmp(argv[1],"-help") == 0 ){
147      printf(
148        "Usage: img [-fac f] inputimage [prefix]\n"
149        "\n"
150        "* Takes a 2D image and applies a painting effect.\n"
151        "* Output is in png format.\n"
152        "* '-fac' lets you set the size of the painting effect.\n"
153        "  Larger is weirder. The default is 1 = 1%% of image size.\n"
154        "* This is just for fun.\n"
155        "* Author: Vincent van Zhark (the lesser).\n"
156      ) ;
157      exit(0) ;
158    }
159 
160    if( strcasecmp(argv[iarg],"-fac") == 0 ){
161      float fac ;
162      iarg++ ; if( iarg >= argc ) ERROR_exit("bad fac") ;
163      fac = (float)strtod(argv[iarg],NULL) ;
164      if( fac >= 1.0f ) fac *= 0.01f ;
165      if( fac >  0.2f ) fac  = 0.2f  ;
166      sigfac = fac ;
167      iarg++ ;
168    }
169 
170    inim = mri_read(argv[iarg]) ;
171    if( inim == NULL || inim->nz > 1 ) ERROR_exit("bad input input") ;
172 
173    if( inim->kind != MRI_rgb ){
174      MRI_IMAGE *qim = mri_to_rgb(inim) ;
175      mri_free(inim) ; inim = qim ;
176    }
177 
178    outim = mri_vgize(inim) ;
179 
180    if( outim == NULL ) ERROR_exit("bad vgize operation") ;
181 
182    if( ++iarg < argc ){
183      fname = (char *)malloc(sizeof(char)*(strlen(argv[iarg])+16)) ;
184      strcpy(fname,argv[iarg]) ;
185      if( strcasestr(fname,".png") == NULL ) strcat(fname,".png") ;
186    }
187 
188    mri_write_png( fname , outim ) ;
189    INFO_message("output %s",fname) ;
190    exit(0) ;
191 }
192