PICCANTE  0.4
The hottest HDR imaging library!
histogram_matching.hpp
Go to the documentation of this file.
1 /*
2 
3 PICCANTE
4 The hottest HDR imaging library!
5 http://vcg.isti.cnr.it/piccante
6 
7 Copyright (C) 2014
8 Visual Computing Laboratory - ISTI CNR
9 http://vcg.isti.cnr.it
10 First author: Francesco Banterle
11 
12 This Source Code Form is subject to the terms of the Mozilla Public
13 License, v. 2.0. If a copy of the MPL was not distributed with this
14 file, You can obtain one at http://mozilla.org/MPL/2.0/.
15 
16 */
17 
18 #ifndef PIC_ALGORITHMS_HISTOGRAM_MATCHING_HPP
19 #define PIC_ALGORITHMS_HISTOGRAM_MATCHING_HPP
20 
21 #include "../base.hpp"
22 
23 #include "../image.hpp"
24 #include "../image_vec.hpp"
25 #include "../histogram.hpp"
26 
27 #include "../util/std_util.hpp"
28 
29 namespace pic {
30 
32 {
33 protected:
34  int nBin;
35  bool bClipping;
36  float clip_value;
37 
45  void computeHistograms(Image *img_s, Image *img_t,
46  Histogram *hist_s, Histogram *hist_t)
47  {
48 
49  if(img_s == NULL) {
50  return;
51  }
52 
53  int channels = img_s->channels;
54  uint clip_value_ui = uint(clip_value * float(img_s->nPixels() / nBin));
55 
56  for(int i = 0; i < channels; i++) {
57  hist_s[i].calculate(img_s, VS_LIN, nBin, NULL, i);
58 
59  if(img_t != NULL) {
60  hist_t[i].calculate(img_t, VS_LIN, nBin, NULL, i);
61  } else {
62  uint value = MAX(img_s->nPixels() / nBin, 1);
63 
64  hist_t[i].uniform(hist_s[i].getfMin(),
65  hist_s[i].getfMax(),
66  value, VS_LIN, nBin);
67  }
68  if(bClipping) {
69  hist_s[i].clip(clip_value_ui);
70  hist_t[i].clip(clip_value_ui);
71  }
72  }
73  }
74 
82  void computeLUT(Histogram *hist_s, Histogram *hist_t, int channels, std::vector<int *> &lut)
83  {
84  for(int i = 0 ; i < channels; i++) {
85  hist_s[i].cumulativef(true);
86  hist_t[i].cumulativef(true);
87 
88  float *c_s = hist_s[i].getCumulativef();
89  float *c_t = hist_t[i].getCumulativef();
90 
91  int *tmp_lut = new int[nBin];
92 
93  for(int j = 0; j < nBin; j++) {
94  float x = c_s[j];
95  float *ptr = std::upper_bound(c_t, c_t + nBin, x);
96  tmp_lut[j] = MAX((int)(ptr - c_t), 0);
97  }
98 
99  lut.push_back(tmp_lut);
100  }
101  }
102 
103 public:
104 
109  {
110  update(256, -1.0f);
111  }
112 
118  void update(int nBin, float clip_value = 1.0f)
119  {
120  this->nBin = nBin > 1 ? nBin : 256;
121  this->clip_value = clip_value;
122  bClipping = clip_value > 0.0f;
123  }
124 
131  Image *Process(ImageVec imgIn, Image *imgOut = NULL)
132  {
133  Image *img_source = NULL; //imgIn[0]
134  Image *img_target = NULL; //imgIn[1]
135 
136  int count = 0;
137  if(ImageVecCheck(imgIn, 1)) {
138  img_source = imgIn[0];
139  count = 1;
140  }
141 
142  if(ImageVecCheck(imgIn, 2)) {
143  img_target = imgIn[1];
144 
145  if(imgIn[0]->channels != imgIn[1]->channels) {
146  return imgOut;
147  }
148  count = 2;
149  }
150 
151  if(count == 0) {
152  return imgOut;
153  }
154 
155  count--;
156 
157  if(imgOut == NULL) {
158  imgOut = imgIn[count]->clone();
159  } else {
160  if(!imgOut->isSimilarType(imgIn[count])) {
161  imgOut = imgIn[count]->allocateSimilarOne();
162  }
163  }
164 
165  int channels = img_source->channels;
166 
167  Histogram *h_source = new Histogram[channels];
168  Histogram *h_target = new Histogram[channels];
169 
170 
171  computeHistograms(img_source, img_target, h_source, h_target);
172  std::vector<int *> lut;
173  computeLUT(h_source, h_target, channels, lut);
174 
175  for(int i = 0; i < imgOut->size(); i += channels) {
176 
177  for(int j = 0; j < channels; j++) {
178  int k = i + j;
179 
180  int ind_source = h_source[j].project(img_source->data[k]);
181 
182  int ind_target = lut[j][ind_source];
183 
184  imgOut->data[k] = h_target[j].unproject(ind_target);
185  }
186  }
187 
188  delete[] h_source;
189  delete[] h_target;
190 
191  stdVectorArrayClear(lut);
192 
193  return imgOut;
194  }
195 
203  static Image* execute(Image *img_source, Image *img_target, Image *imgOut = NULL)
204  {
206  imgOut = hm.Process(Double(img_source, img_target), imgOut);
207  return imgOut;
208  }
209 
217  static Image* executeEqualization(Image *img, Image *imgOut = NULL, float clip_value = 0.9f)
218  {
220  hm.update(256, clip_value);
221  imgOut = hm.Process(Double(img, NULL), imgOut);
222  return imgOut;
223  }
224 };
225 
226 } // end namespace pic
227 
228 #endif /* PIC_ALGORITHMS_HISTOGRAM_MATCHING_HPP */
229 
PIC_INLINE bool ImageVecCheck(ImageVec &imgIn, int minInputImages)
ImageVecCheck.
Definition: image_vec.hpp:147
unsigned int uint
Definition: base.hpp:23
float * cumulativef(bool bNormalized)
cumulativef computes the cumulative Histogram.
Definition: histogram.hpp:440
void update(int nBin, float clip_value=1.0f)
update
Definition: histogram_matching.hpp:118
void calculate(Image *imgIn, VALUE_SPACE type=VS_LIN, int nBin=256, BBox *box=NULL, int channel=0)
calculate computes the histogram of an input image. In the case of LDR images, they are ssumed to be ...
Definition: histogram.hpp:213
float * data
data is the main buffer where pixel values are stored.
Definition: image.hpp:91
int channels
Definition: image.hpp:80
std::vector< Image * > ImageVec
ImageVec an std::vector of pic::Image.
Definition: image_vec.hpp:29
The Histogram class is a class for creating, managing, loading, and saving histogram for an Image...
Definition: histogram.hpp:37
Image * Process(ImageVec imgIn, Image *imgOut=NULL)
Process.
Definition: histogram_matching.hpp:131
static Image * execute(Image *img_source, Image *img_target, Image *imgOut=NULL)
execute
Definition: histogram_matching.hpp:203
static Image * executeEqualization(Image *img, Image *imgOut=NULL, float clip_value=0.9f)
executeEqualization
Definition: histogram_matching.hpp:217
Definition: histogram_matching.hpp:31
float clip_value
Definition: histogram_matching.hpp:36
void stdVectorArrayClear(std::vector< T *> &vec)
stdVectorArrayClear
Definition: std_util.hpp:71
void clip(uint value)
clip clips the histogram to value.
Definition: histogram.hpp:409
float * getCumulativef()
getCumulativef this function returns the cumulative Histogram. Note that cumulativef needs to be comp...
Definition: histogram.hpp:459
bool bClipping
Definition: histogram_matching.hpp:35
int nPixels() const
nPixels computes the number of pixels.
Definition: image.hpp:499
int project(float x)
project converts an input value in the histogram domain.
Definition: histogram.hpp:337
PIC_INLINE ImageVec Double(Image *img1, Image *img2)
Double creates an std::vector which contains img1 and img2; this is for filters input.
Definition: image_vec.hpp:49
Definition: histogram.hpp:31
float unproject(int ind)
unproject converts a histogram value back to its original domain.
Definition: histogram.hpp:352
void computeLUT(Histogram *hist_s, Histogram *hist_t, int channels, std::vector< int *> &lut)
computeLUT
Definition: histogram_matching.hpp:82
The Image class stores an image as buffer of float.
Definition: image.hpp:60
void computeHistograms(Image *img_s, Image *img_t, Histogram *hist_s, Histogram *hist_t)
computeHistograms
Definition: histogram_matching.hpp:45
Image * clone() const
Clone creates a deep copy of the calling instance.
Image * allocateSimilarOne()
allocateSimilarOne creates an Image with similar size of the calling instance.
Definition: bilateral_separation.hpp:25
#define MAX(a, b)
Definition: math.hpp:73
HistogramMatching()
HistogramMatching.
Definition: histogram_matching.hpp:108
void uniform(float fMin, float fMax, uint value, VALUE_SPACE type, int nBin)
uniform
Definition: histogram.hpp:298
int nBin
Definition: histogram_matching.hpp:34