CVD 0.8
cvd/integral_image.h
00001 /*
00002         This file is part of the CVD Library.
00003 
00004         Copyright (C) 2005 The Authors
00005 
00006         This library is free software; you can redistribute it and/or
00007         modify it under the terms of the GNU Lesser General Public
00008         License as published by the Free Software Foundation; either
00009         version 2.1 of the License, or (at your option) any later version.
00010 
00011         This library is distributed in the hope that it will be useful,
00012         but WITHOUT ANY WARRANTY; without even the implied warranty of
00013         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014         Lesser General Public License for more details.
00015 
00016         You should have received a copy of the GNU Lesser General Public
00017         License along with this library; if not, write to the Free Software
00018         Foundation, Inc.,
00019     51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00020 */
00021 
00022 #ifndef CVD_INC_INTEGRAL_IMAGE_H
00023 #define CVD_INC_INTEGRAL_IMAGE_H
00024 
00025 #include <cvd/image.h>
00026 #include <cvd/vision.h>
00027 #include <cvd/internal/pixel_operations.h>
00028 
00029 namespace CVD
00030 {
00039         
00040     template<class S, class D> void integral_image(const SubImage<S>& in, SubImage<D>& out)
00041     {
00042         if( in.size() != out.size())
00043             throw Exceptions::Vision::IncompatibleImageSizes("integral_image");
00044 
00045         Pixel::operations<D>::assign(out[0][0], in[0][0]);
00046         //Do the first row. 
00047         for(int x=1; x < in.size().x; x++)
00048             out[0][x] =out[0][x-1] + in[0][x];
00049 
00050         //Do the first column. 
00051         for(int y=1; y < in.size().y; y++)
00052             out[y][0] =out[y-1][0] + in[y][0];
00053 
00054         //Do the remainder of the image
00055         for(int y=1; y < in.size().y; y++)
00056         {
00057             D sum;
00058             Pixel::operations<D>::assign(sum,in[y][0]);
00059 
00060             for(int x=1; x < in.size().x; x++)
00061             {
00062                 sum+= in[y][x];
00063                 Pixel::operations<D>::assign(out[y][x],sum + out[y-1][x]);
00064             }
00065         }
00066     }
00067     #ifndef DOXYGEN_IGNORE_INTERNAL
00068         namespace Internal
00069         {
00070             template<class C> class IntegralImage{};
00071 
00072             template<class C>  struct ImagePromise<IntegralImage<C> >
00073             {
00074                 ImagePromise(const SubImage<C>& im)
00075                 :i(im)
00076                 {}
00077 
00078                 const SubImage<C>& i;
00079                 template<class D> void execute(Image<D>& j)
00080                 {
00081                     j.resize(i.size());
00082                     integral_image<C,D>(i, j);
00083                 }
00084             };
00085         };
00086 
00087         template<class C> Internal::ImagePromise<Internal::IntegralImage<C> > integral_image(const SubImage<C>& c)
00088         {
00089             return Internal::ImagePromise<Internal::IntegralImage<C> >(c);
00090         }
00091     #else
00092 
00093 
00094 
00095 
00096 
00097 
00098 
00099 
00100 
00101 
00102 
00103 
00104 
00105 
00106 
00107 
00108 
00109         template<class S, class D> Image<D> integral_image(const BasicImage<S>& from);
00110 
00111     #endif
00112 
00113 }
00114 
00115 
00116 #endif
00117