00001 #ifndef Impala_Core_Tracking_KernelSet_h
00002 #define Impala_Core_Tracking_KernelSet_h
00003
00004 #include <vector>
00005 #include <algorithm>
00006 #include <assert.h>
00007 #include "Core/Array/Arrays.h"
00008
00009 namespace Impala
00010 {
00011 namespace Core
00012 {
00013 namespace Tracking
00014 {
00015
00017 class KernelSet
00018 {
00019 public:
00020 KernelSet(int size) : mFilterSize(size)
00021 {
00022 }
00023
00024 virtual ~KernelSet()
00025 {
00026 for(int i=0 ; i<mFilters.size() ; i++)
00027 delete mFilters[i];
00028 }
00029
00030 void
00031 AddKernel(Array::Array2dScalarReal64* kernel)
00032 {
00033 assert(kernel->CW() == mFilterSize && kernel->CH() == mFilterSize);
00034 mFilters.push_back(kernel);
00035 }
00036
00037 int GetFilterCount()
00038 {
00039 return mFilters.size();
00040 }
00041
00050 void Apply(double* buffer, Array::Array2dVec3Real64& image, int posX, int posY)
00051 {
00052
00053 int i;
00054 for(i=0 ; i<3*mFilters.size() ; i++)
00055 buffer[i] = 0;
00056
00057
00058 int radius = mFilterSize / 2;
00059 if (posX-radius <= -image.BW() ||
00060 posY-radius <= -image.BH() ||
00061 posX+radius >= image.CW() + image.BW() ||
00062 posY+radius >= image.CH() + image.BH())
00063 {
00064 return;
00065 }
00066
00067 posX -= radius;
00068 posY -= radius;
00069 int y;
00070 for(y=0 ; y<mFilterSize ; y++)
00071 {
00072 for(i=0 ; i<mFilters.size() ; i++)
00073 {
00074 double* ip;
00075 double* fp;
00076 ip = image.CPB(posX, y+posY);
00077 fp = mFilters[i]->CPB(0, y);
00078 int x;
00079 for(x=0 ; x<mFilterSize ; x++)
00080 {
00081 double* tp;
00082 tp = buffer+(i*3);
00083 *tp += *ip * *fp;
00084 tp++;
00085 ip++;
00086 *tp += *ip * *fp;
00087 tp++;
00088 ip++;
00089 *tp += *ip * *fp;
00090 ip++;
00091 fp++;
00092 }
00093 }
00094 }
00095
00096 double total=0;
00097 for(i=0 ; i<3*mFilters.size() ; i++)
00098 {
00099 buffer[i] /= (double)mFilterSize*mFilterSize;
00100 total += buffer[i];
00101 }
00102 }
00103
00104
00105 void Reconstruct(Array::Array2dVec3Real64& image, Array::Array2dScalarReal64& texture, int posX, int posY)
00106 {
00107
00108 Array::Array2dVec3Real64 mix(3*mFilterSize, mFilterSize, 0, 0);
00109
00110 int y;
00111 double* ip;
00112 for(y=0 ; y<mFilterSize ; y++)
00113 {
00114 ip = mix.CPB(0,y);
00115 int x;
00116 for(x=0 ; x<3*mFilterSize ; x++)
00117 {
00118 *ip = 0.0;
00119 ip++;
00120 }
00121 }
00122
00123 for(y=0 ; y<mFilterSize ; y++)
00124 {
00125 int i;
00126 for(i=0 ; i<mFilters.size() ; i++)
00127 {
00128 double *fp;
00129 ip = mix.CPB(0, y);
00130 fp = mFilters[i]->CPB(0, y);
00131 int x;
00132 for(x=0 ; x<mFilterSize ; x++)
00133 {
00134 double *tp;
00135 tp = texture.CPB(i*3, 0);
00136
00137 *ip += *tp * *fp;
00138 tp++;
00139 ip++;
00140
00141 *ip += *tp * *fp;
00142 tp++;
00143 ip++;
00144
00145 *ip += *tp * *fp;
00146 ip++;
00147 fp++;
00148 }
00149 }
00150 }
00151
00152 for(y=0 ; y<mFilterSize ; y++)
00153 {
00154 ip = mix.CPB(0, y);
00155 int x;
00156 for(x=0 ; x<3*mFilterSize ; x++)
00157 {
00158 *ip /= (double)mFilters.size();
00159 ip++;
00160 }
00161 }
00162
00163
00164 for(y=0 ; y<mFilterSize ; y++)
00165 {
00166 if(y+posY>=0 && y+posY<image.CH())
00167 {
00168 double *mp = mix.CPB(0, y);
00169 double *ip = image.CPB(posX, y+posY);
00170 for(int x=0 ; x<mFilterSize ; x++)
00171 {
00172 if(x+posX>=0 && x+posX<image.CW())
00173 {
00174 ip[3*x] += mp[3*x];
00175 ip[3*x+1] += mp[3*x+1];
00176 ip[3*x+2] += mp[3*x+2];
00177 }
00178 }
00179 }
00180 }
00181 }
00182
00183
00184 void
00185 ReconstructSeparate(std::vector<Array::Array2dVec3Real64*>* images, Array::Array2dScalarReal64& texture)
00186 {
00187 int y;
00188 for(y=0 ; y<mFilterSize ; y++)
00189 {
00190 for(int i=0 ; i<mFilters.size() ; i++)
00191 {
00192 double* ip = (*images)[i]->CPB(0,y);
00193 int x;
00194 for(x=0 ; x<3*mFilterSize ; x++)
00195 {
00196 *ip = 0.0;
00197 ip++;
00198 }
00199 }
00200 }
00201
00202 for(y=0 ; y<mFilterSize ; y++)
00203 {
00204 for(int i=0 ; i<mFilters.size() ; i++)
00205 {
00206 double *ip = (*images)[i]->CPB(0, y);
00207 double *fp = mFilters[i]->CPB(0, y);
00208 int x;
00209 for(x=0 ; x<mFilterSize ; x++)
00210 {
00211 double *tp;
00212 tp = texture.CPB(i*3, 0);
00213
00214 *ip += *tp * *fp;
00215 tp++;
00216 ip++;
00217
00218 *ip += *tp * *fp;
00219 tp++;
00220 ip++;
00221
00222 *ip += *tp * *fp;
00223 ip++;
00224 fp++;
00225 }
00226 }
00227 }
00228 }
00229
00230 private:
00231 std::vector<Array::Array2dScalarReal64*> mFilters;
00232 int mFilterSize;
00233
00234 void operator= (const KernelSet&);
00235 };
00236
00237 }
00238 }
00239 }
00240
00241 #endif //Impala_Core_Tracking_KernelSet_h