Как программно отрегулировать яркость изображения без насыщенных бликов?

Я разрабатываю алгоритм обработки изображений для регулировки яркости, контрастности, теней, бликов, уровней и гаммы.

У меня проблемы с моделированием яркости, чтобы она в основном была линейной (например, регулировка экспозиции), но сжимала блики, а не насыщала их.

Это кривая, которую я хочу:
введите описание изображения здесь

И это кривая, которую я имею в моей текущей реализации. Вы можете заметить, что он смещается от линейной линии слишком рано. Я бы предпочел кривую, где это произошло бы в области бликов:
введите описание изображения здесь

Вот код, который у меня есть сейчас:

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);

0

Решение

Вы можете использовать Кривая Безье чтобы получить любую произвольную форму, которую вы хотите.

Я получил эту картину от https://www.desmos.com/calculator/cahqdxeshd

введите описание изображения здесь

2

Другие решения

Других решений пока нет …