From a8413180bd2dd66c77e3994ff4a3140be6cdbecc Mon Sep 17 00:00:00 2001 From: Ian Gulliver Date: Thu, 10 Aug 2017 21:28:27 -0700 Subject: [PATCH] Bugfixes to make gradient descent finally incrementally sane --- colorchecker.h | 16 +++++++++++----- intmath.h | 2 +- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/colorchecker.h b/colorchecker.h index 7d4a2a8..17da045 100644 --- a/colorchecker.h +++ b/colorchecker.h @@ -116,6 +116,7 @@ template & image, Lut3d* lut) { static_assert(C == 3); + auto snapshot = *lut; uint32_t diff = 0; for (uint32_t x = 0; x < LUT_X; ++x) { @@ -130,16 +131,21 @@ uint32_t OptimizeLut(const Image& image, Lut3d{{{x, y, z}}} << std::endl; for (uint32_t c = 0; c < C; ++c) { + auto& channel = color.at(c); + auto min = FindPossibleMinimum( 0, UINT16_MAX, - [&image, &lut, x, y, z, c](uint32_t val) { - auto test_lut = *lut; + [&image, &snapshot, x, y, z, c](uint32_t val) { + auto test_lut = snapshot; test_lut.at(x).at(y).at(z).at(c) = val; return ScoreImage(*test_lut.MapImage(image)); }); - std::cout << "\tC" << c << ": " << color.at(c) << " -> " << min << std::endl; - diff += AbsDiff(color.at(c), min); - color.at(c) = min; + // Magic value of 8 is the number of points making up a square, so the number + // of points that control any given given LUT mapping. + auto new_value = Interpolate(channel, min, UINT32_C(1), UINT32_C(8)); + std::cout << "\tC" << c << ": " << channel << " -> " << new_value << " (interpolated from " << min << ")" << std::endl; + diff += AbsDiff(channel, new_value); + channel = new_value; } } } diff --git a/intmath.h b/intmath.h index b6af5ec..77c49f5 100644 --- a/intmath.h +++ b/intmath.h @@ -10,6 +10,6 @@ constexpr T Interpolate(T val0, T val1, T mul, T div) { if (val1 > val0) { return val0 + ((mul * (val1 - val0)) / div); } else { - return val0 - (((div - mul) * (val0 - val1)) / div); + return val0 - ((mul * (val0 - val1)) / div); } }