2 ***********************************************************
3 $SNARK_Header: S N A R K 1 4 - A PICTURE RECONSTRUCTION PROGRAM $
4 $HeadURL: svn://dig.cs.gc.cuny.edu/snark/trunk/src/snark/pix2blob.cpp $
5 $LastChangedRevision: 80 $
6 $Date: 2014-07-01 21:01:54 -0400 (Tue, 01 Jul 2014) $
8 ***********************************************************
11 /* This subroutine converts an image function in pixel basis into that in blob basis. This subroutine uses SIRT type algorithm with blob footprints for speeding up. See subroutine blob2pix() for the meaning of various variables.
25 void Blob_class::pix2blob(REAL* pict, REAL* blob_array)
28 INTEGER i, k, j, ii, kk, jj;
37 REAL ipixsiz = (REAL) 1.0 / GeoPar.pixsiz;
38 INTEGER count, ncount;
39 REAL maxpict, minpict;
50 frelax = 2.0; //changed on 4/8/04, from 1.0 to 2.0, as suggested by Laszlo
57 frelax *= GeoPar.pixsiz * GeoPar.pixsiz
58 / (Consts.pi * Blob.support * Blob.support);
59 frelax = MIN0(2.0, frelax); //frelax param cannot be greater than 2 !
61 REAL *u = new REAL[GeoPar.area]; //art4 dual var
62 REAL *Delta = new REAL[GeoPar.area]; //art4 epsilon
63 REAL *Gamma = new REAL[GeoPar.area]; //art4 epsilon
64 INTEGER *que = new INTEGER[GeoPar.area]; //art4
66 INTEGER pow2, num_dig;
67 INTEGER *decomp = NULL;
68 INTEGER *base = NULL; //wei 3/2005
69 INTEGER *old_numk, *new_numk;
70 INTEGER *old_numj, *new_numj;
72 H2 = (INTEGER) (Blob.H / 2);
73 M2 = (INTEGER) (Blob.M / 2);
74 nelem2 = (INTEGER) (GeoPar.nelem / 2);
76 //get the decomposition of the smallest power of 2 >= nelem
79 while (pow2 < GeoPar.nelem)
84 factorization(pow2, &decomp, &num_dig);
85 get_base(decomp, num_dig, &base);
86 old_numk = new INTEGER[num_dig];
87 new_numk = new INTEGER[num_dig];
88 old_numj = new INTEGER[num_dig];
89 new_numj = new INTEGER[num_dig];
91 // initialising the blobs with the value of the nearest pixel and computing mod2 using BLOB footprint
93 for (h = lhf; h <= lhl; h++)
95 for (m = lmf; m <= lml; m++)
96 { // m and h must have the same parity!!
102 indb = h1 * Blob.M + m1;
104 xc = di2 * m; // coord of the center of the blob (m,h)
108 jx = (INTEGER) floor(ipixsiz * xc + 0.5); // coord of the center of
109 ky = (INTEGER) floor(auy + 0.5); // the nearest pixel
111 jc = jx + nelem2; // bring to the right address
112 kc = (INTEGER) floor(-auy + 0.5) + nelem2;
124 blob_array[indb] = pict[kc * GeoPar.nelem + jc];
129 //initialize dual var and finding the max amplitud between pict and 0
130 maxpict = -Consts.infin;
131 minpict = Consts.infin;
132 for (k = 0; k < GeoPar.nelem; k++)
134 for (j = 0; j < GeoPar.nelem; j++)
136 ind = k * GeoPar.nelem + j;
137 if (maxpict < pict[ind])
141 if (minpict > pict[ind])
148 amppict = MAX0(maxpict,0.0) - MIN0(minpict, 0.0);
150 //computing delta and gamma of ART4
151 for (k = 0; k < GeoPar.nelem; k++)
153 for (j = 0; j < GeoPar.nelem; j++)
155 ind = k * GeoPar.nelem + j;
156 p2b_neighb(k, j, pict, &nc, rneigh);
159 Delta[ind] = unif * amppict;
160 Gamma[ind] = -(tau * fabs(pict[ind] - nc) + unif * amppict);
164 Delta[ind] = tau * fabs(pict[ind] - nc) + unif * amppict;
165 Gamma[ind] = -unif * amppict;
173 //initializing list "que" and count
176 for (kk = 0; kk < pow2; kk++)
178 pi_map(num_dig, decomp, base, &old_numk, &new_numk, &k);
179 if (k < GeoPar.nelem)
182 for (jj = 0; jj < pow2; jj++)
184 pi_map(num_dig, decomp, base, &old_numj, &new_numj, &j);
185 if (j < GeoPar.nelem)
187 ind = k * GeoPar.nelem + j;
194 //ART4-type algorithm
198 Correct(pict, blob_array, u, Delta, Gamma, que, count, &ncount, &sd,
202 if (count == 0 || i >= niter)
207 if (ii == 0 || i >= niter)
211 delete[] old_numk; // bug 92 - Lajos - 03/02/2005
212 delete[] new_numk; // bug 92 - Lajos - 03/02/2005
213 delete[] old_numj; // bug 92 - Lajos - 03/02/2005
214 delete[] new_numj; // bug 92 - Lajos - 03/02/2005
215 delete[] u; // bug 92 - Lajos - 03/02/2005
216 delete[] Delta; // bug 92 - Lajos - 03/02/2005
217 delete[] Gamma; // bug 92 - Lajos - 03/02/2005
218 delete[] que; // bug 92 - Lajos - 03/02/2005
222 delete[] base; //wei 3/2005
227 void Blob_class::Correct(REAL* pict, REAL* blob_array, REAL* u, REAL* Delta,
228 REAL* Gamma, INTEGER* que, INTEGER count, INTEGER* ncount, REAL* sd,
229 REAL width, REAL frelax)
236 INTEGER multp = (INTEGER) floor(Blob.support / Blob.delta + 0.5) + 1;
237 INTEGER npts = 4 * multp * multp;
238 INTEGER *list = new INTEGER[npts];
240 REAL *weight = new REAL[npts];
250 for (c = 0; c < count; c++)
254 k = ind / GeoPar.nelem;
255 j = ind % GeoPar.nelem;
256 bpix(k, j, list, weight, &numb, &snorm);
259 for (g = 0; g < numb; g++)
262 sum += blob_array[indb] * weight[g];
264 diff = pict[ind] - sum;
265 (*sd) += (diff * diff);
266 if (!(diff <= -width * Gamma[ind])
267 || !(diff >= -width * Delta[ind])) //Ran bug 235 August 17, 2008
269 que[(*ncount)] = ind;
272 lowb = frelax * (diff + Gamma[ind]) / snorm;
273 uppb = frelax * (diff + Delta[ind]) / snorm;
274 ck = MAX0(MIN0(uppb, u[ind]), lowb);
276 // updates of dual var
278 // backward operation with relaxation param relax
279 for (g = 0; g < numb; g++)
282 blob_array[indb] += (ck * weight[g]);
287 delete[] list; // bug 92 - Lajos - 03/02/2005
288 delete[] weight; // bug 92 - Lajos - 03/02/2005
292 void Blob_class::p2b_neighb(INTEGER k, INTEGER j, REAL* pict, REAL *nc,
299 REAL mult = rneigh * Blob.support / GeoPar.pixsiz;
300 INTEGER multn = (INTEGER) ceil(mult);
305 for (m = -multn; m <= multn; m++)
307 for (n = -multn; n <= multn; n++)
309 if ((n * n + m * m) <= (mult * mult))
315 for (m = -multn; m <= multn; m++)
318 if (kk >= 0 && kk < GeoPar.nelem)
320 for (n = -multn; n <= multn; n++)
323 if (jj >= 0 && jj < GeoPar.nelem)
325 if ((n * n + m * m) <= (mult * mult))
327 ind = kk * GeoPar.nelem + jj;
334 (*nc) /= (REAL) size;