96 std::vector<double> scales(MAX_RETINEX_SCALES);
99 scales[0] = scale / 2.0;
101 else if (scaleDiv == val_2) {
102 scales[0] = scale / 2.0;
106 double size_step = scale /
static_cast<double>(scaleDiv);
111 for (i = 0; i < scaleDiv; ++i) {
112 scales[
static_cast<size_t>(i)] = 2.0 + (i * size_step);
117 size_step = std::log(scale - 2.0) /
static_cast<double>(scaleDiv);
118 for (i = 0; i < scaleDiv; ++i) {
119 scales[
static_cast<size_t>(i)] = 2.0 + std::pow(10.0, (i * size_step) / std::log(10.0));
124 size_step = std::log(scale - 2.0) /
static_cast<double>(scaleDiv);
125 for (i = 0; i < scaleDiv; ++i) {
126 scales[
static_cast<size_t>(i)] = scale - std::pow(10.0, (i * size_step) / std::log(10.0));
149 double weight = 1.0 /
static_cast<double>(scaleDiv);
151 std::vector<vpImage<double> > doubleRGB(3);
152 std::vector<vpImage<double> > doubleResRGB(3);
153 unsigned int size = I.getSize();
155 int kernelSize = v_kernelSize;
156 if (kernelSize == -1) {
158 kernelSize =
static_cast<int>(std::min<unsigned int>(I.getWidth(), I.getHeight()) / 2.0);
159 const int moduloForOddityCheck = 2;
160 kernelSize = (kernelSize - (kernelSize % moduloForOddityCheck)) + 1;
163 const int nbChannels = 3;
164 const int id0 = 0, id1 = 1, id2 = 2;
165 for (
int channel = 0; channel < nbChannels; ++channel) {
166 doubleRGB[
static_cast<size_t>(channel)] =
vpImage<double>(I.getHeight(), I.getWidth());
167 doubleResRGB[
static_cast<size_t>(channel)] =
vpImage<double>(I.getHeight(), I.getWidth());
169 for (
unsigned int cpt = 0; cpt < size; ++cpt) {
173 doubleRGB[
static_cast<size_t>(channel)].bitmap[cpt] = I.bitmap[cpt].R + 1.0;
177 doubleRGB[
static_cast<size_t>(channel)].bitmap[cpt] = I.bitmap[cpt].G + 1.0;
181 doubleRGB[
static_cast<size_t>(channel)].bitmap[cpt] = I.bitmap[cpt].B + 1.0;
189 for (
int sc = 0; sc < scaleDiv; ++sc) {
191 double sigma = retinexScales[
static_cast<size_t>(sc)];
194 for (
unsigned int cpt = 0; cpt < size; ++cpt) {
198 doubleResRGB[
static_cast<size_t>(channel)].bitmap[cpt] +=
199 weight * (std::log(doubleRGB[
static_cast<size_t>(channel)].bitmap[cpt]) - std::log(blurImage.
bitmap[cpt]));
204 std::vector<double> dest(size * nbChannels);
205 const double gain = 1.0, alpha = 128.0, offset = 0.0;
207 for (
unsigned int cpt = 0; cpt < size; ++cpt) {
208 double logl = std::log(
static_cast<double>(I.bitmap[cpt].R + I.bitmap[cpt].G + I.bitmap[cpt].B + 3.0));
210 dest[cpt * nbChannels] = (gain * (std::log(alpha * doubleRGB[id0].bitmap[cpt]) - logl) * doubleResRGB[id0].bitmap[cpt]) + offset;
211 dest[(cpt * nbChannels) + id1] =
212 (gain * (std::log(alpha * doubleRGB[id1].bitmap[cpt]) - logl) * doubleResRGB[id1].bitmap[cpt]) + offset;
213 dest[(cpt * nbChannels) + id2] =
214 (gain * (std::log(alpha * doubleRGB[id2].bitmap[cpt]) - logl) * doubleResRGB[id2].bitmap[cpt]) + offset;
217 double sum = std::accumulate(dest.begin(), dest.end(), 0.0);
218 double mean = sum / dest.size();
220 std::vector<double> diff(dest.size());
222#if VISP_CXX_STANDARD > VISP_CXX_STANDARD_98
223 std::transform(dest.begin(), dest.end(), diff.begin(), std::bind(std::minus<double>(), std::placeholders::_1, mean));
225 std::transform(dest.begin(), dest.end(), diff.begin(), std::bind2nd(std::minus<double>(), mean));
228 double sq_sum = std::inner_product(diff.begin(), diff.end(), diff.begin(), 0.0);
229 double stdev = std::sqrt(sq_sum / dest.size());
231 double mini = mean - (dynamic * stdev);
232 double maxi = mean + (dynamic * stdev);
233 double range = maxi - mini;
239 for (
unsigned int cpt = 0; cpt < size; ++cpt) {
249 const int minScale = 16, maxScale = 250;
250 if ((scale < minScale) || (scale > maxScale)) {
251 std::cerr <<
"Scale must be between the interval [" << minScale <<
" - " << maxScale <<
"]" << std::endl;
256 const int minScaleDiv = 1, maxScaleDiv = 8;
257 if ((scaleDiv < minScaleDiv) || (scaleDiv > maxScaleDiv)) {
258 std::cerr <<
"Scale division must be between the interval [" << minScaleDiv <<
" - " << maxScaleDiv <<
"]" << std::endl;
262 if ((I.getWidth() * I.getHeight()) == 0) {
266 MSRCR(I, scale, scaleDiv, level, dynamic, kernelSize);