core/vbl/vbl_local_minima.txx
Go to the documentation of this file.
00001 #ifndef VBL_LOCAL_MINIMA_TXX_
00002 #define VBL_LOCAL_MINIMA_TXX_
00003 #include "vbl_local_minima.h"
00004 //
00005 #include <vcl_iostream.h>
00006 #include <vcl_limits.h>
00007 #include <vcl_cassert.h>
00008 
00009 template <class T>
00010 bool local_minima(vbl_array_1d<T> const& in, vbl_array_1d<T>& minima, T thresh)
00011 {
00012   const unsigned int n = (unsigned int)(in.size());
00013   assert(minima.size()==n);
00014   //special cases
00015   // minimum is not defined for n<3
00016   if (n<3)
00017     return false;
00018   bool minima_found = false;
00019   for (unsigned int i=0; i<n; ++i)
00020     minima[i] = T(0);
00021   //the general case
00022   for (unsigned int c=1; c<n-1; ++c) {
00023     T dm = in[c-1]-in[c], dp = in[c+1]-in[c];
00024     if (dm>thresh && dp > thresh) {
00025       T dmin = dm;
00026       if (dp<dmin)
00027         dmin = dp;
00028       minima[c]=dmin;
00029       minima_found = true;
00030     }
00031   }
00032   // Check the ends of the array for minima
00033   // left end
00034   if ((in[1]-in[0])>thresh) {
00035     minima[0]=in[1]-in[0];
00036     minima_found = true;
00037   }
00038   // right end
00039   if ((in[n-2]-in[n-1])>thresh) {
00040     minima[n-1]=in[n-2]-in[n-1];
00041     minima_found = true;
00042   }
00043 
00044   return minima_found;
00045 }
00046 
00047 template <class T>
00048 bool local_minima(vbl_array_2d<T> const& in, vbl_array_2d<T>& minima, T thresh)
00049 {
00050   const unsigned int nr = (unsigned int)(in.rows()), nc = (unsigned int)(in.cols());
00051   assert(nr==minima.rows() && nc==minima.cols());
00052   //special case
00053   // actually a 1-d array or null
00054   if (nr<2||nc<2)
00055     return false;
00056   bool  minima_found = false;
00057   T mval = vcl_numeric_limits<T>::max();
00058   for (unsigned r = 0; r<nr; ++r)
00059     for (unsigned c = 0; c<nc; ++c)
00060       minima[r][c] = T(0);
00061   T ul,  um, ur;
00062   T lf,/*m,*/ri;
00063   T ll,  lm, lr;
00064   T dmin;
00065   //general case
00066   if (nr>2&&nc>2)
00067     for (unsigned r = 1; r<nr-1; ++r)
00068       for (unsigned c = 1; c<nc-1; ++c) {
00069         // xxxxxxxxxxxxxxxxxxxxxxx
00070         // xxxx   ul um  ur  xxxxx
00071         // xxxx   lf  m  ri  xxxxx
00072         // xxxx   ll lm  lr  xxxxx
00073         // xxxxxxxxxxxxxxxxxxxxxxx
00074         ul = in[r-1][c-1] - in[r][c];
00075         um = in[r-1][c]   - in[r][c];
00076         ur = in[r-1][c]   - in[r][c];
00077         lf = in[r][c-1]   - in[r][c];
00078         ri = in[r][c+1]   - in[r][c];
00079         ll = in[r+1][c-1] - in[r][c];
00080         lm = in[r+1][c]   - in[r][c];
00081         lr = in[r+1][c+1] - in[r][c];
00082         dmin = mval;
00083         if (ul<=thresh) continue; if (ul<dmin) dmin = ul;
00084         if (um<=thresh) continue; if (um<dmin) dmin = um;
00085         if (ur<=thresh) continue; if (ur<dmin) dmin = ur;
00086         if (lf<=thresh) continue; if (lf<dmin) dmin = lf;
00087         if (ri<=thresh) continue; if (ri<dmin) dmin = ri;
00088         if (ll<=thresh) continue; if (ll<dmin) dmin = ll;
00089         if (lm<=thresh) continue; if (lm<dmin) dmin = lm;
00090         if (lr<=thresh) continue; if (lr<dmin) dmin = lr;
00091         if (dmin>thresh) {
00092           minima[r][c] = dmin;
00093           minima_found = true;
00094         }
00095       }
00096 
00097   // special cases at the borders
00098   if (nc>2) {
00099     for (unsigned c = 1; c<nc-1; ++c) {
00100       // first row case
00101       // xxxx   lf  m  ri  xxxxx
00102       // xxxx   ll lm  lr  xxxxx
00103       // xxxxxxxxxxxxxxxxxxxxxxx
00104       lf = in[0][c-1]   - in[0][c];
00105       ri = in[0][c+1]   - in[0][c];
00106       ll = in[1][c-1]   - in[0][c];
00107       lm = in[1][c]     - in[0][c];
00108       lr = in[1][c+1]   - in[0][c];
00109       dmin = mval;
00110       if (lf<=thresh) continue; if (lf<dmin) dmin = lf;
00111       if (ri<=thresh) continue; if (ri<dmin) dmin = ri;
00112       if (ll<=thresh) continue; if (ll<dmin) dmin = ll;
00113       if (lm<=thresh) continue; if (lm<dmin) dmin = lm;
00114       if (lr<=thresh) continue; if (lr<dmin) dmin = lr;
00115       if (dmin>thresh) {
00116         minima[0][c] = dmin;
00117         minima_found = true;
00118       }
00119     }
00120     for (unsigned c = 1; c<nc-1; ++c) {
00121       // last row case
00122       // xxxxxxxxxxxxxxxxxxxxxxx
00123       // xxxx   ul um  ur  xxxxx
00124       // xxxx   lf  m  ri  xxxxx
00125       ul = in[nr-2][c-1] - in[nr-1][c];
00126       um = in[nr-2][c]   - in[nr-1][c];
00127       ur = in[nr-2][c+1] - in[nr-1][c];
00128       lf = in[nr-1][c-1] - in[nr-1][c];
00129       ri = in[nr-1][c+1] - in[nr-1][c];
00130       dmin = mval;
00131       if (ul<=thresh) continue; if (ul<dmin) dmin = ul;
00132       if (um<=thresh) continue; if (um<dmin) dmin = um;
00133       if (ur<=thresh) continue; if (ur<dmin) dmin = ur;
00134       if (lf<=thresh) continue; if (lf<dmin) dmin = lf;
00135       if (ri<=thresh) continue; if (ri<dmin) dmin = ri;
00136       if (dmin>thresh) {
00137         minima[nr-1][c] = dmin;
00138         minima_found = true;
00139       }
00140     }
00141   }
00142   if (nr>2) {
00143     //first column case
00144     for (unsigned r = 1; r<nr-1; ++r) {
00145       // um  ur  xxxxx
00146       //  m  ri  xxxxx
00147       // lm  lr  xxxxx
00148       um = in[r-1][0] - in[r][0];
00149       ur = in[r-1][1] - in[r][0];
00150       ri = in[r][1]   - in[r][0];
00151       lm = in[r+1][0] - in[r][0];
00152       lr = in[r+1][1] - in[r][0];
00153       dmin = mval;
00154       if (um<=thresh) continue; if (um<dmin) dmin = um;
00155       if (ur<=thresh) continue; if (ur<dmin) dmin = ur;
00156       if (ri<=thresh) continue; if (ri<dmin) dmin = ri;
00157       if (lm<=thresh) continue; if (lm<dmin) dmin = lm;
00158       if (lr<=thresh) continue; if (lr<dmin) dmin = lr;
00159       if (dmin>thresh) {
00160         minima[r][0] = dmin;
00161         minima_found = true;
00162       }
00163     }
00164     //last column case
00165     for (unsigned r = 1; r<nr-1; ++r) {
00166       //  xxxxx ul um
00167       //  xxxxx lf  m
00168       //  xxxxx ll lm
00169       ul = in[r-1][nc-2] - in[r][nc-1];
00170       um = in[r-1][nc-1] - in[r][nc-1];
00171       lf = in[r][nc-2]   - in[r][nc-1];
00172       ll = in[r+1][nc-2] - in[r][nc-1];
00173       lm = in[r+1][nc-1] - in[r][nc-1];
00174       dmin = mval;
00175       if (ul<=thresh) continue; if (ul<dmin) dmin = ul;
00176       if (um<=thresh) continue; if (um<dmin) dmin = um;
00177       if (lf<=thresh) continue; if (lf<dmin) dmin = lf;
00178       if (ll<=thresh) continue; if (ll<dmin) dmin = ll;
00179       if (lm<=thresh) continue; if (lm<dmin) dmin = lm;
00180       if (dmin>thresh) {
00181         minima[r][nc-1] = dmin;
00182         minima_found = true;
00183       }
00184     }
00185   }
00186   // check the corners for minima
00187   // upper left corner
00188   //  m  ri  xxxxx
00189   // lm  lr  xxxxx
00190   bool fail = false;
00191   ri = in[0][1] - in[0][0];
00192   lm = in[1][0] - in[0][0];
00193   lr = in[1][1] - in[0][0];
00194   dmin = mval;
00195   if (ri<=thresh) fail = true; if (ri<dmin) dmin = ri;
00196   if (lm<=thresh) fail = true; if (lm<dmin) dmin = lm;
00197   if (lr<=thresh) fail = true; if (lr<dmin) dmin = lr;
00198   if (!fail) {
00199     minima[0][0] = dmin;
00200     minima_found = true;
00201   }
00202   // upper right corner
00203   // xxxxx lf   m
00204   // xxxxx ll  lm
00205   fail = false;
00206   lf = in[0][nc-2] - in[0][nc-1];
00207   lm = in[1][nc-1] - in[0][nc-1];
00208   ll = in[1][nc-2] - in[0][nc-1];
00209   dmin = mval;
00210   if (lf<=thresh) fail = true; if (lf<dmin) dmin = lf;
00211   if (lm<=thresh) fail = true; if (lm<dmin) dmin = lm;
00212   if (ll<=thresh) fail = true; if (ll<dmin) dmin = ll;
00213   if (!fail) {
00214     minima[0][nc-1] = dmin;
00215     minima_found = true;
00216   }
00217   // lower right corner
00218   // xxxxx ul   um
00219   // xxxxx lf    m
00220   fail = false;
00221   ul = in[nr-2][nc-2] - in[nr-1][nc-1];
00222   um = in[nr-2][nc-1] - in[nr-1][nc-1];
00223   lf = in[nr-1][nc-2] - in[nr-1][nc-1];
00224   dmin = mval;
00225   if (ul<=thresh) fail = true; if (ul<dmin) dmin = ul;
00226   if (um<=thresh) fail = true; if (um<dmin) dmin = um;
00227   if (lf<=thresh) fail = true; if (lf<dmin) dmin = lf;
00228   if (!fail) {
00229     minima[nr-1][nc-1] = dmin;
00230     minima_found = true;
00231   }
00232   // lower left corner
00233   // xxxxx um   ur
00234   // xxxxx  m    ri
00235   fail = false;
00236   ur = in[nr-2][1] - in[nr-1][0];
00237   um = in[nr-2][0] - in[nr-1][0];
00238   ri = in[nr-1][1] - in[nr-1][0];
00239   dmin = mval;
00240   if (ur<=thresh) fail = true; if (ur<dmin) dmin = ur;
00241   if (um<=thresh) fail = true; if (um<dmin) dmin = um;
00242   if (ri<=thresh) fail = true; if (ri<dmin) dmin = ri;
00243   if (!fail) {
00244     minima[nr-1][0] = dmin;
00245     minima_found = true;
00246   }
00247   return minima_found;
00248 }
00249 
00250 template <class T>
00251 bool local_minima(vbl_array_3d<T> const& in, vbl_array_3d<T>& minima, T thresh)
00252 {
00253   const unsigned int n1=(unsigned int)(in.get_row1_count()),
00254                      n2=(unsigned int)(in.get_row2_count()),
00255                      n3=(unsigned int)(in.get_row3_count());
00256   assert(n3==minima.get_row3_count() &&
00257          n2==minima.get_row2_count() &&
00258          n1==minima.get_row1_count() );
00259   //special case
00260   // actually a 2-d array or null
00261   if (n3<2||n2<2||n1<2)
00262     return false;
00263   bool minima_found = false;
00264   unsigned int x3=0, x2=0, x1=0;
00265   for (x3 = 0; x3<n3; ++x3)
00266     for (x2 = 0; x2<n2; ++x2)
00267       for (x1 = 0; x1<n1; ++x1)
00268         minima[x1][x2][x3] = T(0);
00269   T v, d, mind;
00270   bool fail;
00271   const T mval = vcl_numeric_limits<T>::max();
00272   // general case
00273   if (n3>2||n2>2||n1>2)
00274     for (x3 = 1; x3<n3-1; ++x3)
00275       for (x2 = 1; x2<n2-1; ++x2)
00276         for (x1 = 1; x1<n1-1; ++x1) {
00277           mind = mval;
00278           fail = false;
00279           v = in[x1][x2][x3];
00280           for (int k3 = -1; k3<=1;++k3)
00281             for (int k2 = -1; k2<=1;++k2)
00282               for (int k1 = -1; k1<=1;++k1)
00283                 if (k1!=0||k2!=0||k3!=0) {
00284                   d = in[x1+k1][x2+k2][x3+k3]-v;
00285                   if (d<=thresh) {fail = true; break;}
00286                   if (d<mind) mind = d;
00287                 }
00288           if (!fail) { // local min found
00289             minima[x1][x2][x3]=mind;
00290             minima_found = true;
00291           }
00292         }
00293   //face border cases six in total
00294   if (n3>2&&n2>2) { // top and bottom faces of the array vary x3, x2
00295     //top face
00296     x1 = 0;
00297     for (x3 = 1; x3<n3-1; ++x3)
00298       for (x2 = 1; x2<n2-1; ++x2) {
00299         mind = mval; fail = false;
00300         v = in[x1][x2][x3];
00301         for (int k3 = -1; k3<=1;++k3)
00302           for (int k2 = -1; k2<=1;++k2)
00303             for (int k1 = 0; k1<=1;++k1)
00304               if (k3!=0||k2!=0||k1!=0) {
00305                 d = in[x1+k1][x2+k2][x3+k3]-v; if (d<=thresh) {fail=true; break;}
00306                 if (d<mind) mind = d;
00307               }
00308         if (!fail) { // local min found
00309           minima[x1][x2][x3]=mind;
00310           minima_found = true;
00311         }
00312       }
00313     //bottom face
00314     x1 = n1-1;
00315     for (x3 = 1; x3<n3-1; ++x3)
00316       for (x2 = 1; x2<n2-1; ++x2) {
00317         mind = mval; fail = false;
00318         v = in[x1][x2][x3];
00319         for (int k3 = -1; k3<=1;++k3)
00320           for (int k2 = -1; k2<=1;++k2)
00321             for (int k1 = -1; k1<=0;++k1)
00322               if (k3!=0||k2!=0||k1!=0) {
00323                 d = in[x1+k1][x2+k2][x3+k3]-v; if (d<=thresh) {fail=true; break;}
00324                 if (d<mind) mind = d;
00325               }
00326         if (!fail) { // local min found
00327           minima[x1][x2][x3]=mind;
00328           minima_found = true;
00329         }
00330       }
00331   }
00332   if (n3>2&&n1>2) { // front and back faces of the array vary x3, x1
00333     //front face
00334     x2 = 0;
00335     for (x3 = 1; x3<n3-1; ++x3)
00336       for (x1 = 1; x1<n1-1; ++x1) {
00337         mind = mval; fail = false;
00338         v = in[x1][x2][x3];
00339         for (int k3 = -1; k3<=1;++k3)
00340           for (int k2 = 0; k2<=1;++k2)
00341             for (int k1 = -1; k1<=1;++k1)
00342               if (k3!=0||k2!=0||k1!=0) {
00343                 d = in[x1+k1][x2+k2][x3+k3]-v; if (d<=thresh) {fail=true; break;}
00344                 if (d<mind) mind = d;
00345               }
00346         if (!fail) { // local min found
00347           minima[x1][x2][x3]=mind;
00348           minima_found = true;
00349         }
00350       }
00351     //back face
00352     x2 = n2-1;
00353     for (x3 = 1; x3<n3-1; ++x3)
00354       for (x1 = 1; x1<n1-1; ++x1) {
00355         mind = mval; fail = false;
00356         v = in[x1][x2][x3];
00357         for (int k3 = -1; k3<=1;++k3)
00358           for (int k2 = -1; k2<=0;++k2)
00359             for (int k1 = -1; k1<=1;++k1)
00360               if (k3!=0||k2!=0||k1!=0) {
00361                 d = in[x1+k1][x2+k2][x3+k3]-v; if (d<=thresh) {fail=true; break;}
00362                 if (d<mind) mind = d;
00363               }
00364         if (!fail) { // local min found
00365           minima[x1][x2][x3]=mind;
00366           minima_found = true;
00367         }
00368       }
00369   }
00370 
00371   if (n2>2&&n1>2) { // left and right faces of the array vary x2, x1
00372     //left face
00373     x3 = 0;
00374     for (x2 = 1; x2<n2-1; ++x2)
00375       for (x1 = 1; x1<n1-1; ++x1) {
00376         mind = mval; fail = false;
00377         v = in[x1][x2][x3];
00378         for (int k3 = 0; k3<=1;++k3)
00379           for (int k2 = -1; k2<=1;++k2)
00380             for (int k1 = -1; k1<=1;++k1)
00381               if (k3!=0||k2!=0||k1!=0) {
00382                 d = in[x1+k1][x2+k2][x3+k3]-v; if (d<=thresh) {fail=true; break;}
00383                 if (d<mind) mind = d;
00384               }
00385         if (!fail) { // local min found
00386           minima[x1][x2][x3]=mind;
00387           minima_found = true;
00388         }
00389       }
00390     //right face
00391     x3 = n3-1;
00392     for (x2 = 1; x2<n2-1; ++x2)
00393       for (x1 = 1; x1<n1-1; ++x1) {
00394         mind = mval; fail = false;
00395         v = in[x1][x2][x3];
00396         for (int k3 = -1; k3<=0;++k3)
00397           for (int k2 = -1; k2<=1;++k2)
00398             for (int k1 = -1; k1<=1;++k1)
00399               if (k3!=0||k2!=0||k1!=0) {
00400                 d = in[x1+k1][x2+k2][x3+k3]-v; if (d<=thresh) {fail=true; break;}
00401                 if (d<mind) mind = d;
00402               }
00403         if (!fail) { // local min found
00404           minima[x1][x2][x3]=mind;
00405           minima_found = true;
00406         }
00407       }
00408   }
00409 
00410   //edge border cases, 12 in total
00411   if (x1>2)
00412   {
00413     //edges along x1
00414     x3 = 0, x2 = 0;     //vary x1
00415     for (x1 = 1; x1<n1-1; ++x1) {
00416       mind = mval; fail = false;
00417       v = in[x1][x2][x3];
00418       for (int k3 = 0; k3<=1;++k3)
00419         for (int k2 = 0; k2<=1;++k2)
00420           for (int k1 = -1; k1<=1;++k1)
00421             if (k3!=0||k2!=0||k1!=0) {
00422               d = in[x1+k1][x2+k2][x3+k3]-v; if (d<=thresh) {fail=true; break;}
00423               if (d<mind) mind = d;
00424             }
00425       if (!fail) { // local min found
00426         minima[x1][x2][x3]=mind;
00427         minima_found = true;
00428       }
00429     }
00430     x3 = n3-1; x2 = 0;     //vary x1
00431     for (x1 = 1; x1<n1-1; ++x1) {
00432       mind = mval; fail = false;
00433       v = in[x1][x2][x3];
00434       for (int k3 = 0; k3<=1;++k3)
00435         for (int k2 = 0; k2<=1;++k2)
00436           for (int k1 = -1; k1<=1;++k1)
00437             if (k3!=0||k2!=0||k1!=0) {
00438               d = in[x1+k1][x2+k2][x3+k3]-v; if (d<=thresh) {fail=true; break;}
00439               if (d<mind) mind = d;
00440             }
00441       if (!fail) { // local min found
00442         minima[x1][x2][x3]=mind;
00443         minima_found = true;
00444       }
00445     }
00446     x3 = 0; x2 = n2-1;     //vary x1
00447     for (x1 = 1; x1<n1-1; ++x1) {
00448       mind = mval; fail = false;
00449       v = in[x1][x2][x3];
00450       for (int k3 = 0; k3<=1;++k3)
00451         for (int k2 = -1; k2<=0;++k2)
00452           for (int k1 = -1; k1<=1;++k1)
00453             if (k3!=0||k2!=0||k1!=0) {
00454               d = in[x1+k1][x2+k2][x3+k3]-v; if (d<=thresh) {fail=true; break;}
00455               if (d<mind) mind = d;
00456             }
00457       if (!fail) { // local min found
00458         minima[x1][x2][x3]=mind;
00459         minima_found = true;
00460       }
00461     }
00462     x3 = n3-1; x2 = n2-1;     //vary x1
00463     for (x1 = 1; x1<n1-1; ++x1) {
00464       mind = mval; fail = false;
00465       v = in[x1][x2][x3];
00466       for (int k3 = -1; k3<=0;++k3)
00467         for (int k2 = -1; k2<=0;++k2)
00468           for (int k1 = -1; k1<=1;++k1)
00469             if (k3!=0||k2!=0||k1!=0) {
00470               d = in[x1+k1][x2+k2][x3+k3]-v; if (d<=thresh) {fail=true; break;}
00471               if (d<mind) mind = d;
00472             }
00473       if (!fail) { // local min found
00474         minima[x1][x2][x3]=mind;
00475         minima_found = true;
00476       }
00477     }
00478   }
00479   if (x2>2)
00480   {
00481     // edges along x2
00482     x3 = 0,    x1 = 0;     //vary x2
00483     for (x2 = 1; x2<n2-1; ++x2) {
00484       mind = mval; fail = false;
00485       v = in[x1][x2][x3];
00486       for (int k3 = 0; k3<=1;++k3)
00487         for (int k2 = -1; k2<=1;++k2)
00488           for (int k1 = 0; k1<=1;++k1)
00489             if (k3!=0||k2!=0||k1!=0) {
00490               d = in[x1+k1][x2+k2][x3+k3]-v; if (d<=thresh) {fail=true; break;}
00491               if (d<mind) mind = d;
00492             }
00493       if (!fail) { // local min found
00494         minima[x1][x2][x3]=mind;
00495         minima_found = true;
00496       }
00497     }
00498     x3 = n3-1; x1 = 0;     //vary x2
00499     for (x2 = 1; x2<n2-1; ++x2) {
00500       mind = mval; fail = false;
00501       v = in[x1][x2][x3];
00502       for (int k3 = -1; k3<=0;++k3)
00503         for (int k2 = -1; k2<=1;++k2)
00504           for (int k1 = 0; k1<=1;++k1)
00505             if (k3!=0||k2!=0||k1!=0) {
00506               d = in[x1+k1][x2+k2][x3+k3]-v; if (d<=thresh) {fail=true; break;}
00507               if (d<mind) mind = d;
00508             }
00509       if (!fail) { // local min found
00510         minima[x1][x2][x3]=mind;
00511         minima_found = true;
00512       }
00513     }
00514     x3 = 0;    x1 = n1-1;     //vary x2
00515     for (x2 = 1; x2<n2-1; ++x2) {
00516       mind = mval; fail = false;
00517       v = in[x1][x2][x3];
00518       for (int k3 = 0; k3<=1;++k3)
00519         for (int k2 = -1; k2<=1;++k2)
00520           for (int k1 = -1; k1<=0;++k1)
00521             if (k3!=0||k2!=0||k1!=0) {
00522               d = in[x1+k1][x2+k2][x3+k3]-v; if (d<=thresh) {fail=true; break;}
00523               if (d<mind) mind = d;
00524             }
00525       if (!fail) { // local min found
00526         minima[x1][x2][x3]=mind;
00527         minima_found = true;
00528       }
00529     }
00530     x3 = n3-1; x1 = n1-1;     //vary x2
00531     for (x2 = 1; x2<n2-1; ++x2) {
00532       mind = mval; fail = false;
00533       v = in[x1][x2][x3];
00534       for (int k3 = -1; k3<=0;++k3)
00535         for (int k2 = -1; k2<=1;++k2)
00536           for (int k1 = -1; k1<=0;++k1)
00537             if (k3!=0||k2!=0||k1!=0) {
00538               d = in[x1+k1][x2+k2][x3+k3]-v; if (d<=thresh) {fail=true; break;}
00539               if (d<mind) mind = d;
00540             }
00541       if (!fail) { // local min found
00542         minima[x1][x2][x3]=mind;
00543         minima_found = true;
00544       }
00545     }
00546   }
00547   if (x3>2)
00548   {
00549     // edges along x3
00550     x2 = 0,    x1 = 0;     //vary x3
00551     for (x3 = 1; x3<n3-1; ++x3) {
00552       mind = mval; fail = false;
00553       v = in[x1][x2][x3];
00554       for (int k3 = -1; k3<=1;++k3)
00555         for (int k2 = 0; k2<=1;++k2)
00556           for (int k1 = 0; k1<=1;++k1)
00557             if (k3!=0||k2!=0||k1!=0) {
00558               d = in[x1+k1][x2+k2][x3+k3]-v; if (d<=thresh) {fail=true; break;}
00559               if (d<mind) mind = d;
00560             }
00561       if (!fail) { // local min found
00562         minima[x1][x2][x3]=mind;
00563         minima_found = true;
00564       }
00565     }
00566     x2 = n2-1; x1 = 0;     //vary x3
00567     for (x3 = 1; x3<n3-1; ++x3) {
00568       mind = mval; fail = false;
00569       v = in[x1][x2][x3];
00570       for (int k3 = -1; k3<=1;++k3)
00571         for (int k2 = -1; k2<=0;++k2)
00572           for (int k1 = 0; k1<=1;++k1)
00573             if (k3!=0||k2!=0||k1!=0) {
00574               d = in[x1+k1][x2+k2][x3+k3]-v; if (d<=thresh) {fail=true; break;}
00575               if (d<mind) mind = d;
00576             }
00577       if (!fail) { // local min found
00578         minima[x1][x2][x3]=mind;
00579         minima_found = true;
00580       }
00581     }
00582     x2 = 0;    x1 = n1-1;     //vary x3
00583     for (x3 = 1; x3<n3-1; ++x3) {
00584       mind = mval; fail = false;
00585       v = in[x1][x2][x3];
00586       for (int k3 = -1; k3<=1;++k3)
00587         for (int k2 = 0; k2<=1;++k2)
00588           for (int k1 = -1; k1<=0;++k1)
00589             if (k3!=0||k2!=0||k1!=0) {
00590               d = in[x1+k1][x2+k2][x3+k3]-v; if (d<=thresh) {fail=true; break;}
00591               if (d<mind) mind = d;
00592             }
00593       if (!fail) { // local min found
00594         minima[x1][x2][x3]=mind;
00595         minima_found = true;
00596       }
00597     }
00598     x2 = n2-1; x1 = n1-1;     //vary x3
00599     for (x3 = 1; x3<n3-1; ++x3) {
00600       mind = mval; fail = false;
00601       v = in[x1][x2][x3];
00602       for (int k3 = -1; k3<=1;++k3)
00603         for (int k2 = -1; k2<=0;++k2)
00604           for (int k1 = -1; k1<=0;++k1)
00605             if (k3!=0||k2!=0||k1!=0) {
00606               d = in[x1+k1][x2+k2][x3+k3]-v; if (d<=thresh) {fail=true; break;}
00607               if (d<mind) mind = d;
00608             }
00609       if (!fail) { // local min found
00610         minima[x1][x2][x3]=mind;
00611         minima_found = true;
00612       }
00613     }
00614   }
00615   // corner border cases 8 in total
00616   // corner 000
00617   x3=0; x2=0; x1=0;
00618   v = in[x1][x2][x3];
00619   mind = mval; fail = false;
00620   for (int k3 = 0; k3<=1;++k3)
00621     for (int k2 = 0; k2<=1;++k2)
00622       for (int k1 = 0; k1<=1;++k1)
00623         if (k3!=0||k2!=0||k1!=0) {
00624           d = in[x1+k1][x2+k2][x3+k3]-v; if (d<=thresh) {fail=true; break;}
00625           if (d<mind) mind = d;
00626         }
00627   if (!fail) {
00628     minima[x1][x2][x3]=mind;
00629     minima_found = true;
00630   }
00631   // corner 001
00632   x3=n3-1; x2=0; x1=0;
00633   v = in[x1][x2][x3];
00634   mind = mval; fail = false;
00635   for (int k3 = -1; k3<=0;++k3)
00636     for (int k2 = 0; k2<=1;++k2)
00637       for (int k1 = 0; k1<=1;++k1)
00638         if (k3!=0||k2!=0||k1!=0) {
00639           d = in[x1+k1][x2+k2][x3+k3]-v; if (d<=thresh) {fail=true; break;}
00640           if (d<mind) mind = d;
00641         }
00642   if (!fail) {
00643     minima[x1][x2][x3]=mind;
00644     minima_found = true;
00645   }
00646   // corner 010
00647   x3=0; x2=n2-1; x1=0;
00648   v = in[x1][x2][x3];
00649   mind = mval; fail = false;
00650   for (int k3 = 0; k3<=1;++k3)
00651     for (int k2 = -1; k2<=0;++k2)
00652       for (int k1 = 0; k1<=1;++k1)
00653         if (k3!=0||k2!=0||k1!=0) {
00654           d = in[x1+k1][x2+k2][x3+k3]-v; if (d<=thresh) {fail=true; break;}
00655           if (d<mind) mind = d;
00656         }
00657   if (!fail) {
00658     minima[x1][x2][x3]=mind;
00659     minima_found = true;
00660   }
00661   // corner 011
00662   x3=n3-1; x2=n2-1; x1=0;
00663   v = in[x1][x2][x3];
00664   mind = mval; fail = false;
00665   for (int k3 = -1; k3<=0;++k3)
00666     for (int k2 = -1; k2<=0;++k2)
00667       for (int k1 = 0; k1<=1;++k1)
00668         if (k3!=0||k2!=0||k1!=0) {
00669           d = in[x1+k1][x2+k2][x3+k3]-v; if (d<=thresh) {fail=true; break;}
00670           if (d<mind) mind = d;
00671         }
00672   if (!fail) {
00673     minima[x1][x2][x3]=mind;
00674     minima_found = true;
00675   }
00676   // corner 100
00677   x3=0; x2=0; x1=n1-1;
00678   v = in[x1][x2][x3];
00679   mind = mval; fail = false;
00680   for (int k3 = 0; k3<=1;++k3)
00681     for (int k2 = 0; k2<=1;++k2)
00682       for (int k1 = -1; k1<=0;++k1)
00683         if (k3!=0||k2!=0||k1!=0) {
00684           d = in[x1+k1][x2+k2][x3+k3]-v; if (d<=thresh) {fail=true; break;}
00685           if (d<mind) mind = d;
00686         }
00687   if (!fail) {
00688     minima[x1][x2][x3]=mind;
00689     minima_found = true;
00690   }
00691   // corner 101
00692   x3=n3-1; x2=0; x1=n1-1;
00693   v = in[x1][x2][x3];
00694   mind = mval; fail = false;
00695   for (int k3 = -1; k3<=0;++k3)
00696     for (int k2 = 0; k2<=1;++k2)
00697       for (int k1 = -1; k1<=0;++k1)
00698         if (k3!=0||k2!=0||k1!=0) {
00699           d = in[x1+k1][x2+k2][x3+k3]-v; if (d<=thresh) {fail=true; break;}
00700           if (d<mind) mind = d;
00701         }
00702   if (!fail) {
00703     minima[x1][x2][x3]=mind;
00704     minima_found = true;
00705   }  // corner 110
00706   mind = mval; fail = false;
00707   x3=0; x2=n2-1; x1=n1-1;
00708   v = in[x1][x2][x3];
00709   for (int k3 = 0; k3<=1;++k3)
00710     for (int k2 = -1; k2<=0;++k2)
00711       for (int k1 = -1; k1<=0;++k1)
00712         if (k3!=0||k2!=0||k1!=0) {
00713           d = in[x1+k1][x2+k2][x3+k3]-v; if (d<=thresh) {fail=true; break;}
00714           if (d<mind) mind = d;
00715         }
00716   if (!fail) {
00717     minima[x1][x2][x3]=mind;
00718     minima_found = true;
00719   }  // corner 111
00720   mind = mval; fail = false;
00721   x3=n3-1; x2=n2-1; x1=n1-1;
00722   v = in[x1][x2][x3];
00723   for (int k3 = -1; k3<=0;++k3)
00724     for (int k2 = -1; k2<=0;++k2)
00725       for (int k1 = -1; k1<=0;++k1)
00726         if (k3!=0||k2!=0||k1!=0) {
00727           d = in[x1+k1][x2+k2][x3+k3]-v; if (d<=thresh) {fail=true; break;}
00728           if (d<mind) mind = d;
00729         }
00730   if (!fail) {
00731     minima[x1][x2][x3]=mind;
00732     minima_found = true;
00733   }
00734   return minima_found;
00735 }
00736 
00737 #define VBL_LOCAL_MINIMA_INSTANTIATE(T) \
00738 template vbl_array_1d<T > vbl_local_minima(vbl_array_1d<T >const&, T); \
00739 template vbl_array_2d<T > vbl_local_minima(vbl_array_2d<T >const&, T); \
00740 template vbl_array_3d<T > vbl_local_minima(vbl_array_3d<T >const&, T); \
00741 template bool local_minima(vbl_array_1d<T >const&, vbl_array_1d<T >&, T); \
00742 template bool local_minima(vbl_array_2d<T >const&, vbl_array_2d<T >&, T); \
00743 template bool local_minima(vbl_array_3d<T >const&, vbl_array_3d<T >&, T)
00744 
00745 #endif // VBL_LOCAL_MINIMA_TXX_