TPCCLIB
Loading...
Searching...
No Matches
trmrp.c File Reference

Transmission image reconstruction using MRP. More...

#include "libtpcrec.h"

Go to the source code of this file.

Functions

int trmrp (float *bla, float *tra, int dim, float *image, int iter, int os_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)

Detailed Description

Transmission image reconstruction using MRP.

Remarks
Based on the program fbprec (Feb 1998) written by Sakari Alenius for Sun UNIX workstations.
Author
Vesa Oikonen

Definition in file trmrp.c.

Function Documentation

◆ trmrp()

int trmrp ( float * bla,
float * tra,
int dim,
float * image,
int iter,
int os_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 )

Median Root Prior (MRP) reconstruction of one 2D data matrix given as an array of floats.

See also
fbp, reprojection
Returns
Returns 0 if ok.
Parameters
blaFloat array containing rays*views blank sinogram values. Data must be normalization-corrected.
traFloat array containing rays*views transmission sinogram values. Data must be normalization-corrected.
dimImage x and y dimensions.
imagePointer to pre-allocated image data; size must be at least dim*dim; log-transformed attenuation correction factors will be written in here.
iterNr of iterations.
os_setsLength of ordered subset process order array; 1, 2, 4, ... 128.
raysNr of rays (bins or columns) in sinogram data.
viewsNr of views (rows) in sinogram data.
maskdimMask dimension; 3 or 5 (9 or 21 pixels).
zoomReconstruction zoom.
betaBeta.
axial_fovAxial field-of-view in mm (found in transmission mainheader in cm).
sample_distanceSample distance in mm (found in transmission subheader in cm).
skip_priorNumber of iteration before prior; usually 1.
oslUse OSL-type (0 or 1).
shiftXPossible shifting in x dimension (mm).
shiftYPossible shifting in y dimension (mm).
rotationPossible image rotation, -180 - +180 (in degrees).
verboseVerbose level; if zero, then nothing is printed to stderr or stdout.

Definition at line 17 of file trmrp.c.

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}
void fMinMaxFin(float *data, long long int n, float *fmin, float *fmax)
Definition imgminmax.c:649
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)
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

Referenced by atnMake(), and trmrp().