00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
00047 for(int x=1; x < in.size().x; x++)
00048 out[0][x] =out[0][x-1] + in[0][x];
00049
00050
00051 for(int y=1; y < in.size().y; y++)
00052 out[y][0] =out[y-1][0] + in[y][0];
00053
00054
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