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_