TuttleOFX  1
SelectionAverage.hpp
Go to the documentation of this file.
00001 #ifndef SELECTIONAVERAGE_HPP
00002 #define SELECTIONAVERAGE_HPP
00003 
00004 #include "ColorCubeViewerDefinitions.hpp"
00005 #include "GeodesicForm.hpp"
00006 
00007 #include <tuttle/plugin/memory/OfxAllocator.hpp>
00008 #include <boost/gil/channel_algorithm.hpp>
00009 #include <terry/numeric/operations.hpp>
00010 #include <terry/numeric/operations_assign.hpp>
00011 #include <terry/numeric/assign.hpp>
00012 #include <terry/numeric/init.hpp>
00013 
00014 namespace tuttle {
00015 namespace plugin {
00016 namespace colorCubeViewer {
00017 
00018 typedef boost::gil::rgba32f_view_t SView;
00019 typedef boost::gil::rgba32f_pixel_t SPixel;
00020 typedef std::vector<float, OfxAllocator<float> > DataVector;
00021 
00022 //Functor used to compute average on color clip selection
00023 template<class View, typename CType = boost::gil::bits64f>
00024 struct ComputeAverage
00025 {
00026         typedef typename View::value_type Pixel;
00027         typedef typename boost::gil::color_space_type<View>::type Colorspace;
00028         typedef boost::gil::pixel<CType, boost::gil::layout<Colorspace> > CPixel; // the pixel type use for computation (using input colorspace)
00029 
00030         CPixel operator()( const View& image )
00031         {
00032                 using namespace boost::gil;
00033                 using namespace terry;
00034                 using namespace terry::numeric;
00035                 std::size_t nbPixels = 0; 
00036                 CPixel sum; //sum of each pixel
00037                 pixel_zeros_t<CPixel>( )( sum ); //set sum to 0
00038 
00039                 for( int y = 0;                                 //for each lines
00040                      y < image.height();
00041                      ++y )
00042                 {
00043                         typename View::x_iterator src_it = image.x_at( 0, y );
00044                         for( int x = 0;
00045                              x < image.width();
00046                              ++x, ++src_it )            // for each pixels in a line
00047                         {
00048                                 CPixel pix;     //initialize a container pixel
00049                                 pixel_assigns_t<Pixel, CPixel>( )( * src_it, pix ); // pix = src_it;
00050                                 
00051                                 if(pix[3] == 1) //if current pixel is selected (alpha channel == 1)
00052                                 {
00053                                         pixel_plus_assign_t<CPixel, CPixel>( )( pix, sum ); // sum += pix;
00054                                         ++nbPixels; //increments number of selected pixel
00055                                 }
00056                         }
00057                 }
00058                 if(nbPixels != 0) // if any selected pixel has been added
00059                         sum = pixel_divides_scalar_t<CPixel, double>() ( sum, nbPixels ); //compute average average (sum/nbPixels)
00060                 return  sum; //return average (or (0,0,0) pixel)
00061         }
00062 
00063 };
00064 
00065 
00066 //Functor : extend the geodesicForm with selection (only alpha channel)
00067 struct Pixel_extend_GeodesicForm
00068 {
00069         //Arguments
00070     GeodesicForm& _data; //buffer to fill up
00071         
00072         //Constructor
00073         Pixel_extend_GeodesicForm(GeodesicForm& data)
00074         :_data( data )
00075         {
00076         }
00077         //Operator ()
00078         template< typename Pixel>
00079     Pixel operator()( const Pixel& p )
00080     {
00081         using namespace boost::gil;     
00082                 //RGB only
00083                 if(p[3] == 1) //current pixel is in the selection
00084                 {
00085                         //construct current point
00086                         Ofx3DPointD point; //initialize
00087                         point.x = p[0]; //(x == red)
00088                         point.y = p[1]; //(y == green)
00089                         point.z = p[2]; //(z == blue)
00090                         
00091                         //extend geodesicForm
00092                         _data.extendOnePoint(point); //extends geodesic form (point is already into geodesic form checked)
00093                 }
00094         return p;
00095     }
00096 };
00097 
00098 
00099 
00100 class SelectionAverage {
00101 public:
00102         //Arguments
00103         Ofx3DPointD _averageValue;              //Average of the selection color clip (selection)
00104         OfxTime _time;                                  //current time in sequence
00105 public:
00106         //Constructor (initialize value to 0)
00107         SelectionAverage(OfxTime time);
00108         
00109         //Draw average value on screen (cross)
00110         void draw();
00111         //Generate average from color selection clip
00112         bool computeAverageSelection(OFX::Clip* clipColor, const OfxPointD& renderScale);
00113         
00114         //Extends a geodesic form with the selection
00115         void extendGeodesicForm(OFX::Clip* clipColor, const OfxPointD& renderScale, GeodesicForm& geodesicForm);
00116 };
00117 
00118 }
00119 }
00120 }
00121 
00122 #endif  /* SELECTIONAVERAGE_HPP */
00123