|
| 1 | +/******************************************************************************* |
| 2 | +* * |
| 3 | +* Brno University of Technology * |
| 4 | +* CPhoto@FIT * |
| 5 | +* * |
| 6 | +* Tone Mapping Studio * |
| 7 | +* * |
| 8 | +* Brno 2021 * |
| 9 | +* * |
| 10 | +* Implementation of the TMODrago03 class * |
| 11 | +* * |
| 12 | +*******************************************************************************/ |
| 13 | +#include <math.h> |
| 14 | + |
| 15 | +#include "TMODrago03.h" |
| 16 | + |
| 17 | +/* --------------------------------------------------------------------------- * |
| 18 | + * Constructor serves for describing a technique and input parameters * |
| 19 | + * --------------------------------------------------------------------------- */ |
| 20 | +TMODrago03::TMODrago03() |
| 21 | +{ |
| 22 | + SetName(L"Drago03"); |
| 23 | + SetDescription(L"Adaptive Logarithmic Mapping For Displaying High Contrast Scenes"); |
| 24 | + |
| 25 | + /* Kernel size multiplier */ |
| 26 | + kernel.SetName(L"kernel"); |
| 27 | + kernel.SetDescription(L"Kernel size multiplier: <0.1,1.0>"); |
| 28 | + kernel.SetDefault(0.125); |
| 29 | + kernel=0.125; |
| 30 | + this->Register(kernel); |
| 31 | + kernel.SetRange(0.1, 1.0); |
| 32 | + |
| 33 | + /* y coordinate for center-weighting */ |
| 34 | + centerY.SetName(L"centerY"); |
| 35 | + centerY.SetDescription(L"y coordinate for center-weighting"); |
| 36 | + centerY.SetDefault(false); |
| 37 | + centerY=false; |
| 38 | + this->Register(centerY); |
| 39 | + |
| 40 | + /* x coordinate for center-weighting */ |
| 41 | + centerX.SetName(L"centerX"); |
| 42 | + centerX.SetDescription(L"x coordinate for center-weighting"); |
| 43 | + centerX.SetDefault(0); |
| 44 | + centerX=0; |
| 45 | + this->Register(centerX); |
| 46 | + |
| 47 | + /* Center-weighted scalefactor */ |
| 48 | + center.SetName(L"center"); |
| 49 | + center.SetDescription(L"Use a center-weighted scalefactor"); |
| 50 | + center.SetDefault(false); |
| 51 | + center=false; |
| 52 | + this->Register(center); |
| 53 | + |
| 54 | + /* Gamma transfer function */ |
| 55 | + gammaForm.SetName(L"gammaForm"); |
| 56 | + gammaForm.SetDescription(L"Use a gamma transfer function"); |
| 57 | + gammaForm.SetDefault(false); |
| 58 | + gammaForm=false; |
| 59 | + this->Register(gammaForm); |
| 60 | + |
| 61 | + /* Gamma */ |
| 62 | + gamma.SetName(L"gamma"); |
| 63 | + gamma.SetDescription(L"Gamma correction value: <1.0e-3,1.0e+2>"); |
| 64 | + gamma.SetDefault(1.0); |
| 65 | + gamma=1.0; |
| 66 | + gamma.SetRange(1.0e-3,1.0e+2); |
| 67 | + this->Register(gamma); |
| 68 | + |
| 69 | + /* Exposure */ |
| 70 | + exposure.SetName(L"exposure"); |
| 71 | + exposure.SetDescription(L"Exposure scale factor: <0,100>"); |
| 72 | + exposure.SetDefault(0.0); |
| 73 | + exposure=0.0; |
| 74 | + exposure.SetRange(0,100); |
| 75 | + this->Register(exposure); |
| 76 | + |
| 77 | + /* Bias parameter b */ |
| 78 | + bias.SetName(L"bias"); |
| 79 | + bias.SetDescription(L"Bias parameter b: <0.7,0.9>"); |
| 80 | + bias.SetDefault(0.85); |
| 81 | + bias=0.85; |
| 82 | + bias.SetRange(0.7,0.9); |
| 83 | + this->Register(bias); |
| 84 | +} |
| 85 | + |
| 86 | +TMODrago03::~TMODrago03() |
| 87 | +{ |
| 88 | +} |
| 89 | + |
| 90 | +float BiasFunc (float t, float bias) |
| 91 | +{ |
| 92 | + const float LOG05 = -0.693147f; |
| 93 | + |
| 94 | + return pow(t, log(bias)/LOG05); |
| 95 | +} |
| 96 | + |
| 97 | +void SetExp (double* exp_d) |
| 98 | +{ |
| 99 | + *exp_d = pow(2, *exp_d); |
| 100 | +} |
| 101 | + |
| 102 | +int TMODrago03::Transform() |
| 103 | +{ |
| 104 | + double Y, x, y; |
| 105 | + double L_av; |
| 106 | + double exp_d; |
| 107 | + double L_w, L_d, interpol; |
| 108 | + double L_min=0.; |
| 109 | + double L_max=0.; |
| 110 | + double L_world=0.; |
| 111 | + |
| 112 | + double* pSourceData; |
| 113 | + double* pDestinationData; |
| 114 | + |
| 115 | + pSrc->GetMinMaxAvgWorldAdapt(&L_min, &L_max, &L_world); |
| 116 | + |
| 117 | + /* Set exposure */ |
| 118 | + exp_d = exposure.GetDouble(); |
| 119 | + SetExp(&exp_d); |
| 120 | + |
| 121 | + pSrc->Convert(TMO_Yxy); |
| 122 | + pDst->Convert(TMO_Yxy); |
| 123 | + |
| 124 | + pSourceData = pSrc->GetData(); |
| 125 | + pDestinationData = pDst->GetData(); |
| 126 | + |
| 127 | + if (center.GetBool()) |
| 128 | + { |
| 129 | + pSrc->CenterWeight(centerX.GetInt(), centerY.GetInt(), (float)kernel.GetDouble(), &L_world); |
| 130 | + } |
| 131 | + |
| 132 | + L_av = exp(L_world)/1.0; |
| 133 | + L_max /= L_av; |
| 134 | + |
| 135 | + /* Tone mapping */ |
| 136 | + int j = 0; |
| 137 | + |
| 138 | + for (j = 0; j < pSrc->GetHeight(); j++) |
| 139 | + { |
| 140 | + pSrc->ProgressBar(j, pSrc->GetHeight()); |
| 141 | + for (int i = 0; i < pSrc->GetWidth(); i++) |
| 142 | + { |
| 143 | + Y = *pSourceData++; |
| 144 | + x = *pSourceData++; |
| 145 | + y = *pSourceData++; |
| 146 | + |
| 147 | + L_w = Y / L_av; |
| 148 | + |
| 149 | + if (exp_d != 1.0) |
| 150 | + { |
| 151 | + L_w *= exp_d; |
| 152 | + } |
| 153 | + |
| 154 | + interpol = log (2.0f + BiasFunc(L_w / L_max, bias.GetDouble()) * 8.0f); |
| 155 | + L_d = (log(L_w+1.0f)/interpol) / log10(L_max+1.0f); |
| 156 | + |
| 157 | + *pDestinationData++ = L_d; |
| 158 | + *pDestinationData++ = x; |
| 159 | + *pDestinationData++ = y; |
| 160 | + } |
| 161 | + } |
| 162 | + |
| 163 | + pDst->Convert(TMO_RGB); |
| 164 | + |
| 165 | + /* Gamma */ |
| 166 | + if (gamma.GetDouble() != 1.0) |
| 167 | + { |
| 168 | + if (gammaForm.GetBool()) |
| 169 | + { |
| 170 | + pDst->RecCorrectGamma(gamma.GetDouble()); |
| 171 | + } |
| 172 | + else |
| 173 | + { |
| 174 | + pDst->CorrectGamma(gamma.GetDouble()); |
| 175 | + } |
| 176 | + } |
| 177 | + |
| 178 | + pSrc->ProgressBar(j, pSrc->GetHeight()); |
| 179 | + |
| 180 | + return 0; |
| 181 | +} /* Transform */ |
0 commit comments