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