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