PICCANTE  0.4
The hottest HDR imaging library!
ssim_index.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_METRICS_SSIM_INDEX_HPP
19 #define PIC_METRICS_SSIM_INDEX_HPP
20 
21 #include <math.h>
22 
23 #include "../base.hpp"
24 #include "../image.hpp"
25 #include "../util/math.hpp"
26 #include "../metrics/base.hpp"
27 
28 #include "../util/array.hpp"
29 #include "../util/std_util.hpp"
30 
31 #include "../filtering/filter_luminance.hpp"
32 #include "../filtering/filter_gaussian_2d.hpp"
33 #include "../filtering/filter_downsampler_2d.hpp"
34 #include "../filtering/filter_ssim.hpp"
35 
36 namespace pic {
37 
38 class SSIMIndex
39 {
40 protected:
43 
47 
49 
50 public:
51 
53  {
54  K0 = 0.01f;
55  K1 = 0.03f;
56  dynamic_range = -1.0f;
57  sigma_window = 1.5f;
58  type = MD_LIN;
59  bDownsampling = true;
61  }
62 
72  void update(float K0 = 0.01f,
73  float K1 = 0.03f,
74  float sigma_window = 1.5f,
75  float dynamic_range = -1.0f,
76  bool bDownsampling = true,
78  {
79  this->K0 = K0 > 0.0f ? K0 : this->K0;
80  this->K1 = K1 > 0.0f ? K1 : this->K0;
81  this->sigma_window = sigma_window > 0.0f ? sigma_window : this->sigma_window;
82  this->dynamic_range = dynamic_range > 0.0f ? dynamic_range : this->dynamic_range;
83  this->bDownsampling = bDownsampling;
84  this->type = type;
85 
87  }
88 
94  Image *execute(ImageVec imgIn, float &ssim_index, Image *ssim_map = NULL)
95  {
96  ssim_index = -1.0f;
97 
98  bool bCheckInput = ImageVecCheck(imgIn, 2) && ImageVecCheckSimilarType(imgIn);
99 
100  if(!bCheckInput) {
101  return ssim_map;
102  }
103 
104  Image *ori = imgIn[0];
105  Image *cmp = imgIn[1];
106 
107  Image *ori_d = NULL;
108  Image *cmp_d = NULL;
109 
110  bool bAllocated = false;
111  if(bDownsampling) {
112  float f = MAX(1.0f, lround(MIN(ori->widthf, ori->heightf) / 256.0f));
113 
114  #ifdef PIC_DEBUG
115  printf("\nDownsampling factor: %f\n", f);
116  #endif
117 
118  if(f > 1.0f) {
119  ori_d = FilterDownSampler2D::execute(ori, NULL, 1.0f / f);
120  cmp_d = FilterDownSampler2D::execute(cmp, NULL, 1.0f / f);
121 
122  ori = ori_d;
123  cmp = cmp_d;
124 
125  bAllocated = true;
126  }
127  }
128 
129  Image *L_ori = flt_lum.Process(Single(ori), NULL);
130  Image *L_cmp = flt_lum.Process(Single(cmp), NULL);
131 
132  switch(type)
133  {
134  case MD_PU:
135  {
136  L_ori->applyFunction(PUEncode);
137  L_cmp->applyFunction(PUEncode);
138  } break;
139 
140  case MD_LOG10:
141  {
144  } break;
145 
146  default:
147  {
148 
149  } break;
150  }
151 
152  if(dynamic_range <= 0.0f) {
153  dynamic_range = L_ori->getDynamicRange(false, 1.0f);
154  }
155 
156  float C0 = K0 * dynamic_range;
157  C0 = C0 * C0;
158 
159  float C1 = K1 * dynamic_range;
160  C1 = C1 * C1;
161 
162  Image *img_mu1 = flt_gauss2D.Process(Single(L_ori), NULL);
163  Image *img_mu2 = flt_gauss2D.Process(Single(L_cmp), NULL);
164 
165  Image img_ori_cmp = (*L_ori) * (*L_cmp);
166 
167  L_ori->applyFunction(square);
168  L_cmp->applyFunction(square);
169 
170  Image *img_sigma1_sq = flt_gauss2D.Process(Single(L_ori), NULL);
171  Image *img_sigma2_sq = flt_gauss2D.Process(Single(L_cmp), NULL);
172  Image *img_sigma1_sigma2 = flt_gauss2D.Process(Single(&img_ori_cmp), NULL);
173 
174  if(C0 > 0.0f && C1 > 0.0f) {
175  flt_ssim.update(C0, C1);
176 
177  ImageVec src;
178  src.push_back(img_mu1);
179  src.push_back(img_mu2);
180  src.push_back(img_sigma1_sq);
181  src.push_back(img_sigma2_sq);
182  src.push_back(img_sigma1_sigma2);
183 
184  ssim_map = flt_ssim.Process(src, ssim_map);
185 
186  if(ssim_map != NULL) {
187  ssim_map->getMeanVal(NULL, &ssim_index);
188  }
189 
190  stdVectorClear<Image>(src);
191  }
192 
193  if(bAllocated) {
194  auto vec = Double(ori_d, cmp_d);
195  stdVectorClear<Image>(vec);
196  }
197 
198  return ssim_map;
199  }
200 
201 };
202 
203 } // end namespace pic
204 
205 #endif /* PIC_METRICS_SSIM_INDEX_HPP */
206 
Image * execute(ImageVec imgIn, float &ssim_index, Image *ssim_map=NULL)
execute
Definition: ssim_index.hpp:94
PIC_INLINE bool ImageVecCheck(ImageVec &imgIn, int minInputImages)
ImageVecCheck.
Definition: image_vec.hpp:147
PIC_INLINE bool ImageVecCheckSimilarType(ImageVec &stack)
ImageVecCheckSimilarType.
Definition: image_vec.hpp:126
std::vector< Image * > ImageVec
ImageVec an std::vector of pic::Image.
Definition: image_vec.hpp:29
PIC_INLINE long lround(double x)
lround rounds double numbers properly.
Definition: math.hpp:229
SSIMIndex()
Definition: ssim_index.hpp:52
PIC_INLINE float log10fPlusEpsilon(float x)
log10fPlusEpsilon
Definition: math.hpp:355
virtual Image * Process(ImageVec imgIn, Image *imgOut)
Process.
Definition: filter.hpp:390
The FilterLuminance class.
Definition: filter_luminance.hpp:33
float getDynamicRange(bool bRobust, float percentile)
getDynamicRange computes the dynamic range of the image.
float heightf
Definition: image.hpp:84
METRICS_DOMAIN type
Definition: ssim_index.hpp:48
void update(float C0, float C1)
update
Definition: filter_ssim.hpp:101
FilterSSIM flt_ssim
Definition: ssim_index.hpp:46
Definition: ssim_index.hpp:38
static Image * execute(Image *imgIn, Image *imgOut, int width, int height)
execute
Definition: filter_downsampler_2d.hpp:100
float dynamic_range
Definition: ssim_index.hpp:41
Definition: base.hpp:30
FilterGaussian2D flt_gauss2D
Definition: ssim_index.hpp:45
float K0
Definition: ssim_index.hpp:41
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
Image * Process(ImageVec imgIn, Image *imgOut)
Process.
Definition: filter_npasses.hpp:310
PIC_INLINE float square(float x)
Square applies square function to a value.
Definition: math.hpp:188
void update(float K0=0.01f, float K1=0.03f, float sigma_window=1.5f, float dynamic_range=-1.0f, bool bDownsampling=true, METRICS_DOMAIN type=MD_LIN)
update
Definition: ssim_index.hpp:72
float widthf
Definition: image.hpp:84
The FilterSSIM class.
Definition: filter_ssim.hpp:28
void applyFunction(float(*func)(float))
applyFunction is an operator that applies an input function to all values in data.
bool bDownsampling
Definition: ssim_index.hpp:42
FilterLuminance flt_lum
Definition: ssim_index.hpp:44
#define MIN(a, b)
Definition: math.hpp:69
The Image class stores an image as buffer of float.
Definition: image.hpp:60
float * getMeanVal(BBox *box, float *ret)
getMeanVal computes the mean for the current Image.
Definition: filter_radial_basis_function.hpp:1501
void update(float sigma)
update
Definition: filter_gaussian_2d.hpp:72
Definition: base.hpp:30
float PUEncode(float L)
PUEncode encodes luminance values in a perceptually uniform space.
Definition: pu_encode.hpp:37
PIC_INLINE ImageVec Single(Image *img)
Single creates an std::vector which contains img; this is for filters input.
Definition: image_vec.hpp:36
Definition: bilateral_separation.hpp:25
float sigma_window
Definition: ssim_index.hpp:41
#define MAX(a, b)
Definition: math.hpp:73
METRICS_DOMAIN
Definition: base.hpp:30
The FilterGaussian2D class.
Definition: filter_gaussian_2d.hpp:31
float K1
Definition: ssim_index.hpp:41
Definition: base.hpp:30