TuttleOFX
1
|
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