00001
00002 #ifndef vil3d_math_h_
00003 #define vil3d_math_h_
00004
00005
00006
00007
00008
00009 #include <vcl_cassert.h>
00010 #include <vcl_vector.h>
00011
00012 #include <vil3d/vil3d_image_view.h>
00013 #include <vil3d/vil3d_plane.h>
00014 #include <vcl_algorithm.h>
00015
00016
00017
00018
00019 template <class T>
00020 inline void vil3d_math_value_range(const vil3d_image_view<T>& im,
00021 T& min_value, T& max_value)
00022 {
00023 if (im.size()==0)
00024 {
00025 min_value = 0;
00026 max_value = 0;
00027 return;
00028 }
00029
00030 const T* plane = im.origin_ptr();
00031 min_value = *plane;
00032 max_value = min_value;
00033
00034 unsigned ni = im.ni();
00035 unsigned nj = im.nj();
00036 unsigned nk = im.nk();
00037 unsigned np = im.nplanes();
00038 vcl_ptrdiff_t istep = im.istep(), jstep=im.jstep(), kstep=im.kstep();
00039
00040 for (unsigned int p=0;p<np;++p, plane += im.planestep())
00041 {
00042 const T* slice = plane;
00043 for (unsigned int k=0;k<nk;++k, slice += kstep)
00044 {
00045 const T* row = slice;
00046 for (unsigned int j=0;j<nj;++j, row += jstep)
00047 {
00048 const T* pixel = row;
00049 for (unsigned int i=0;i<ni;++i, pixel+=istep)
00050 {
00051 if (*pixel<min_value) min_value = *pixel;
00052 else if (*pixel>max_value) max_value = *pixel;
00053 }
00054 }
00055 }
00056 }
00057 }
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 template <class T>
00070 inline void vil3d_math_value_range_percentile(const vil3d_image_view<T>& im,
00071 const double fraction,
00072 T& value)
00073 {
00074 vcl_vector<double> fractions(1, fraction);
00075 vcl_vector<T> values;
00076 vil3d_math_value_range_percentiles(im, fractions, values);
00077 if (values.size() > 0)
00078 value = values[0];
00079 }
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 template <class T>
00091 inline void vil3d_math_value_range_percentiles(const vil3d_image_view<T>& im,
00092 const vcl_vector<double> fraction,
00093 vcl_vector<T>& value)
00094 {
00095 value.clear();
00096
00097
00098 if (im.size()==0)
00099 {
00100 return;
00101 }
00102 unsigned nfrac = fraction.size();
00103 for (unsigned f=0; f<nfrac; ++f)
00104 {
00105 if (fraction[f]<0.0 || fraction[f]>1.0)
00106 return;
00107 }
00108
00109
00110 unsigned ni = im.ni();
00111 unsigned nj = im.nj();
00112 unsigned nk = im.nk();
00113 unsigned np = im.nplanes();
00114 vcl_ptrdiff_t istep = im.istep();
00115 vcl_ptrdiff_t jstep=im.jstep();
00116 vcl_ptrdiff_t kstep=im.kstep();
00117 vcl_ptrdiff_t pstep = im.planestep();
00118 vcl_vector<T> data(ni*nj*nk*np);
00119
00120 typename vcl_vector<T>::iterator it = data.begin();
00121 const T* plane = im.origin_ptr();
00122 for (unsigned int p=0;p<np;++p, plane += pstep)
00123 {
00124 const T* slice = plane;
00125 for (unsigned int k=0;k<nk;++k, slice += kstep)
00126 {
00127 const T* row = slice;
00128 for (unsigned int j=0;j<nj;++j, row += jstep)
00129 {
00130 const T* pixel = row;
00131 for (unsigned int i=0;i<ni;++i, pixel+=istep)
00132 {
00133 *it = *pixel;
00134 it++;
00135 }
00136 }
00137 }
00138 }
00139 unsigned npix = data.size();
00140
00141
00142 value.resize(nfrac);
00143 for (unsigned f=0; f<nfrac; ++f)
00144 {
00145 unsigned index = static_cast<unsigned>(fraction[f]*npix - 0.5);
00146 typename vcl_vector<T>::iterator index_it = data.begin() + index;
00147 vcl_nth_element(data.begin(), index_it, data.end());
00148 value[f] = *index_it;
00149 }
00150 }
00151
00152
00153
00154
00155 template<class aT, class sumT>
00156 inline void vil3d_math_mean_over_planes(const vil3d_image_view<aT>& src,
00157 vil3d_image_view<sumT>& dest)
00158 {
00159 dest.set_size(src.ni(), src.nj(), src.nk(), 1);
00160 for (unsigned k=0;k<src.nk();++k)
00161 for (unsigned j=0;j<src.nj();++j)
00162 for (unsigned i=0;i<src.ni();++i)
00163 {
00164 sumT sum=0;
00165 for (unsigned p=0;p<src.nplanes();++p)
00166 sum += (sumT) src(i,j,k,p);
00167 dest(i,j,k) = sum / src.nplanes();
00168 }
00169 }
00170
00171
00172
00173 template<class inT, class outT, class sumT>
00174 inline void vil3d_math_mean_over_planes(const vil3d_image_view<inT>& src,
00175 vil3d_image_view<outT>& dest,
00176 sumT )
00177 {
00178 dest.set_size(src.ni(), src.nj(), src.nk(), 1);
00179 for (unsigned k=0;k<src.nk();++k)
00180 for (unsigned j=0;j<src.nj();++j)
00181 for (unsigned i=0;i<src.ni();++i)
00182 {
00183 sumT sum=0;
00184 for (unsigned p=0;p<src.nplanes();++p)
00185 sum += static_cast<sumT>(src(i,j,k,p));
00186 dest(i,j,k) = static_cast<outT>(sum / src.nplanes());
00187 }
00188 }
00189
00190
00191
00192 template<class inT, class outT, class sumT>
00193 inline void vil3d_math_rms(const vil3d_image_view<inT>& src,
00194 vil3d_image_view<outT>& dest,
00195 sumT )
00196 {
00197 dest.set_size(src.ni(), src.nj(), src.nk(), 1);
00198 for (unsigned k=0;k<src.nk();++k)
00199 for (unsigned j=0;j<src.nj();++j)
00200 for (unsigned i=0;i<src.ni();++i)
00201 {
00202 sumT sum_sqr=0;
00203 for (unsigned p=0;p<src.nplanes();++p)
00204 sum_sqr += static_cast<sumT>(src(i,j,k,p))*static_cast<sumT>(src(i,j,k,p));
00205 dest(i,j,k) = static_cast<outT>(vcl_sqrt(sum_sqr / src.nplanes()));
00206 }
00207 }
00208
00209
00210
00211
00212 template <class imT, class sumT>
00213 inline void vil3d_math_sum(sumT& sum, const vil3d_image_view<imT>& im,
00214 unsigned p)
00215 {
00216 assert(p<im.nplanes());
00217 sum=0;
00218 if (im.size()==0)
00219 {
00220 return;
00221 }
00222
00223 const imT* plane = im.origin_ptr();
00224 unsigned ni = im.ni();
00225 unsigned nj = im.nj();
00226 unsigned nk = im.nk();
00227 vcl_ptrdiff_t istep = im.istep(), jstep=im.jstep(), kstep=im.kstep();
00228
00229 const imT* slice = plane + p*im.planestep();
00230 for (unsigned int k=0;k<nk;++k, slice += kstep)
00231 {
00232 const imT* row = slice;
00233 for (unsigned int j=0;j<nj;++j, row += jstep)
00234 {
00235 const imT* pixel = row;
00236 for (unsigned int i=0;i<ni;++i, pixel+=istep) sum += sumT(*pixel);
00237 }
00238 }
00239 }
00240
00241
00242
00243 template <class imT, class sumT>
00244 inline void vil3d_math_mean(sumT& mean, const vil3d_image_view<imT>& im,
00245 unsigned p)
00246 {
00247 if (im.size()==0) { mean=0; return; }
00248 vil3d_math_sum(mean,im,p);
00249 mean/=(im.ni()*im.nj()*im.nk());
00250 }
00251
00252
00253
00254
00255 template <class imT, class sumT>
00256 inline void vil3d_math_sum_squares(sumT& sum, sumT& sum_sq,
00257 const vil3d_image_view<imT>& im, unsigned p)
00258 {
00259 assert(p<im.nplanes());
00260 sum = 0; sum_sq=0;
00261 if (im.size()==0)
00262 {
00263 return;
00264 }
00265
00266 const imT* plane = im.origin_ptr();
00267 unsigned ni = im.ni();
00268 unsigned nj = im.nj();
00269 unsigned nk = im.nk();
00270 vcl_ptrdiff_t istep = im.istep(), jstep=im.jstep(), kstep=im.kstep();
00271
00272 const imT* slice = plane + p*im.planestep();
00273 for (unsigned int k=0;k<nk;++k, slice += kstep)
00274 {
00275 const imT* row = slice;
00276 for (unsigned int j=0;j<nj;++j, row += jstep)
00277 {
00278 const imT* r = row;
00279 for (unsigned int i=0;i<ni;++i, r+=istep)
00280 { sum += *r; sum_sq+=sumT(*r)*sumT(*r); }
00281 }
00282 }
00283 }
00284
00285
00286
00287
00288 template <class imT, class sumT>
00289 inline sumT vil3d_math_ssd(const vil3d_image_view<imT>& imA,
00290 const vil3d_image_view<imT>& imB, sumT )
00291 {
00292 assert(imA.ni() == imB.ni() && imB.nj() == imB.nj() &&
00293 imB.nk() == imB.nk() && imA.nplanes() == imB.nplanes());
00294 sumT ssd=0;
00295 for (unsigned p=0;p<imA.nplanes();++p)
00296 for (unsigned k=0;k<imA.nk();++k)
00297 for (unsigned j=0;j<imA.nj();++j)
00298 for (unsigned i=0;i<imA.ni();++i)
00299 {
00300 const sumT v = ((sumT)imA(i,j,k,p) - (sumT)imB(i,j,k,p));
00301 ssd += v*v;
00302 }
00303 return ssd;
00304 }
00305
00306
00307
00308
00309 template<class imT, class offsetT>
00310 inline void vil3d_math_scale_and_offset_values(vil3d_image_view<imT>& image,
00311 double scale, offsetT offset)
00312 {
00313 unsigned ni = image.ni(), nj = image.nj(),
00314 nk = image.nk(), np = image.nplanes();
00315 vcl_ptrdiff_t istep=image.istep(), jstep=image.jstep(),
00316 kstep = image.kstep(), pstep = image.planestep();
00317 imT* plane = image.origin_ptr();
00318 for (unsigned p=0;p<np;++p,plane += pstep)
00319 {
00320 imT* slice = plane;
00321 for (unsigned k=0;k<nk;++k,slice += kstep)
00322 {
00323 imT* row = slice;
00324 for (unsigned j=0;j<nj;++j,row += jstep)
00325 {
00326 imT* pixel = row;
00327 for (unsigned i=0;i<ni;++i,pixel+=istep)
00328 *pixel = imT(scale*(*pixel)+offset);
00329 }
00330 }
00331 }
00332 }
00333
00334
00335
00336
00337 template <class imT, class sumT>
00338 inline void vil3d_math_mean_and_variance(sumT& mean, sumT& var,
00339 const vil3d_image_view<imT>& im,
00340 unsigned p)
00341 {
00342 if (im.size()==0) { mean=0; var=0; return; }
00343 sumT sum, sum_sq;
00344 vil3d_math_sum_squares(sum,sum_sq,im,p);
00345 mean = sum/(im.ni()*im.nj()*im.nk());
00346 var = sum_sq/(im.ni()*im.nj()*im.nk()) - mean*mean;
00347 }
00348
00349
00350
00351
00352 template <class imT, class sumT>
00353 inline sumT vil3d_math_dot_product(const vil3d_image_view<imT>& imA,
00354 const vil3d_image_view<imT>& imB, sumT)
00355 {
00356 assert(imA.ni() == imB.ni() && imB.nj() == imB.nj() &&
00357 imB.nk() == imB.nk() && imA.nplanes() == imB.nplanes());
00358 sumT dp=0;
00359 for (unsigned p=0;p<imA.nplanes();++p)
00360 for (unsigned k=0;k<imA.nk();++k)
00361 for (unsigned j=0;j<imA.nj();++j)
00362 for (unsigned i=0;i<imA.ni();++i)
00363 dp += (sumT)imA(i,j,k,p) * (sumT)imB(i,j,k,p);
00364 return dp;
00365 }
00366
00367
00368
00369
00370 template<class aT, class bT, class sumT>
00371 inline void vil3d_math_image_difference(const vil3d_image_view<aT>& imA,
00372 const vil3d_image_view<bT>& imB,
00373 vil3d_image_view<sumT>& im_sum)
00374 {
00375 unsigned ni = imA.ni(),nj = imA.nj(),nk = imA.nk(),np = imA.nplanes();
00376 assert(imB.ni()==ni && imB.nj()==nj && imB.nk()==nk && imB.nplanes()==np);
00377 im_sum.set_size(ni,nj,nk,np);
00378
00379 vcl_ptrdiff_t istepA=imA.istep(),jstepA=imA.jstep(),kstepA=imA.kstep(),pstepA = imA.planestep();
00380 vcl_ptrdiff_t istepB=imB.istep(),jstepB=imB.jstep(),kstepB=imB.kstep(),pstepB = imB.planestep();
00381 vcl_ptrdiff_t istepS=im_sum.istep(),jstepS=im_sum.jstep(),kstepS=im_sum.kstep(),pstepS = im_sum.planestep();
00382 const aT* planeA = imA.origin_ptr();
00383 const bT* planeB = imB.origin_ptr();
00384 sumT* planeS = im_sum.origin_ptr();
00385 for (unsigned p=0;p<np;++p,planeA += pstepA,planeB += pstepB,planeS += pstepS)
00386 {
00387 const aT* sliceA = planeA;
00388 const bT* sliceB = planeB;
00389 sumT* sliceS = planeS;
00390 for (unsigned k=0;k<nk;++k,sliceA += kstepA,sliceB += kstepB,sliceS += kstepS)
00391 {
00392 const aT* rowA = sliceA;
00393 const bT* rowB = sliceB;
00394 sumT* rowS = sliceS;
00395 for (unsigned j=0;j<nj;++j,rowA += jstepA,rowB += jstepB,rowS += jstepS)
00396 {
00397 const aT* pixelA = rowA;
00398 const bT* pixelB = rowB;
00399 sumT* pixelS = rowS;
00400 for (unsigned i=0;i<ni;++i,pixelA+=istepA,pixelB+=istepB,pixelS+=istepS)
00401 *pixelS = sumT(*pixelA)-sumT(*pixelB);
00402 }
00403 }
00404 }
00405 }
00406
00407
00408
00409 template<class aT, class bT, class sumT>
00410 inline void vil3d_math_image_sum(const vil3d_image_view<aT>& imA,
00411 const vil3d_image_view<bT>& imB,
00412 vil3d_image_view<sumT>& im_sum)
00413 {
00414 unsigned ni = imA.ni(),nj = imA.nj(),nk = imA.nk(),np = imA.nplanes();
00415 assert(imB.ni()==ni && imB.nj()==nj && imB.nk()==nk && imB.nplanes()==np);
00416 im_sum.set_size(ni,nj,nk,np);
00417
00418 vcl_ptrdiff_t istepA=imA.istep(),jstepA=imA.jstep(),kstepA=imA.kstep(),pstepA = imA.planestep();
00419 vcl_ptrdiff_t istepB=imB.istep(),jstepB=imB.jstep(),kstepB=imB.kstep(),pstepB = imB.planestep();
00420 vcl_ptrdiff_t istepS=im_sum.istep(),jstepS=im_sum.jstep(),kstepS=im_sum.kstep(),pstepS = im_sum.planestep();
00421 const aT* planeA = imA.origin_ptr();
00422 const bT* planeB = imB.origin_ptr();
00423 sumT* planeS = im_sum.origin_ptr();
00424 for (unsigned p=0;p<np;++p,planeA += pstepA,planeB += pstepB,planeS += pstepS)
00425 {
00426 const aT* sliceA = planeA;
00427 const bT* sliceB = planeB;
00428 sumT* sliceS = planeS;
00429 for (unsigned k=0;k<nk;++k,sliceA += kstepA,sliceB += kstepB,sliceS += kstepS)
00430 {
00431 const aT* rowA = sliceA;
00432 const bT* rowB = sliceB;
00433 sumT* rowS = sliceS;
00434 for (unsigned j=0;j<nj;++j,rowA += jstepA,rowB += jstepB,rowS += jstepS)
00435 {
00436 const aT* pixelA = rowA;
00437 const bT* pixelB = rowB;
00438 sumT* pixelS = rowS;
00439 for (unsigned i=0;i<ni;++i,pixelA+=istepA,pixelB+=istepB,pixelS+=istepS)
00440 *pixelS = sumT(*pixelA)+sumT(*pixelB);
00441 }
00442 }
00443 }
00444 }
00445
00446
00447
00448 template<class aT, class bT, class prodT>
00449 inline void vil3d_math_image_product(const vil3d_image_view<aT>& imA,
00450 const vil3d_image_view<bT>& imB,
00451 vil3d_image_view<prodT>& im_prod)
00452 {
00453 unsigned ni = imA.ni(),nj = imA.nj(),nk = imA.nk(),np = imA.nplanes();
00454 assert(imB.ni()==ni && imB.nj()==nj && imB.nk()==nk && imB.nplanes()==np);
00455 im_prod.set_size(ni,nj,nk,np);
00456
00457 vcl_ptrdiff_t istepA=imA.istep(),jstepA=imA.jstep(),kstepA=imA.kstep(),pstepA = imA.planestep();
00458 vcl_ptrdiff_t istepB=imB.istep(),jstepB=imB.jstep(),kstepB=imB.kstep(),pstepB = imB.planestep();
00459 vcl_ptrdiff_t istepS=im_prod.istep(),jstepS=im_prod.jstep(),kstepS=im_prod.kstep(),pstepS = im_prod.planestep();
00460 const aT* planeA = imA.origin_ptr();
00461 const bT* planeB = imB.origin_ptr();
00462 prodT* planeS = im_prod.origin_ptr();
00463 for (unsigned p=0;p<np;++p,planeA += pstepA,planeB += pstepB,planeS += pstepS)
00464 {
00465 const aT* sliceA = planeA;
00466 const bT* sliceB = planeB;
00467 prodT* sliceS = planeS;
00468 for (unsigned k=0;k<nk;++k,sliceA += kstepA,sliceB += kstepB,sliceS += kstepS)
00469 {
00470 const aT* rowA = sliceA;
00471 const bT* rowB = sliceB;
00472 prodT* rowS = sliceS;
00473 for (unsigned j=0;j<nj;++j,rowA += jstepA,rowB += jstepB,rowS += jstepS)
00474 {
00475 const aT* pixelA = rowA;
00476 const bT* pixelB = rowB;
00477 prodT* pixelS = rowS;
00478 for (unsigned i=0;i<ni;++i,pixelA+=istepA,pixelB+=istepB,pixelS+=istepS)
00479 *pixelS = prodT(*pixelA)*prodT(*pixelB);
00480 }
00481 }
00482 }
00483 }
00484
00485
00486
00487
00488
00489
00490 template<class aT, class bT, class scaleT>
00491 inline void vil3d_math_add_image_fraction(vil3d_image_view<aT>& imA, scaleT fa,
00492 const vil3d_image_view<bT>& imB, scaleT fb)
00493 {
00494 unsigned ni = imA.ni(),nj = imA.nj(),nk = imA.nk(),np = imA.nplanes();
00495 assert(imB.ni()==ni && imB.nj()==nj && imB.nk()==nk && imB.nplanes()==np);
00496
00497 vcl_ptrdiff_t istepA=imA.istep(),jstepA=imA.jstep(),kstepA=imA.kstep(),pstepA = imA.planestep();
00498 vcl_ptrdiff_t istepB=imB.istep(),jstepB=imB.jstep(),kstepB=imB.kstep(),pstepB = imB.planestep();
00499 aT* planeA = imA.origin_ptr();
00500 const bT* planeB = imB.origin_ptr();
00501 for (unsigned p=0;p<np;++p,planeA += pstepA,planeB += pstepB)
00502 {
00503 aT* sliceA = planeA;
00504 const bT* sliceB = planeB;
00505 for (unsigned k=0;k<nk;++k,sliceA += kstepA,sliceB += kstepB)
00506 {
00507 aT* rowA = sliceA;
00508 const bT* rowB = sliceB;
00509 for (unsigned j=0;j<nj;++j,rowA += jstepA,rowB += jstepB)
00510 {
00511 aT* pixelA = rowA;
00512 const bT* pixelB = rowB;
00513 for (unsigned i=0;i<ni;++i,pixelA+=istepA,pixelB+=istepB)
00514 *pixelA = aT(fa*(*pixelA)+fb*(*pixelB));
00515 }
00516 }
00517 }
00518 }
00519
00520
00521
00522
00523
00524 template<class T>
00525 inline void vil3d_math_truncate_range(vil3d_image_view<T>& image,
00526 T min_v, T max_v)
00527 {
00528 unsigned ni=image.ni(), nj=image.nj(), nk=image.nk(), np=image.nplanes();
00529 vcl_ptrdiff_t istep=image.istep(), jstep=image.jstep(),
00530 kstep=image.kstep(), pstep=image.planestep();
00531 T* plane = image.origin_ptr();
00532 for (unsigned p=0; p<np; ++p, plane+=pstep)
00533 {
00534 T* slice = plane;
00535 for (unsigned k=0; k<nk; ++k, slice+=kstep)
00536 {
00537 T* row = slice;
00538 for (unsigned j=0; j<nj; ++j, row+=jstep)
00539 {
00540 T* pixel = row;
00541 for (unsigned i=0; i<ni; ++i, pixel+=istep)
00542 {
00543 if (*pixel<min_v) *pixel=min_v;
00544 else if (*pixel>max_v) *pixel=max_v;
00545 }
00546 }
00547 }
00548 }
00549 }
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559 template<class aT, class sumT>
00560 inline void vil3d_math_integral_image(const vil3d_image_view<aT>& imA,
00561 vil3d_image_view<sumT>& im_sum)
00562 {
00563 assert(imA.nplanes()==1);
00564 unsigned ni = imA.ni(),nj = imA.nj(),nk = imA.nk();
00565 unsigned ni1=ni+1;
00566 unsigned nj1=nj+1;
00567 unsigned nk1=nk+1;
00568 im_sum.set_size(ni1,nj1,nk1,1);
00569
00570
00571 vcl_ptrdiff_t istepS=im_sum.istep();
00572 vcl_ptrdiff_t jstepS=im_sum.jstep();
00573 vcl_ptrdiff_t kstepS=im_sum.kstep();
00574 sumT* planeS = im_sum.origin_ptr();
00575 sumT* rowS = planeS;
00576 sumT* voxelS;
00577 for (unsigned j=0;j<nj1;++j,rowS += jstepS)
00578 {
00579 voxelS = rowS;
00580 for (unsigned i=0;i<ni1;++i,voxelS+=istepS)
00581 *voxelS=0;
00582 }
00583
00584
00585 vcl_ptrdiff_t istepA=imA.istep();
00586 vcl_ptrdiff_t jstepA=imA.jstep();
00587 vcl_ptrdiff_t kstepA=imA.kstep();
00588
00589 const aT* planeA = imA.origin_ptr();
00590
00591 sumT sum;
00592 vcl_ptrdiff_t prev_j = -jstepS;
00593 vcl_ptrdiff_t prev_k = -kstepS;
00594 planeS += kstepS;
00595
00596
00597 for (unsigned k=0;k<nk;++k,planeA += kstepA,planeS += kstepS)
00598 {
00599 const aT* rowA = planeA;
00600 rowS = planeS;
00601
00602
00603 voxelS = rowS;
00604 for (unsigned i=0;i<ni1;++i,voxelS += istepS)
00605 *voxelS = 0;
00606 rowS += jstepS;
00607
00608
00609 for (unsigned j=0;j<nj;++j,rowA += jstepA,rowS += jstepS)
00610 {
00611 const aT* voxelA = rowA;
00612 voxelS = rowS;
00613 sum = 0;
00614
00615
00616 *voxelS = 0;
00617 voxelS += istepS;
00618
00619
00620 for (unsigned i=1; i<ni1;++i,voxelA+=istepA,voxelS+=istepS)
00621 {
00622 sum += *voxelA;
00623 *voxelS = sum + voxelS[prev_j];
00624 }
00625 }
00626 }
00627
00628
00629
00630 planeS = im_sum.origin_ptr() + 2*kstepS;
00631 for (unsigned k=2;k<nk1;k++,planeS += kstepS)
00632 {
00633
00634 rowS = planeS+jstepS;
00635 for (unsigned j=1;j<nj1;j++,rowS += jstepS)
00636 {
00637
00638 voxelS = rowS+istepS;
00639 for (unsigned i=1;i<ni1;i++,voxelS += istepS)
00640 *voxelS += voxelS[prev_k];
00641 }
00642 }
00643
00644 }
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656 template<class aT, class sumT>
00657 inline void vil3d_math_integral_sqr_image(const vil3d_image_view<aT>& imA,
00658 vil3d_image_view<sumT>& im_sum,
00659 vil3d_image_view<sumT>& im_sum_sq)
00660 {
00661 assert(imA.nplanes()==1);
00662 unsigned ni = imA.ni(),nj = imA.nj(),nk = imA.nk();
00663 unsigned ni1=ni+1;
00664 unsigned nj1=nj+1;
00665 unsigned nk1=nk+1;
00666 im_sum.set_size(ni1,nj1,nk1,1);
00667 im_sum_sq.set_size(ni1,nj1,nk1,1);
00668
00669
00670 vcl_ptrdiff_t istepS=im_sum.istep();
00671 vcl_ptrdiff_t istepS2=im_sum_sq.istep();
00672 vcl_ptrdiff_t jstepS=im_sum.jstep();
00673 vcl_ptrdiff_t jstepS2=im_sum_sq.jstep();
00674 vcl_ptrdiff_t kstepS=im_sum.kstep();
00675 vcl_ptrdiff_t kstepS2=im_sum_sq.kstep();
00676 sumT* planeS = im_sum.origin_ptr();
00677 sumT* planeS2 = im_sum_sq.origin_ptr();
00678 sumT* rowS = planeS;
00679 sumT* rowS2 = planeS2;
00680 sumT *voxelS, *voxelS2;
00681
00682
00683 for (unsigned j=0;j<nj1;++j,rowS += jstepS)
00684 {
00685 voxelS = rowS;
00686 for (unsigned i=0;i<ni1;++i,voxelS+=istepS)
00687 *voxelS=0;
00688 }
00689
00690
00691 for (unsigned j=0;j<nj1;++j,rowS2 += jstepS2)
00692 {
00693 voxelS2 = rowS2;
00694 for (unsigned i=0;i<ni1;++i,voxelS2+=istepS2)
00695 *voxelS2=0;
00696 }
00697
00698
00699 vcl_ptrdiff_t istepA=imA.istep();
00700 vcl_ptrdiff_t jstepA=imA.jstep();
00701 vcl_ptrdiff_t kstepA=imA.kstep();
00702
00703 const aT* planeA = imA.origin_ptr();
00704
00705 sumT sum, sum2;
00706 vcl_ptrdiff_t prev_j = -jstepS;
00707 vcl_ptrdiff_t prev_k = -kstepS;
00708 vcl_ptrdiff_t prev_j2 = -jstepS2;
00709 vcl_ptrdiff_t prev_k2 = -kstepS2;
00710 planeS += kstepS;
00711 planeS2 += kstepS2;
00712
00713
00714 for (unsigned k=0;k<nk;++k,planeA+=kstepA,planeS+=kstepS,planeS2+=kstepS2)
00715 {
00716 const aT* rowA = planeA;
00717 rowS = planeS;
00718 rowS2 = planeS2;
00719
00720
00721 voxelS = rowS;
00722 voxelS2 = rowS2;
00723 for (unsigned i=0;i<ni1;++i,voxelS += istepS, voxelS2 += istepS2)
00724 {
00725 *voxelS = 0;
00726 *voxelS2 = 0;
00727 }
00728 rowS += jstepS;
00729 rowS2 += jstepS2;
00730
00731
00732 for (unsigned j=0;j<nj;++j,rowA += jstepA,rowS += jstepS,rowS2+=jstepS2)
00733 {
00734 const aT* voxelA = rowA;
00735 voxelS = rowS;
00736 voxelS2 = rowS2;
00737 sum = 0;
00738 sum2 = 0;
00739
00740
00741 *voxelS = 0;
00742 *voxelS2 = 0;
00743 voxelS += istepS;
00744 voxelS2 += istepS2;
00745
00746
00747 for (unsigned i=1;i<ni1;++i,voxelA+=istepA,
00748 voxelS+=istepS,voxelS2+=istepS2)
00749 {
00750 sum += *voxelA;
00751 *voxelS = sum + voxelS[prev_j];
00752 sum2 += sumT(*voxelA)*sumT(*voxelA);
00753 *voxelS2 = sum2 + voxelS2[prev_j2];
00754 }
00755 }
00756 }
00757
00758
00759
00760 planeS = im_sum.origin_ptr() + 2*kstepS;
00761 planeS2 = im_sum_sq.origin_ptr() + 2*kstepS2;
00762 for (unsigned k=2;k<nk1;k++,planeS += kstepS, planeS2 += kstepS2)
00763 {
00764
00765 rowS = planeS+jstepS;
00766 rowS2 = planeS2+jstepS2;
00767 for (unsigned j=1;j<nj1;j++,rowS += jstepS,rowS2 += jstepS2)
00768 {
00769
00770 voxelS = rowS+istepS;
00771 voxelS2 = rowS2+istepS2;
00772 for (unsigned i=1;i<ni1;i++,voxelS += istepS,voxelS2 += istepS2)
00773 {
00774 *voxelS += voxelS[prev_k];
00775 *voxelS2 += voxelS2[prev_k2];
00776 }
00777 }
00778 }
00779
00780 }
00781
00782
00783 #endif