test-generics.C

00001 #include "Image/Image.H"
00002 #include "Image/Pixels.H"
00003 #include "GenericUtils/ProcessFunctor.H"
00004 #include "GenericUtils/GenericItem.H"
00005 #include <vector>
00006 
00007 //typdef our ProcessFunction and associated GenericItem definitions, the first
00008 // template type is the underlying container type, and the second is all the
00009 // types that could be processed. If a conversion is desired, we will attempt to
00010 // convert from the end to the front.
00011 // ######################################################################
00012 typedef ProcessFunctor<Image, PixRGB<byte>, byte, double, float> ImageFunctor;
00013 typedef GenericItem<Image, PixRGB<byte>, byte, double, float> GenericImage;
00014 
00015 // ######################################################################
00016 //a simple class to sum images as an example
00017 // ######################################################################
00018 class SumFunc : public ImageFunctor//implements virtual funcions for PixRGB<byte>, byte, double, float
00019 {
00020 public:
00021   float getSum() const { return itsSum; };
00022 private :
00023 
00024   //implement for float
00025   bool process(const Image<float>& feature)
00026   {
00027     //take the sum of the image
00028     itsSum = 0.0;
00029     Image<float>::const_iterator iter(feature.begin());
00030     while (iter != feature.end())
00031       itsSum += *iter++;
00032     return true;
00033   }
00034 
00035   //for other types if desired....but if left empty then we will attempt to convert to float
00036 
00037   float itsSum;
00038 };
00039 // ######################################################################
00040 // here is how you would make one generically... now, for all types in Types
00041 // functions will be defined. In the base implementaton, specialization for
00042 // other types not part of Types could be declared (for instance, if you want to
00043 // do something generically for all types but 1.
00044 // ######################################################################
00045 //define a recursive template
00046 template<typename... Types> class GenSumFunc;             
00047 //base case derives from ImageFunctor, accessor function and storage of data
00048 template<> struct GenSumFunc<> : public ImageFunctor       
00049 {
00050   float getSum() const { return itsSum; };
00051   float itsSum;
00052 
00053   //specializations for process go here by just defining the function
00054 };
00055 //recursive case creates our funcions
00056 template<typename T, typename... Tail>                    
00057 class GenSumFunc<T, Tail...> : public GenSumFunc<Tail...>
00058 {
00059 private:
00060   bool process(const Image<T>& feature)
00061   {
00062     //take the sum of the image
00063     T sum = T();
00064     typename Image<T>::const_iterator iter(feature.begin());
00065     while (iter != feature.end())
00066       sum += *iter++;
00067     
00068     GenSumFunc<>::itsSum = (float)sum;
00069     return true;
00070   }
00071 };
00072 
00073 // ######################################################################
00074 int main(const int argc, const char **argv)
00075 {
00076   //Fill a vector of generic images
00077   Image<float> I1(10,10,ZEROS);
00078   I1.setVal(1,1,10.0F);
00079   Image<double> I2(10,10,ZEROS);
00080   I2.setVal(1,1,9.0);
00081   Image<int> I3(10,10,ZEROS);
00082   I3.setVal(1,8);
00083 
00084   std::vector<GenericImage> fsv;//collectin of generic images
00085   fsv.push_back(GenericImage::make(I1));
00086   fsv.push_back(GenericImage::make(I2));
00087   fsv.push_back(GenericImage::make(I3));
00088 
00089   //iterate through and take the sum, allowing conversions to float and possibly
00090   //converting to others first depending on the order of the template
00091   //declaration:
00092   // element 1) direct call to the virtual function
00093   //
00094   // element 2) call the non-op double function (our SumFunc knows about
00095   // doubles, but didn't implement and function for them, which will dive
00096   // straight to the non-op base function, and then convert to float since float
00097   // is last in declaration (we try converting backwards) and it is implemented
00098   //
00099   // element 3) Dive straight to the non-op base function (GenericImage doesn't
00100   // know about ints), and then convert to float since float is last in
00101   // declaration (we try converting backwards) and it is implemented
00102   std::vector<GenericImage>::iterator i(fsv.begin());
00103   while (i != fsv.end())
00104     {
00105       SumFunc f; 
00106       (i++)->runProcessFunctor(f, true);//if the last argument is true, force conversion to float, otherwise no-op
00107       if (f.hasData())
00108         LINFO("%3.2f", f.getSum());
00109     }
00110 
00111   //No conversion for the first two elements se our template defines functions
00112   //for them automaticall, and then conversion if Image<int> to Image<float> as
00113   //in the above example;
00114   i = fsv.begin();
00115   while (i != fsv.end())
00116     {
00117       GenSumFunc<float, double> f; 
00118       (i++)->runProcessFunctor(f, true);//if the last argument is true, force conversion to float if we              
00119       if (f.hasData())                  //are not a float or double, otherwise no-op
00120         LINFO("%3.2f", f.getSum());
00121     }
00122 
00123   return 0;
00124 
00125 };
Generated on Sun May 8 08:40:39 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3