00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef CVD_HAAR_H
00022 #define CVD_HAAR_H
00023
00024 #include <vector>
00025 #include <cmath>
00026 #include <cvd/image.h>
00027
00028 namespace CVD {
00029
00030 namespace Internal {
00031 template<class It, class TempIt>
00032 inline void haar1D(It from, int w, TempIt store){
00033 for(int i = 0; i < w; ++i){
00034 store[i] = (from[2*i] + from[2*i+1]) * M_SQRT1_2;
00035 store[i+w] = (from[2*i] - from[2*i+1]) * M_SQRT1_2;
00036 }
00037 std::copy(store, store+2*w, from);
00038 }
00039
00040 template<class It, class TempIt>
00041 inline void inv_haar1D(It from, int w, TempIt store){
00042 for(int i = 0; i < w; ++i){
00043 store[2*i] = (from[i] + from[w+i]) * M_SQRT1_2;
00044 store[2*i+1] = (from[i] - from[w+i]) * M_SQRT1_2;
00045 }
00046 std::copy(store, store+2*w, from);
00047 }
00048 }
00049
00050
00057 template<class It>
00058 inline void haar1D(It from, It to){
00059 std::vector<typename std::iterator_traits<It>::value_type> store(std::distance(from,to), typename std::iterator_traits<It>::value_type());
00060 for(int w = std::distance(from,to)/2; w > 0; w /= 2)
00061 Internal::haar1D(from, w, store.begin());
00062 }
00063
00070 template<class It>
00071 inline void inv_haar1D(It from, It to){
00072 std::vector<typename std::iterator_traits<It>::value_type> store(std::distance(from,to), typename std::iterator_traits<It>::value_type());
00073 for(int w = 1; w < std::distance(from,to); w *= 2)
00074 Internal::inv_haar1D(from, w, store.begin());
00075 }
00076
00082 template<class It>
00083 inline void haar1D(It from, int size){
00084 haar1D(from, from + size);
00085 }
00086
00092 template<class It>
00093 inline void inv_haar1D(It from, int size){
00094 inv_haar1D(from, from + size);
00095 }
00096
00104 template<class It>
00105 inline void haar2D(It from, const int width, const int height, int stride = -1){
00106 if(stride < 0) stride = width;
00107 typedef typename std::iterator_traits<It>::value_type T;
00108 std::vector<T> column(height, T());
00109 std::vector<T> store(std::max(width,height), T());
00110 int w = width;
00111 int h = height;
00112 while(w > 1 || h > 1){
00113 if(w > 1){
00114 for(int i = 0; i < h; ++i){
00115 Internal::haar1D(from + stride * i, w/2, store.begin());
00116 }
00117 }
00118 if(h > 1){
00119 for(int i = 0; i < w; ++i){
00120 for(int j = 0; j < h; ++j)
00121 column[j] = from[stride * j + i];
00122 Internal::haar1D(column.begin(), h/2, store.begin());
00123 for(int j = 0; j < h; ++j)
00124 from[stride * j + i] = column[j];
00125 }
00126 }
00127 if(w>1) w/=2;
00128 if(h>1) h/=2;
00129 }
00130 }
00131
00136 template<class T>
00137 inline void haar2D( SubImage<T> & I ){
00138 haar2D(I.data(), I.size().x, I.size().y, I.row_stride());
00139 }
00140
00141 }
00142
00143 #endif // CVD_HAAR_H