contrib/tbl/vipl/filter/vipl_filter.h

Go to the documentation of this file.
00001 // This is tbl/vipl/filter/vipl_filter.h
00002 #ifndef _vipl_filter_h_
00003 #define _vipl_filter_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007 //:
00008 // \file
00009 // Here is how the get/set macros are used.
00010 // First note there are 4 types of access:
00011 // for each of get and set we can do it with or without bounds/cache checking.
00012 // These are respectively defined in 4 macros:
00013 // GET_PIXEL SET_PIXEL FGET_PIXEL FSET_PIXEL (fast get...)
00014 // Arguments for GET_PIXEL and FGET_PIXEL are (x,y)  (i.e. column,row) and they return the value.
00015 // For SET_PIXEL FSET_PIXEL, the syntax is SET_PIXEL(x,y,value).
00016 // Note that SET_PIXEL is expected to return value!
00017 // We support operator() being the access, or if the used defines USE_NAMED_ACCESSORS, the named accessors.
00018 // For the named accessors the user can #define the names to use.
00019 // (And if they really want to, they can change the #defines for GET_PIXEL SET_PIXEL...
00020 //  but be careful as existing code uses the args in the given order.)
00021 
00022 #include "vipl_filter_abs.h"
00023 #include <vipl/filter/vipl_trivial_pixeliter.h>
00024 
00025 template < class ImgIn, class ImgOut, class DataIn, class DataOut, int Arity, class PixelItr = vipl_trivial_pixeliter >
00026  class vipl_filter ;
00027 
00028 #include <vipl/section/vipl_section_descriptor.h>
00029 #include <vipl/section/vipl_section_container.h>
00030 //#include <vipl/section/vipl_section_iterator.h>
00031 
00032 #include <vcl_stlfwd.h> // forward declaration for vcl_vector
00033 
00034 #ifdef USE_NAMED_ACCESSORS // cannot have both set,
00035 #undef USE_OPERATOR_ACCESSORS // to be safe if we have named we undefine operator()
00036 #else
00037 #ifndef USE_OPERATOR_ACCESSORS // if neither is set
00038 #define USE_NAMED_ACCESSORS    // use names by default
00039 #endif
00040 #endif
00041 
00042 #ifndef GET_NAME
00043 #define GET_NAME get_pixel
00044 #endif
00045 #ifndef SET_NAME
00046 #define SET_NAME set_pixel
00047 #endif
00048 #ifndef FGET_NAME
00049 #define FGET_NAME fget_pixel
00050 #endif
00051 #ifndef FSET_NAME
00052 #define FSET_NAME fset_pixel
00053 #endif
00054 #ifdef USE_OPERATOR_ACCESSORS
00055 // if not we use operator accessors
00056 #ifndef GET_PIXEL
00057 #define GET_PIXEL(img,x,y)  (img)(x,y)
00058 #endif
00059 #ifndef SET_PIXEL
00060 #define SET_PIXEL(img,x,y,expr)  (img)(x,y) = expr
00061 #endif
00062 #ifndef FGET_PIXEL
00063 #define FGET_PIXEL(img,x,y)  (img)(x,y)
00064 #endif
00065 #ifndef FSET_PIXEL
00066 #define FSET_PIXEL(img,x,y,expr)  (img)(x,y) = expr
00067 #endif
00068 #else // USE_NAMED_ACCESSORS
00069 #ifndef GET_PIXEL
00070 #define GET_PIXEL(img,x,y)  (img). GET_NAME (x,y)
00071 #endif
00072 #ifndef SET_PIXEL
00073 #define SET_PIXEL(img,x,y,expr)  (img). SET_NAME (expr, x,y)
00074 #endif
00075 #ifndef FGET_PIXEL
00076 #define FGET_PIXEL(img,x,y)  (img). FGET_NAME (x,y)
00077 #endif
00078 #ifndef FSET_PIXEL
00079 #define FSET_PIXEL(img,x,y,expr)  (img). FSET_NAME (expr, x,y)
00080 #endif
00081 #endif // end use NAMED ACCESSORS
00082 
00083 #ifndef CONVERT_TO_OUT
00084 #define CONVERT_TO_OUT(v) ((DataOut) (v))
00085 #endif
00086 // the include file below defines the type VIPL_FILTER_STATE
00087 #include "vipl_filter_helper.h" // for adding members by macros....
00088 
00089 class vipl_trivial_pixeliter;
00090 extern const void * DAhelp(vipl_trivial_pixeliter const*,int level=0);
00091 
00092 template < class ImgIn, class ImgOut, class DataIn, class DataOut, int Arity, class PixelItr >
00093 class vipl_filter          : public vipl_filter_abs
00094 {
00095   // declare some static consts....
00096   static const VIPL_FILTER_STATE Not_Ready      VCL_STATIC_CONST_INIT_INT_DECL(0);
00097   static const VIPL_FILTER_STATE Ready          VCL_STATIC_CONST_INIT_INT_DECL(1);
00098   static const VIPL_FILTER_STATE Unchanged      VCL_STATIC_CONST_INIT_INT_DECL(2);
00099   static const VIPL_FILTER_STATE Filter_Owned   VCL_STATIC_CONST_INIT_INT_DECL(4);
00100   // typedef iterators from our "iterator" class
00101 
00102  public: typedef typename PixelItr::Titerator Titerator;
00103  public: typedef typename PixelItr::Yiterator Yiterator;
00104  public: typedef typename PixelItr::Xiterator Xiterator;
00105  public: typedef typename PixelItr::Ziterator Ziterator;
00106  public: typedef vipl_filter_abs parent;
00107  public: typedef ImgIn const* inimagept; // make it easy to use.
00108  public: typedef ImgOut* outimagept; // make it easy to use.
00109  public: typedef vipl_filter thisclass; // needed for macro use
00110 
00111   //declare variable to hold "border" size for images.
00112   // May change to array in future (with argless accessor defaulting to largest)
00113  private: int hsimage_border_size;
00114  public: int image_border_size() const { return hsimage_border_size; }
00115  public: int & ref_image_border_size() { return hsimage_border_size; }
00116   // when too close to border what should we use as "fill" value.  It's up to
00117   // the filter implementer to "use" this value in their implementation so it
00118   // might get ignored...
00119  private: DataOut hsdef_fill_value;
00120  public: DataOut def_fill_value() const { return hsdef_fill_value; }
00121  public: DataOut & ref_def_fill_value() { return hsdef_fill_value; }
00122   // we track "state" for input, output and overall filter using these
00123   // ints. g++ had problems with nested enums as types outside of class
00124  private: VIPL_FILTER_STATE  hsinput_state;
00125  public: VIPL_FILTER_STATE input_state() const { return hsinput_state; }
00126  public: VIPL_FILTER_STATE & ref_input_state() { return hsinput_state; }
00127  private: VIPL_FILTER_STATE  hsfilter_state;
00128  public: VIPL_FILTER_STATE filter_state() const { return hsfilter_state; }
00129  public: VIPL_FILTER_STATE & ref_filter_state() { return hsfilter_state; }
00130  private: VIPL_FILTER_STATE  hsoutput_state;
00131  public: VIPL_FILTER_STATE output_state() const { return hsoutput_state; }
00132  public: VIPL_FILTER_STATE & ref_output_state() { return hsoutput_state; }
00133  public: void put_output_state(VIPL_FILTER_STATE const t) { hsoutput_state = t; }
00134   // how many input images are there.
00135  private: int hsnuminputs;
00136  public: int numinputs() const { return hsnuminputs; }
00137  public: int & ref_numinputs() { return hsnuminputs; }
00138   // how many output images are there. currently only 1 is allowed but this will change...
00139  private: int hsnumoutputs;
00140  public: int numoutputs() const { return hsnumoutputs; }
00141  public: int & ref_numoutputs() { return hsnumoutputs; }
00142   // raw "C" like array of pointers to input images
00143  private: vcl_vector<inimagept> hsinf;
00144  public: vcl_vector<inimagept> inf() const { return hsinf; }
00145  public: vcl_vector<inimagept> & ref_inf() { return hsinf; }
00146   // should be raw "C" like array of pointers to output images but
00147   // right now it is a direct pointer to the output image
00148  private: outimagept hsoutf;
00149  public: outimagept outf() const { return hsoutf; }
00150  public: outimagept & ref_outf() { return hsoutf; }
00151  public: void put_outf(outimagept const& t) { hsoutf = t; }
00152   // input section container.  Macros cannot handle commas so use typedef.
00153   // Assume one container works for all input images (implies multi-image filters cannot be ptr-safe.. FIXME)
00154   typedef vipl_section_container< DataIn >* in_section_type;
00155  private:   in_section_type hssrc_section;
00156  public: in_section_type src_section() const { return hssrc_section; }
00157  public: in_section_type & ref_src_section() { return hssrc_section; }
00158   // section descriptor for "current" input section
00159   typedef vipl_section_descriptor< DataIn >* in_descriptor_type;
00160  private:  in_descriptor_type hsinsecp;
00161  public: in_descriptor_type insecp() const { return hsinsecp; }
00162  public: in_descriptor_type & ref_insecp() { return hsinsecp; }
00163  public: void put_insecp(in_descriptor_type const t) { hsinsecp = t; }
00164   // output section container.  Macros cannot handle commas so use typedef
00165   typedef vipl_section_container< DataOut >* out_section_type;
00166  private:  out_section_type hsdst_section;
00167  public: out_section_type dst_section() const { return hsdst_section; }
00168  public: out_section_type & ref_dst_section() { return hsdst_section; }
00169   // section descriptor for "current" output section
00170   typedef vipl_section_descriptor< DataOut>* out_descriptor_type;
00171  private:  out_descriptor_type hssecp;
00172  public: out_descriptor_type secp() const { return hssecp; }
00173  public: out_descriptor_type & ref_secp() { return hssecp; }
00174  public: void put_secp(out_descriptor_type t) { hssecp = t; }
00175   // section descriptor for input ROA
00176   typedef vipl_section_descriptor< DataIn >* in_ROA_descriptor_type;
00177  private:  in_ROA_descriptor_type hsinROA;
00178  public: in_ROA_descriptor_type inROA() const { return hsinROA; }
00179  public: in_ROA_descriptor_type & ref_inROA() { return hsinROA; }
00180   // section descriptor for output ROA
00181   typedef vipl_section_descriptor< DataOut >* out_ROA_descriptor_type;
00182  private:  out_ROA_descriptor_type hsROA;
00183  public: out_descriptor_type ROA() const { return hsROA; }
00184  public: out_descriptor_type & ref_ROA() { return hsROA; }
00185   // if false (default) the ROA is taken from output image
00186   // if true, it is taken from the input image.
00187  private:  bool hsis_input_driven;
00188  public: bool is_input_driven() const { return hsis_input_driven; }
00189  public: bool & ref_is_input_driven() { return hsis_input_driven; }
00190  public: void put_is_input_driven(bool b=true) { hsis_input_driven=b; }
00191 
00192  public:
00193   //:
00194   // A workhorse constructor for this abstract class. If dst_image
00195   // (by default) the output will be generated automatically when
00196   // filtering is about to proceed. (Either way, the filter
00197   // increments refcount when set and decrements the refcount of
00198   // the output when it is destroyed.) Some filters support
00199   // multiple inputs, if ninputs is >1 then this constructor expects
00200   // src_img to be the first element pointer to the input
00201   // (i.e. src_img+1 is the location of input image2). Note that
00202   // the filter keeps pointers to the input (properly refcounted).
00203   vipl_filter(ImgIn const* src_img,
00204               ImgOut* dst_img=0,
00205               int ninputs=1,
00206               int img_border=0 ,
00207               DataOut fill_val=0 ) ;
00208   //:
00209   // A second workhorse constructor for this abstract class. If
00210   // dst_img is null (by default), the output will be generated
00211   // automatically when filtering is about to proceed. The filter
00212   // decrements the refcount of the output when it is
00213   // destroyed. Some filters support multiple inputs, if ninputs is
00214   // >1 then this constructor uses non_consecutive input images (with
00215   // their address in a c_vector, i.e. *(src_img+1) is the location
00216   // of input image2). Note that the filter keeps pointers to the
00217   // input (properly refcounted).
00218   vipl_filter(ImgIn const** src_img,
00219               ImgOut* dst_img=0,
00220               int ninputs=1,
00221               int img_border=0 ,
00222               DataOut fill_val=0 );
00223   virtual ~vipl_filter();
00224   vipl_filter();
00225   vipl_filter(vipl_filter< ImgIn, ImgOut, DataIn, DataOut, Arity, PixelItr > const&);
00226 
00227   // begin method list for class filter
00228 
00229   //:
00230   // The main operation of the class, filters input images to
00231   // produce output image.
00232   // Before this function can run to completion, all arguments must
00233   // be set via the respective ``put_*'' functions (or
00234   // be supplied at construction time). Particularly important is
00235   // the filter input. The programmer should take a look at the
00236   // concrete child classes of filter to see what additional
00237   // parameters they need before the actual filter operation can
00238   // proceed.
00239   virtual bool filter();
00240 
00241   //:
00242   // For those filters that only need one input and output set (after
00243   // construction), the following function allows one to treat the filter
00244   // object more like a function calling
00245   // obj.process(inimg, outimg)
00246   // will set the input and output then call filter()
00247   // It does not require pointers but takes the address of its
00248   // inputs, set the fields in the filter
00249   // does the filter and un-sets the in/out fields in the filter.
00250   bool process(ImgIn const& inimg, ImgOut& outimg);
00251   // second form passing pointers...
00252   bool process(ImgIn const* inimg, ImgOut* outimg);
00253 
00254   //: The ``start'' coordinate for the current apply section.
00255   // This always leaves a border around the
00256   // section. (E.g. if there is no ROA this is actual section start
00257   // + image_boarder_size; remember section iteration overlaps). If
00258   // the current section is outside the ROA, the section_start and
00259   // section_end may be equal.
00260   int start(int axis) const;
00261   int start(int axis, int other_axis_value) const;
00262 
00263   //: The ``stopping'' coordinate for the current apply section.
00264   // This always leaves a border around the
00265   // section. (E.g. if there is no ROA this is actual section end -
00266   // image_boarder_size; remember section iteration overlaps). If
00267   // the current section is outside the ROA, the section_start and
00268   // section_end may be equal.
00269   int stop(int axis) const;
00270   int stop(int axis, int other_axis_value) const;
00271 
00272   //: The ``start'' coordinate for the current source apply section.
00273   // This always leaves a border around the
00274   // section. (E.g. if there is no ROA this is actual section start
00275   // + image_boarder_size; remember section iteration overlaps). If
00276   // the current section is outside the ROA, the section_start and
00277   // section_end may be equal.
00278   int start_src(int axis) const;
00279 
00280   //: The ``stopping'' coordinate for the current source apply section.
00281   // This always leaves a border around the
00282   // section. (E.g. if there is no ROA this is actual section end -
00283   // image_boarder_size; remember section iteration overlaps). If
00284   // the current section is outside the ROA, the section_start and
00285   // section_end may be equal.
00286   int stop_src(int axis) const;
00287 
00288   //: The ``start'' coordinate for the current destination apply section.
00289   // This always leaves a border around the
00290   // section. (E.g. if there is no ROA this is actual section start
00291   // + image_boarder_size; remember section iteration overlaps). If
00292   // the current section is outside the ROA, the section_start and
00293   // section_end may be equal.
00294   int start_dst(int axis) const;
00295 
00296   //: The ``stopping'' coordinate for the current destination apply section.
00297   // This always leaves a border around the
00298   // section. (E.g. if there is no ROA this is actual section end -
00299   // image_boarder_size; remember section iteration overlaps). If
00300   // the current section is outside the ROA, the section_start and
00301   // section_end may be equal.
00302   int stop_dst(int axis) const;
00303 
00304 
00305   //:
00306   // Put the given pointer into an input "image" at the provided
00307   // index. Decrements old objects refcount, increments
00308   // newobjects refcount
00309   bool put_in_data_ptr(ImgIn const* fpointer, int index=0);
00310 
00311   //:
00312   // Return a smart pointer to the input ``image'' at the
00313   // provided index. Increments refcount before returning
00314   inimagept in_data_ptr( int index=0);
00315 
00316   //:
00317   // Return a ref to the input ``data object'' at the provided
00318   // index (dereferences the internal pointer).
00319   const ImgIn& in_data( int index=0) const ;
00320 
00321   //:
00322   // Put the given pointer into output data at the given index
00323   // location Decrements old putput refcount, Inc's newobjects
00324   // refcount
00325   bool put_out_data_ptr(ImgOut* fpointer, int /*index*/=0);
00326 
00327   //:
00328   // Get ptr to specified output data item given index
00329   // location. Inc's refcount before returning ptr
00330   virtual outimagept out_data_ptr(int index=0);
00331 
00332   //:
00333   // Get ref to specified output data item given index location
00334   virtual ImgOut& out_data(int index=0) const;
00335 
00336  protected:
00337 
00338   //:
00339   // This is the function that gets called for every iteration of
00340   // the filtering operation, before the actual filtering
00341   // routine. Can be used for normalization or such. Default op is
00342   // noop
00343   virtual bool preop();
00344 
00345   //:
00346   // This is the function that gets called after every iteration of
00347   // the actual filtering routine. Can be used for post_processing
00348   // normalization or cleaning up the edges. Default op is noop
00349   virtual bool postop();
00350 
00351   //:
00352   // This is the method that implements the basic form for the
00353   // filtering operation.
00354   virtual bool applyop() = 0;
00355 
00356   //:
00357   // For each section, this method runs before
00358   // section_applyop. Default at this level is no_op. (lower level
00359   // class redefine it to ``fill'' the image boarders).
00360   virtual bool section_preop();
00361 
00362   //:
00363   // For each section, this method runs after
00364   // section_applyop. Default is no_op
00365   virtual bool section_postop();
00366 
00367   //:
00368   // This is the method that implements the filtering inside each
00369   // section. You must supply this function.
00370   // pure virtual function
00371   virtual bool section_applyop() = 0;
00372 
00373   //:
00374   // If a section is pointer safe, then this function is called to
00375   // filter it. default is just to call section_applyop
00376   virtual bool ptr_based_section_applyop();
00377 
00378   //:
00379   // Called by filter(). checks for input/output
00380   // being set.  User can make it check for additional
00381   // parameters required before the filtering operation can
00382   // proceed.  Allows filter to "proceed" on warnings so not public
00383   virtual bool check_params_1(bool& proceed_on_warn) const ;
00384 
00385  public:
00386 
00387   //:
00388   // returns if the filter is "ready" to run, i.e. all needed
00389   // parameters are "set".  Default just calls check_parms_1()
00390   virtual bool is_ready() const;
00391 
00392   //:
00393   // Is the current apply section intersected with the ROA an empty
00394   // region, if so we should not load it. If its empty there is no
00395   // guarantee that the section_start and section_end will not overlap.
00396   int is_section_within_ROA( int axis) const;
00397 
00398 #ifdef USE_COMPOSE_WITH
00399   //:
00400   // Try to set the output of this filter to be the input of
00401   // ``to'', and if possible make the filtering more efficient than
00402   // just sequential calls. Currently unimplemented so far this
00403   // function does nothing. Arg should be a nonconst ref because
00404   // composition may change the filter!.
00405   bool compose_with( vipl_filter_abs& to);
00406 #endif
00407 
00408 }; // end of class definition
00409 
00410 #ifdef INSTANTIATE_TEMPLATES
00411 #include "vipl_filter.txx"
00412 #endif
00413 
00414 #endif // file guard

Generated on Tue Oct 14 05:13:27 2008 for contrib/tbl/vipl by  doxygen 1.5.1