TPCCLIB
Loading...
Searching...
No Matches
trmrp.c
Go to the documentation of this file.
1
7/*****************************************************************************/
8#include "libtpcrec.h"
9/*****************************************************************************/
10
11/*****************************************************************************/
20 float *bla,
23 float *tra,
25 int dim,
28 float *image,
30 int iter,
32 int os_sets,
34 int rays,
36 int views,
38 int maskdim,
40 float zoom,
42 float beta,
44 float axial_fov,
46 float sample_distance,
48 int skip_prior,
50 int osl,
52 float shiftX,
54 float shiftY,
56 float rotation,
58 int verbose
59) {
60 if(verbose>0) printf("trmrp()\n");
61
62 if(bla==NULL || tra==NULL || image==NULL) return(1);
63 if(rays<2 || views<2 || dim<2 || iter<1 || os_sets<1) return(1);
64 if(maskdim!=3 && maskdim!=5) return(1);
65 if(zoom<0.05) return(1);
66 //if(dim%2) return(2);
67
68
69 /* Set scale */
70 int recrays;
71 float scale, bp_zoom;
72 recrays=(int)((float)dim*zoom);
73 bp_zoom=zoom*(float)dim/(float)recrays;
74 scale=((float)recrays/(float)rays)*bp_zoom*bp_zoom/(float)views;
75 if(verbose>1) {
76 printf(" recrays := %d\n", recrays);
77 printf(" bp_zoom := %g\n", bp_zoom);
78 printf(" scale := %g\n", scale);
79 }
80
81 int views_in_set;
82 views_in_set=views/os_sets;
83 if(verbose>1) printf(" views_in_set := %d\n", views_in_set);
84
85 /* Make the Ordered Subset process order (bit-reversed sequence) */
86 int seq[os_sets]; set_os_set(os_sets, seq);
87 if(verbose>2) {
88 printf("os_sets :=");
89 for(int i=0; i<os_sets; i++) printf(" %d", seq[i]);
90 printf("\n");
91 }
92 /* Arrange transmission and blank sinograms, and interpolate so that
93 bin width equals pixel width */
94 float recbla[recrays*views], rectra[recrays*views];
95 {
96 float blaset[rays*views], traset[rays*views];
97 /* arrange */
98 for(int s=0; s<os_sets; s++) {
99 for(int j=0; j<views_in_set; j++) {
100 memcpy((char*)(blaset + s*rays*views_in_set + j*rays),
101 (char*)(bla + j*rays*os_sets + s*rays), rays*sizeof(float));
102 memcpy((char*)(traset + s*rays*views_in_set + j*rays),
103 (char*)(tra + j*rays*os_sets + s*rays), rays*sizeof(float));
104 }
105 }
106 /* interpolate */
107 recInterpolateSinogram(blaset, recbla, rays, recrays, views);
108 recInterpolateSinogram(traset, rectra, rays, recrays, views);
109 }
110
111
112 /* Sum of blank and transmission */
113 float bsum=0.0, tsum=0.0;
114 for(int i=0; i<recrays*views_in_set; i++) bsum+=recbla[i];
115 for(int i=0; i<recrays*views_in_set; i++) tsum+=rectra[i];
116 if(verbose>2) {
117 printf(" blank_sum := %g\n", bsum);
118 printf(" transmission_sum := %g\n", tsum);
119 }
120
121 /* Make an initial image: an uniform disk enclosed by rays with a value
122 matching the total count */
123 if(verbose>1) printf("creating initial %dx%d image\n", dim, dim);
124 int imgsize=dim*dim;
125 float current_img[imgsize];
126 for(int i=0; i<imgsize; i++) image[i]=0.0;
127 float init;
128 init=-logf(tsum/bsum)*sample_distance/axial_fov;
129 if(verbose>2) printf(" init := %g\n", init);
130
131 for(int k=0; k<imgsize; k++) current_img[k]=0.0;
132 {
133 int j, k=0;
134 for(j=dim/2-1; j>=-dim/2; j--) {
135 for(int i=-dim/2; i<dim/2; i++) {
136 if((int)hypot((double)i, (double)j) < dim/2-1) current_img[k]=init;
137 k++;
138 }
139 }
140 }
141
142 /* Pre-compute the sine tables for back-projection */
143 if(verbose>1) printf("computing sine table\n");
144 float sinB[3*views/2], sinBrot[3*views/2];
145 recSinTables(views, sinB, sinBrot, rotation);
146 for(int i=0; i<3*views/2; i++) sinB[i]/=bp_zoom;
147 for(int i=0; i<3*views/2; i++) sinBrot[i]/=bp_zoom;
148
149 /* Calculate pixel size */
150 float pixsize;
151 pixsize=sample_distance*(float)rays/(zoom*(float)dim);
152 if(verbose>2) printf(" pixsize := %g\n", pixsize);
153 /* ... and convert shifts from mm to pixels */
154 shiftX/=pixsize;
155 shiftY/=pixsize;
156
157
158 /* Iterations */
159 if(verbose>1) {printf("iterations\n"); fflush(stdout);}
160 float muproj[recrays*views_in_set+1];
161 float atnproj[recrays*views_in_set];
162 float projdiff[recrays*views_in_set];
163 float numerator[imgsize], denominator[imgsize];
164 float med_img[imgsize], oslcoefs[imgsize];
165 int itercount=1;
166 do {
167 if(verbose>3) {printf(" iteration %d\n", itercount); fflush(stdout);}
168
169 if(verbose>1) {
170 float mi, ma;
171 fMinMaxFin(current_img, imgsize, &mi, &ma);
172 printf(" min=%g max=%g iter=%i\n", mi, ma, itercount);
173 for(int i=0; i<imgsize; i++)
174 if(!isfinite(current_img[i])) {
175 printf(" inf in current image! index=%d, iter=%d\n", i, itercount);
176 break;
177 }
178 }
179
180 for(int s=0; s<os_sets; s++) {
181 if(verbose>4) {printf(" os_set %d; seq=%d\n", 1+s, seq[s]); fflush(stdout);}
182 /* Image reprojection */
183 for(int i=0; i<recrays*views_in_set; i++) muproj[i]=0.0;
184#pragma omp parallel for
185 for(int i=0; i<views_in_set; i++) {
186 int view=seq[s]+i*os_sets;
187 if(verbose>8 && (i==0 || i==views_in_set-1)) printf(" reprojecting view %d\n", view);
188 viewReprojection(current_img, muproj+i*recrays, view, dim,
189 views, recrays, sinB, sinBrot, shiftX, shiftY, bp_zoom);
190 //re_proj(current_img, muproj+i*recrays, seq[s]+i*sets, dim, views);
191 }
192
193 /* Calculate correction = measured / re-projected */
194#pragma omp parallel for
195 for(int i=0; i<recrays*views_in_set; i++) {
196 float mup=muproj[i]*scale;
197 float est_count=expf(-mup)*recbla[i];
198 atnproj[i]=est_count*mup;
199 projdiff[i]=est_count - rectra[i];
200 }
201 /* Make numerator and denominator images */
202 for(int i=0; i<imgsize; i++) numerator[i]=0.0;
203 for(int i=0; i<imgsize; i++) denominator[i]=0.0;
204#pragma omp parallel for
205 for(int i=0; i<views_in_set; i++) {
206 int view=seq[s]+i*os_sets;
207 viewBackprojection(projdiff+i*recrays, numerator, dim,
208 view, views, recrays, sinB, sinBrot, shiftX, shiftY, bp_zoom);
209 viewBackprojection(atnproj+i*recrays, denominator, dim,
210 view, views, recrays, sinB, sinBrot, shiftX, shiftY, bp_zoom);
211 }
212 if(verbose>4) {
213 float mi, ma;
214 fMinMaxFin(numerator, imgsize, &mi, &ma);
215 printf(" numerator_range := %g - %g\n", mi, ma);
216 fMinMaxFin(denominator, imgsize, &mi, &ma);
217 printf(" denominator_range := %g - %g\n", mi, ma);
218 }
219
220 /* Apply the prior */
221 if(skip_prior<=0 && beta>0.0) {
222 if(verbose>3) {printf(" applying prior\n"); fflush(stdout);}
223 if(osl) {
224 float maxv, maxm;
225 fMinMaxFin(current_img, imgsize, NULL, &maxv);
226 do_prior(current_img, beta, oslcoefs, dim, 1.0E-08*maxv, maskdim, &maxm);
227 if(verbose>6) {
228 printf(" max value in current image := %g\n", maxv);
229 printf(" max median coefficient := %g\n", maxm);
230 }
231 } else {
232 float *iptr, *mptr;
233 if(maskdim==3) {
234 iptr=current_img+dim+1;
235 mptr=med_img+dim+1;
236 for(int i=2*(dim+1); i<imgsize; i++) *mptr++=med9(iptr++, dim);
237 } else if(maskdim==5) {
238 iptr=current_img+2*dim+2;
239 mptr=med_img+2*dim+2;
240 for(int i=2*(2*dim+2); i<imgsize; i++) *mptr++=med21(iptr++, dim);
241 }
242 for(int i=0; i<imgsize; i++) numerator[i]*=med_img[i];
243 for(int i=0; i<imgsize; i++) numerator[i]-=beta*(current_img[i]-med_img[i]);
244 for(int i=0; i<imgsize; i++) denominator[i]*=med_img[i];
245 for(int i=0; i<imgsize; i++) denominator[i]+=beta*current_img[i];
246 }
247 }
248 /* Calculate the next image */
249 if(verbose>3) {printf(" calculating next image\n"); fflush(stdout);}
250 if(osl && skip_prior<=0 && beta>0.0) { /* convex-OSL */
251 if(verbose>4) printf(" convex-OSL\n");
252 for(int i=0; i<imgsize; i++) {
253 float f=fmaf(numerator[i], 1.0/denominator[i], 1.0);
254 f*=oslcoefs[i];
255 f*=current_img[i];
256 if(isfinite(f)) current_img[i]=f;
257 }
258 } else { /* convex */
259 if(verbose>4) printf(" convex\n");
260 for(int i=0; i<imgsize; i++) {
261 float f=fmaf(numerator[i], 1.0/denominator[i], 1.0);
262 f*=current_img[i];
263 if(isfinite(f)) current_img[i]=f;
264 }
265 }
266 if(verbose>4) {printf(" -> next os_set maybe\n"); fflush(stdout);}
267 } // next set
268 itercount++; skip_prior--;
269 if(verbose>3) {printf(" -> next iteration maybe\n"); fflush(stdout);}
270 } while(itercount<iter);
271 if(verbose>2) {printf(" iterations done.\n"); fflush(stdout);}
272
273 for(int i=0; i<imgsize; i++) image[i]=current_img[i]*=scale;
274
275 if(verbose>1) {printf("trmrp() done.\n"); fflush(stdout);}
276 return(0);
277}
278/*****************************************************************************/
279
280/*****************************************************************************/
void fMinMaxFin(float *data, long long int n, float *fmin, float *fmax)
Definition imgminmax.c:649
Header file for libtpcrec.
void recSinTables(int views, float *sinB, float *sinBrot, float rotation)
Definition recutil.c:12
void viewBackprojection(float *prj, float *idata, int dim, int view, int viewNr, int rayNr, float *sinB, float *sinBrot, float offsX, float offsY, float bpZoom)
void viewReprojection(float *idata, float *sdata, int view, int dim, int viewNr, int rayNr, float *sinB, float *sinBrot, float offsX, float offsY, float bpZoom)
int trmrp(float *bla, float *tra, int dim, float *image, int iter, int sets, int rays, int views, int maskdim, float zoom, float beta, float axial_fov, float sample_distance, int skip_prior, int osl, float shiftX, float shiftY, float rotation, int verbose)
Definition trmrp.c:17
void recInterpolateSinogram(float *srcsino, float *newsino, int srcrays, int newrays, int views)
Definition recutil.c:37
float med21(float *inp, int dim)
Definition mrprior.c:49
void set_os_set(int os_sets, int *set_seq)
Definition recutil.c:113
float med9(float *inp, int dim)
Definition mrprior.c:15
void do_prior(float *img, float beta, float *med_coef, int dim, float small, int maskdim, float *maxm)
Definition mrprior.c:77