dehaze saturation adjuster for local adjustments, #5972

This commit is contained in:
Ingo Weyrich
2020-11-08 11:36:31 +01:00
parent c49e47d81f
commit 28739b8400
11 changed files with 68 additions and 116 deletions

View File

@@ -313,10 +313,6 @@ void ImProcFunctions::dehaze(Imagefloat *img, const DehazeParams &dehazeParams)
const int H = img->getHeight();
const float strength = LIM01(float(dehazeParams.strength) / 100.f * 0.9f);
if (settings->verbose) {
std::cout << "dehaze: strength = " << strength << std::endl;
}
array2D<float> dark(W, H);
int patchsize = max(int(5 / scale), 2);
@@ -384,7 +380,7 @@ void ImProcFunctions::dehaze(Imagefloat *img, const DehazeParams &dehazeParams)
const float depth = -float(dehazeParams.depth) / 100.f;
const float t0 = max(1e-3f, std::exp(depth * maxDistance));
const float teps = 1e-3f;
constexpr float teps = 1.f + 1e-3f;
const float satBlend = dehazeParams.saturation / 100.f;
const TMatrix ws = ICCStore::getInstance()->workingSpaceMatrix(params->icm.workingProfile);
@@ -392,6 +388,7 @@ void ImProcFunctions::dehaze(Imagefloat *img, const DehazeParams &dehazeParams)
const vfloat wsv[3] = {F2V(ws[1][0]), F2V(ws[1][1]),F2V(ws[1][2])};
#endif
const float ambientY = Color::rgbLuminance(ambient[0], ambient[1], ambient[2], ws);
#ifdef _OPENMP
#pragma omp parallel for if (multiThread)
#endif
@@ -414,8 +411,8 @@ void ImProcFunctions::dehaze(Imagefloat *img, const DehazeParams &dehazeParams)
const vfloat g = LVFU(img->g(y, x));
const vfloat b = LVFU(img->b(y, x));
// ... t >= tl to avoid negative values
const vfloat tlv = onev - vminf(r / ambient0v, vminf(g / ambient1v, b / ambient2v));
const vfloat mtv = vmaxf(LVFU(dark[y][x]), vmaxf(tlv + tepsv, t0v));
const vfloat tlv = tepsv - vminf(r / ambient0v, vminf(g / ambient1v, b / ambient2v));
const vfloat mtv = vmaxf(LVFU(dark[y][x]), vmaxf(tlv, t0v));
if (dehazeParams.showDepthMap) {
const vfloat valv = vclampf(onev - mtv, ZEROV, onev) * cmaxChannelv;
STVFU(img->r(y, x), valv);
@@ -437,8 +434,8 @@ void ImProcFunctions::dehaze(Imagefloat *img, const DehazeParams &dehazeParams)
const float g = img->g(y, x);
const float b = img->b(y, x);
// ... t >= tl to avoid negative values
const float tl = 1.f - min(r / ambient[0], g / ambient[1], b / ambient[2]);
const float mt = max(dark[y][x], t0, tl + teps);
const float tl = teps - min(r / ambient[0], g / ambient[1], b / ambient[2]);
const float mt = max(dark[y][x], t0, tl);
if (dehazeParams.showDepthMap) {
img->r(y, x) = img->g(y, x) = img->b(y, x) = LIM01(1.f - mt) * maxChannel;
} else {
@@ -453,19 +450,15 @@ void ImProcFunctions::dehaze(Imagefloat *img, const DehazeParams &dehazeParams)
}
}
void ImProcFunctions::dehazeloc(Imagefloat *img, const DehazeParams &dehazeParams)
{
//J.Desmis 12 2019 - this version derived from ART, is slower than the main from maximum 10% - probably use of SSE
//Probably Ingo could solved this problem in some times
BENCHFUN
if (!dehazeParams.enabled || dehazeParams.strength == 0.0) {
return;
}
const float maxChannel = normalize(img, multiThread);
const int W = img->getWidth();
@@ -473,10 +466,6 @@ void ImProcFunctions::dehazeloc(Imagefloat *img, const DehazeParams &dehazeParam
const float strength = LIM01(float(std::abs(dehazeParams.strength)) / 100.f * 0.9f);
const bool add_haze = dehazeParams.strength < 0;
if (settings->verbose) {
std::cout << "dehaze: strength = " << strength << std::endl;
}
array2D<float> dark(W, H);
int patchsize = max(int(5 / scale), 2);
@@ -546,11 +535,11 @@ void ImProcFunctions::dehazeloc(Imagefloat *img, const DehazeParams &dehazeParam
}
const float depth = -float(dehazeParams.depth) / 100.f;
const float teps = 1e-6f;
constexpr float teps = 1e-6f;
const float t0 = max(teps, std::exp(depth * maxDistance));
// const bool luminance = dehazeParams.luminance;
const bool luminance = true;
const float satBlend = dehazeParams.saturation / 100.f;
const TMatrix ws = ICCStore::getInstance()->workingSpaceMatrix(params->icm.workingProfile);
const float ambientY = Color::rgbLuminance(ambient[0], ambient[1], ambient[2], ws);
@@ -559,56 +548,43 @@ void ImProcFunctions::dehazeloc(Imagefloat *img, const DehazeParams &dehazeParam
#endif
for (int y = 0; y < H; ++y) {
int x = 0;
for (; x < W; ++x) {
for (int x = 0; x < W; ++x) {
// ensure that the transmission is such that to avoid clipping...
float rgb[3] = { img->r(y, x), img->g(y, x), img->b(y, x) };
const float rIn = img->r(y, x);
const float gIn = img->g(y, x);
const float bIn = img->b(y, x);
// ... t >= tl to avoid negative values
float tl = 1.f - min(rgb[0] / ambient[0], rgb[1] / ambient[1], rgb[2] / ambient[2]);
// // ... t >= tu to avoid values > 1
// float tu = t0 - teps;
// for (int c = 0; c < 3; ++c) {
// if (ambient[c] < 1) {
// tu = max(tu, (rgb[c] - ambient[c])/(1.f - ambient[c]));
// }
// }
float &ir = img->r(y, x);
float &ig = img->g(y, x);
float &ib = img->b(y, x);
const float mt = max(dark[y][x], t0, tl + teps);
const float tl = 1.f + teps - min(rIn / ambient[0], gIn / ambient[1], bIn / ambient[2]);
const float mt = max(dark[y][x], t0, tl);
if (dehazeParams.showDepthMap) {
img->r(y, x) = img->g(y, x) = img->b(y, x) = LIM01(1.f - mt) * maxChannel;
} else if (luminance) {
float Y = Color::rgbLuminance(img->r(y, x), img->g(y, x), img->b(y, x), ws);
float YY = (Y - ambientY) / mt + ambientY;
} else {
float f = 1.f;
const float Y = Color::rgbLuminance(rIn, gIn, bIn, ws);
if (Y > 1e-5f) {
float YY = (Y - ambientY) / mt + ambientY;
if (add_haze) {
YY = Y + Y - YY;
}
float f = YY / Y;
ir = rgb[0] * f;
ig = rgb[1] * f;
ib = rgb[2] * f;
f = YY / Y;
}
} else {
float r = ((rgb[0] - ambient[0]) / mt + ambient[0]);
float g = ((rgb[1] - ambient[1]) / mt + ambient[1]);
float b = ((rgb[2] - ambient[2]) / mt + ambient[2]);
const float r1 = rIn * f;
const float g1 = gIn * f;
const float b1 = bIn * f;
float r2 = ((rIn - ambient[0]) / mt + ambient[0]);
float g2 = ((gIn - ambient[1]) / mt + ambient[1]);
float b2 = ((bIn - ambient[2]) / mt + ambient[2]);
if (add_haze) {
ir += (ir - r);
ig += (ig - g);
ib += (ib - b);
} else {
ir = r;
ig = g;
ib = b;
r2 = rIn + rIn - r2;
g2 = gIn + gIn - g2;
b2 = bIn + bIn - b2;
}
img->r(y, x) = intp(satBlend, r2, r1);
img->g(y, x) = intp(satBlend, g2, g1);
img->b(y, x) = intp(satBlend, b2, b1);
}
}
}