如何在不使高光饱和的情况下以编程方式调整图像的亮度?

时间:2018-03-05 15:47:36

标签: c++ image brightness exposure

我正在开发一种图像处理算法来调整亮度,对比度,阴影,高光,水平和伽玛。

我无法对亮度进行建模,使其表现出大部分线性(如曝光调整),但压缩高光而不是使其饱和。

这是我想要的曲线: enter image description here

这是我当前实施中的曲线。您可以注意到它过早地从线性线转移。我更喜欢在高光区域发生的曲线: enter image description here

这是我现在的代码:

fCnt += 1.0f; // fCnt->[-1,1]
fBri += 1.0f; // fBri->[-1,1]
fShd = (fShd/2.0f)*-0.6876f; // fShd -> [0,1]
fHlt /= 2.0f; // [0,1]
const float fRange = 1/(fWhite-fBlack); // fWhite, fBlack -> [0,1]
const float K = 1.0f/255;

float lut[256];
for(int i=0; i<256; ++i)
{
    float x = i*K; // map [0-255] uchar to [0-1] float
    // brightness 
    x = (1-pow(1-x, fBri));
    // contrast
    x = x <= 0.5f ? 0.5f*pow(x*2.0f, fCnt) : 1.0f - (0.5f*pow((1.0f - x)*2.0f, fCnt));
    // shadow
    x *= (qLn(x+0.0001f) * fShd + 1.0f);
    // highlights
    const float x2 = x*x;
    x *= (x <= 0.4 ? 1 : 1 + fHlt*(1.9434*x*x2 - 3.65455*x2 + 1.98107*x - 0.333037));
    // levels
    x = (x - fBlack) * fRange;
    // gamma [0,4]
    x = pow(min(0.0001f, x), fGamma);

    lut[i] = x;
}

for(int i=0; i<size; ++i)
    img[i] = clamp(img[i]*255.0f);

1 个答案:

答案 0 :(得分:2)

您可以使用Bezier curve获得您想要的任意形状。

我从https://www.desmos.com/calculator/cahqdxeshd

获得了这张照片

enter image description here