contrib/tbl/vipl/vipl_histogram.h
Go to the documentation of this file.
00001 // This is tbl/vipl/vipl_histogram.h
00002 #ifndef vipl_histogram_h_
00003 #define vipl_histogram_h_
00004 //:
00005 // \file
00006 // \brief pixel value histogram of 2D image
00007 //
00008 // \author Peter Vanroose, K.U.Leuven (ESAT/PSI)
00009 // \date   15 November 1997.
00010 //
00011 // \verbatim
00012 //  Modifications:
00013 //   Terry Boult - December 1997 - remark added to documentation
00014 //   Peter Vanroose, Aug.2000 - adapted to vxl
00015 // \endverbatim
00016 //
00017 // \example examples/example_histogram.cxx
00018 
00019 #include <vipl/filter/vipl_filter_2d.h> // parent class
00020 
00021 //: Pixel value histogram of 2D image.
00022 //   This image processing class creates a pixel value histogram of a 2D image
00023 //   and writes it into a "1D" image (actually a row of a 2D image).
00024 //   It is implemented using the vipl filters,
00025 //   which means that it can be used with any image class (vxl or not)
00026 //   of any pixel data type.
00027 //
00028 //   The constructor takes three (defaulted) arguments:
00029 //   the scaling SI to be applied to the input pixel values,
00030 //   the translation (shift) SHI to be applied to the input pixel values,
00031 //   and the scaling SO to be applied to the output histogram values.
00032 //   By default, of course, SI=1, SHI=0 and SO=1.
00033 //
00034 //   By specifying SI, one actually specifies the bin size of the histogram:
00035 //   e.g., SI=10 means that all pixel values in the range (e.g.) 15 to 25 (15
00036 //   exclusive, 25 inclusive) contribute to the same histogram count (bin 2).
00037 //   Clearly, for `int'-like pixels, the natural value for SI is 1, but
00038 //   for float pixels, SI should be set to a reasonable bin size.
00039 //
00040 //   Combined with SI, one can set SHI to set the boundaries of those bins:
00041 //   e.g., SI=10 and SHI=15 will map pixels values in the range 0 to 10 to
00042 //   histogram bin 2.
00043 //
00044 //   The third parameter, SO, re-scales the value of the output bin count.
00045 //   When set to 1 (the default), the pixel values of the output image are
00046 //   the (integer) pixel counts of the bin which they represent. Thus
00047 //   the `natural' output pixel type is int.  If this is not desired, SO
00048 //   can be set to make sure that the histogram values fall within the
00049 //   pixel value range of the output data type.
00050 //
00051 //   The there are two other attributes, not specified in the constructor,
00052 //   which default to 0.
00053 //   The first, indexout defines what row of the output image will be used
00054 //   for the actual storage of the histogram values.  By making the output
00055 //   image multi-row and changing this the same filter can do multiple
00056 //   histograms.
00057 //
00058 //   The final attribute, checkrange is a boolean that determines if the
00059 //   histogram should do range checking on bin access.  This can be useful
00060 //   for float images. if a value is below the first image access or above
00061 //   the last, it's set to the extremal value.
00062 //
00063 //   Note it does not limit the maximum of bins so they may wrap around for
00064 //   unsigned and accessing a small number of bins from a large dynamic range
00065 //   image may segfault if check bounds is not turned on (off by default).
00066 //
00067 //   TB says: Note this example does not work unless output image (the
00068 //   histogram) is same size as input image.  This will be fixed when ROI's
00069 //   are update to be either input or output driven.  (They are currently
00070 //   output driven, so only the input pixels corresponding to the output
00071 //   image size are considered.  TB made various mods for newgen and IUE
00072 //   consistency and allow one to chose which "column" in the 2D output image
00073 //   was used to store the histogram.
00074 //
00075 template <class ImgIn,class ImgOut,class DataIn,class DataOut, VCL_DFL_TYPE_PARAM_STLDECL(PixelItr, vipl_trivial_pixeliter) >
00076 class vipl_histogram : public vipl_filter_2d<ImgIn,ImgOut,DataIn,DataOut,PixelItr>
00077 {
00078   // -+-+- data members: -+-+-
00079  public: DataIn scalein_;
00080  public: DataIn scalein() const { return scalein_; }
00081  public: DataIn shiftin_;
00082  public: DataIn shiftin() const { return shiftin_; }
00083  public: DataOut scaleout_;
00084  public: DataOut scaleout() const { return scaleout_; }
00085 
00086   // the column of 2D "image" do we store the histogram
00087  public: int indexout_;
00088  public: int indexout() const { return indexout_; }
00089  public: bool checkrange_;
00090  public: bool checkrange() const { return checkrange_; }
00091 
00092   // -+-+- constructors/destructors: -+-+-
00093  public:
00094   inline vipl_histogram(DataIn si=1, DataIn shi=0, DataOut so=1)
00095            : vipl_filter_2d<ImgIn,ImgOut,DataIn,DataOut,PixelItr>()
00096            , scalein_(si)
00097            , shiftin_(shi)
00098            , scaleout_(so)
00099            , indexout_(0)
00100            , checkrange_(0)
00101       {
00102         this->put_is_input_driven(true); // get sections from input
00103       }
00104 
00105   inline vipl_histogram(vipl_histogram const& A)
00106            : vipl_filter_2d<ImgIn,ImgOut,DataIn,DataOut,PixelItr>(A)
00107            , scalein_(A.scalein())
00108            , shiftin_(A.shiftin())
00109            , scaleout_(A.scaleout())
00110            , indexout_(A.indexout_)
00111            , checkrange_(A.checkrange_)
00112       {
00113         this->put_is_input_driven(true); // get sections from input
00114       }
00115   inline ~vipl_histogram() {}
00116 
00117 // -+-+- required method for filters: -+-+-
00118   bool section_applyop();
00119 
00120   //: Use the preop stage to zero this histogram.
00121   bool section_preop();
00122 };
00123 
00124 #ifdef INSTANTIATE_TEMPLATES
00125 #include "vipl_histogram.txx"
00126 #endif
00127 
00128 #endif // vipl_histogram_h_