Subversion Repositories OpenCV2-Cookbook

Rev

Rev 3 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 PointedEar 1
#if !defined HISTOGRAM
2
#define HISTOGRAM
3
 
5 PointedEar 4
#include <opencv2/core/core.hpp>
5
#include <opencv2/imgproc/imgproc.hpp>
3 PointedEar 6
 
7
class Histogram1D {
8
 
9
  private:
10
 
11
    int histSize[1];
12
        float hranges[2];
13
    const float* ranges[1];
14
    int channels[1];
15
 
16
  public:
17
 
18
        Histogram1D() {
19
 
20
                // Prepare arguments for 1D histogram
21
                histSize[0]= 256;
22
                hranges[0]= 0.0;
23
                hranges[1]= 255.0;
24
                ranges[0]= hranges;
25
                channels[0]= 0; // by default, we look at channel 0
26
        }
27
 
28
        // Sets the channel on which histogram will be calculated.
29
        // By default it is channel 0.
30
        void setChannel(int c) {
31
 
32
                channels[0]= c;
33
        }
34
 
35
        // Gets the channel used.
36
        int getChannel() {
37
 
38
                return channels[0];
39
        }
40
 
41
        // Sets the range for the pixel values.
42
        // By default it is [0,255]
43
        void setRange(float minValue, float maxValue) {
44
 
45
                hranges[0]= minValue;
46
                hranges[1]= maxValue;
47
        }
48
 
49
        // Gets the min pixel value.
50
        float getMinValue() {
51
 
52
                return hranges[0];
53
        }
54
 
55
        // Gets the max pixel value.
56
        float getMaxValue() {
57
 
58
                return hranges[1];
59
        }
60
 
61
        // Sets the number of bins in histogram.
62
        // By default it is 256.
63
        void setNBins(int nbins) {
64
 
65
                histSize[0]= nbins;
66
        }
67
 
68
        // Gets the number of bins in histogram.
69
        int getNBins() {
70
 
71
                return histSize[0];
72
        }
73
 
74
        // Computes the 1D histogram.
75
        cv::MatND getHistogram(const cv::Mat &image) {
76
 
77
                cv::MatND hist;
78
 
79
                // Compute histogram
80
                cv::calcHist(&image,
81
                        1,                      // histogram of 1 image only
82
                        channels,       // the channel used
83
                        cv::Mat(),      // no mask is used
84
                        hist,           // the resulting histogram
85
                        1,                      // it is a 1D histogram
86
                        histSize,       // number of bins
87
                        ranges          // pixel value range
88
                );
89
 
90
                return hist;
91
        }
92
 
93
        // Computes the 1D histogram and returns an image of it.
94
        cv::Mat getHistogramImage(const cv::Mat &image){
95
 
96
                // Compute histogram first
97
                cv::MatND hist= getHistogram(image);
98
 
99
                // Get min and max bin values
100
                double maxVal=0;
101
                double minVal=0;
102
                cv::minMaxLoc(hist, &minVal, &maxVal, 0, 0);
103
 
104
                // Image on which to display histogram
105
                cv::Mat histImg(histSize[0], histSize[0], CV_8U,cv::Scalar(255));
106
 
107
                // set highest point at 90% of nbins
108
                int hpt = static_cast<int>(0.9*histSize[0]);
109
 
110
                // Draw vertical line for each bin 
111
                for( int h = 0; h < histSize[0]; h++ ) {
112
 
113
                        float binVal = hist.at<float>(h);
114
                        int intensity = static_cast<int>(binVal*hpt/maxVal);
115
                        cv::line(histImg,cv::Point(h,histSize[0]),cv::Point(h,histSize[0]-intensity),cv::Scalar::all(0));
116
                }
117
 
118
                return histImg;
119
        }
120
 
121
        // Equalizes the source image.
122
        cv::Mat equalize(const cv::Mat &image) {
123
 
124
                cv::Mat result;
125
                cv::equalizeHist(image,result);
126
 
127
                return result;
128
        }
129
 
130
        // Stretches the source image.
131
        cv::Mat stretch(const cv::Mat &image, int minValue=0) {
132
 
133
                // Compute histogram first
134
                cv::MatND hist= getHistogram(image);
135
 
136
                // find left extremity of the histogram
137
                int imin= 0;
138
                for( ; imin < histSize[0]; imin++ ) {
139
                        std::cout<<hist.at<float>(imin)<<std::endl;
140
                        if (hist.at<float>(imin) > minValue)
141
                                break;
142
                }
143
 
144
                // find right extremity of the histogram
145
                int imax= histSize[0]-1;
146
                for( ; imax >= 0; imax-- ) {
147
 
148
                        if (hist.at<float>(imax) > minValue)
149
                                break;
150
                }
151
 
152
                // Create lookup table
153
                int dims[1]={256};
154
                cv::MatND lookup(1,dims,CV_8U);
155
 
156
                for (int i=0; i<256; i++) {
157
 
158
                        if (i < imin) lookup.at<uchar>(i)= 0;
159
                        else if (i > imax) lookup.at<uchar>(i)= 255;
160
                        else lookup.at<uchar>(i)= static_cast<uchar>(255.0*(i-imin)/(imax-imin)+0.5);
161
                }
162
 
163
                // Apply lookup table
164
                cv::Mat result;
165
                result= applyLookUp(image,lookup);
166
 
167
                return result;
168
        }
169
 
170
        // Applies a lookup table transforming an input image into a 1-channel image
171
        cv::Mat applyLookUp(const cv::Mat& image, const cv::MatND& lookup) {
172
 
173
                // Set output image (always 1-channel)
174
                cv::Mat result(image.rows,image.cols,CV_8U);
175
                cv::Mat_<uchar>::iterator itr= result.begin<uchar>();
176
 
177
                // Iterates over the input image
178
                cv::Mat_<uchar>::const_iterator it= image.begin<uchar>();
179
                cv::Mat_<uchar>::const_iterator itend= image.end<uchar>();
180
 
181
                // Applies lookup to each pixel
182
                for ( ; it!= itend; ++it, ++itr) {
183
 
184
                        *itr= lookup.at<uchar>(*it);
185
                }
186
 
187
                return result;
188
        }
189
};
190
 
191
 
192
#endif