libidx
/home/rex/ebltrunk/core/libidx/include/filters.hpp
00001 /***************************************************************************
00002  *   Copyright (C) 2011 by Pierre Sermanet *
00003  *   pierre.sermanet@gmail.com *
00004  *   All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions are met:
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Redistribution under a license not approved by the Open Source
00014  *       Initiative (http://www.opensource.org) must display the
00015  *       following acknowledgement in all advertising material:
00016  *        This product includes software developed at the Courant
00017  *        Institute of Mathematical Sciences (http://cims.nyu.edu).
00018  *     * The names of the authors may not be used to endorse or promote products
00019  *       derived from this software without specific prior written permission.
00020  *
00021  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
00022  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00023  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00024  * DISCLAIMED. IN NO EVENT SHALL ThE AUTHORS BE LIABLE FOR ANY
00025  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00026  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00027  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00028  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00029  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00030  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031  ***************************************************************************/
00032 
00033 #ifndef FILTERS_HPP_
00034 #define FILTERS_HPP_
00035 
00036 namespace ebl {
00037 
00039   // Filters
00040 
00041   // TODO: cleanup
00042   template <typename T>
00043   idx<T> create_mexican_hat(double s, int n) {
00044     idx<T> m(n, n);
00045     T vinv = (T) (1/(s*s));
00046     T total = 0;
00047     int cx = n/2;
00048     int cy = n/2;
00049     for(int x = 0; x < n; x++){
00050       for(int y = 0; y < n; y++){
00051         int dx = x - cx;
00052         int dy = y - cy;
00053         m.set(-exp(-sqrt(vinv*(dx*dx + dy*dy))), x, y);
00054         total += m.get(x, y);
00055       }
00056     }
00058     m.set(m.get(cx, cy) - total, cx, cy);
00060     T energy = sqrt(idx_sumsqr(m));
00061     idx_dotc(m, 1/energy, m);
00062     return m;
00063   }
00064 
00065   template <typename T>
00066   idx<T> create_gaussian_kernel2(uint n, double sig) {
00067     idx<T> g(n);    
00068     idx_fill_index(g);
00069     // if not odd, shift by half to get equal peaks at the center
00070     if (n % 2 == 0) idx_addc(g, -.5, g);
00071     idx_addc(g, (T) (- (int) ((n - 1) / 2)), g);
00072     idx_mul(g, g, g);
00073     idx_dotc(g, -0.5, g);
00074     idx_dotc(g, 1 / (sig * sig), g);
00075     idx_exp(g);
00076     idx_dotc(g, 1 / idx_sum(g), g);
00077     return g;
00078   }
00079   
00080   template <typename T>
00081   idx<T> create_gaussian_kernel2(uint h, uint w, double sig) {
00082     if (h != w)
00083       eblerror("this function only handles square filters, "
00084                << "use create_gaussian_kernel2()");
00085     idx<T> g1 = create_gaussian_kernel<T>(h, sig);
00086     idx<T> g2(h, h);
00087     idx_m1extm1(g1, g1, g2);
00088     return g2;
00089   }
00090   
00091   template <typename T>
00092   idx<T> create_gaussian_kernel(idxdim &d, double mode) {
00093     // if (d.order() != 1 && d.order() != 2)
00094     //   eblerror("unsupported gaussian kernel dimensions " << d);
00095     // if (d.order() == 1)
00096 
00097     if (d.order() != 2)
00098       eblerror("unsupported gaussian kernel dimensions " << d);
00099     if (d.dim(0) == d.dim(1))
00100       return create_gaussian_kernel<T>((uint) d.dim(0), mode);
00101     else
00102       return create_gaussian_kernel<T>((uint) d.dim(0), (uint) d.dim(1), mode);
00103   }
00104 
00105   template <typename T>
00106   idx<T> create_burt_adelson_kernel(double a) {
00107     idx<T> filter(5, 5), f1d(5);      
00108     f1d.set((T) (.25 - a / 2.0), 0);
00109     f1d.set((T) .25, 1);
00110     f1d.set((T) a, 2);
00111     f1d.set(f1d.get(1), 3);
00112     f1d.set(f1d.get(0), 4);
00113     idx_m1extm1(f1d, f1d, filter);
00114     return filter;
00115   }
00116 
00117   // TODO: cleanup
00118   template <typename T>
00119   idx<T> create_gaussian_kernel(uint n_, double mode) {
00120     int n = n_;
00121     idx<T> m(n, n);
00122     double s = ((double)n)/4;
00123     T vinv;
00124     
00125     if (mode == 0)
00126       vinv = (T) (1/(s*s));
00127     else
00128       vinv = (T) (1/(mode*s));
00129     //      vinv = (T) (1/(2*s));
00130     
00131     T total = 0;
00132     int cx = n/2;
00133     int cy = n/2;
00134     for(int x = 0; x < n; x++){
00135       for(int y = 0; y < n; y++){
00136         int dx = x - cx;
00137         int dy = y - cy;
00138         m.set((T) -exp(-(vinv*(dx*dx + dy*dy))), x, y);
00139         total += m.get(x, y);
00140       }
00141     }
00143     //    m.set(m.get(cx, cy) - total, cx, cy);
00145     //    T energy = sqrt(idx_sumsqr(m));
00146     idx_dotc(m, 1/total, m);
00147     return m;
00148   }
00149 
00150   // TODO: cleanup
00151   template <typename T>
00152   idx<T> create_gaussian_kernel(uint h, uint w, double mode) {
00153     idx<T> m(h, w);
00154     uint min = MIN(h, w); // use smallest dim for gaussian
00155     double s = (double)(min)/4;
00156     T vinv;
00157     
00158     if (mode == 0)
00159       vinv = (T) (1/(s*s));
00160     else
00161       vinv = (T) (1/(mode*s));
00162     //      vinv = (T) (1/(2*s));
00163     
00164     T total = 0;
00165     int cx = min/2;
00166     int cy = min/2;
00167     for(uint x = 0; x < h; x++){
00168       for(uint y = 0; y < w; y++){
00169         int dx = x - cx;
00170         int dy = y - cy;
00171 #ifdef __WINDOWS__
00172         m.set((T) (-exp((double)(-(vinv*(dx*dx + dy*dy))))), x, y);
00173 #else
00174         m.set((T) (-exp(-(vinv*(dx*dx + dy*dy)))), x, y);
00175 #endif
00176         total += m.get(x, y);
00177       }
00178     }
00180     //    m.set(m.get(cx, cy) - total, cx, cy);
00182     //    T energy = sqrt(idx_sumsqr(m));
00183     idx_dotc(m, 1/total, m);
00184     return m;
00185   }
00186 
00187 } // end namespace ebl
00188 
00189 #endif /* FILTERS_HPP_ */