Ищу алгоритм, реализующий фотошоповский "Auto Levels" (или gimp'овский "Увеличить контраст"). Я не нашел конечную реализацию, но выяснил, как приблизительно он работает. Задача алгоритма - увеличить контраст изображения со слабой динамикой.
Изображение рассматривается как монохроматичное (если с цветом работать, то получится Auto Colors, но мне нужно сохранить цвета), составляется гистограмма уровней, на горизонтальной оси которой значение яркости от 0 до 255, а по вертикали количество пикселей с соответствующей яркостью. Чем контрастнее изображение, тем равномернее и ровнее она будет распределена от начала до конца, у неконтрастного изображения она соберется в кучу примерно посередине, а начало и конец всей оси будут пусты. Автоматически назначается самая черная точка (как бы(!) мин. значение), самая белая точка (как бы(!) макс. значение) и, опционально, серая точка (где-то посреди), и гистограмма растягивается так, чтобы мин. точка оказалась в 0, макс. точка в 255, а средняя посередине (опционально).
Исходная (серая) и скорректированная (черная) гистограммы:
Собственно, неясно:
1. Как автоматически выбрать точки ? Фотошоп и gimp делают это по-разному, соответственно, и результаты разные. Меня больше результат у gimp устраивает. Я пробовал в исходниках рыться, но бестолку, там все запрятано в сложной струткре объектно-ориентированного кода.
2. Как по растянутой гистограмме пересчитать пиксели ? Предполагаю, что для каждого уровня запоминаются пиксели, а потом им присваиваются новые значения. Тут еще интересный момент есть. Я работаю с моделью HSV и меня интересует значение S (насыщенность). В результате обработки фотошопом/гимпом оно тоже изменяется (собственно, это мне и нужно), на темных и ярких участках она уменьшается. Значит, "масштабируется" не тупо одно значение V (яркость) у пикселя, а как то по-другому. Полагаю, что каждая составляющая RGB масштибируется, это очень похоже, исходя из того как насыщенность расчитывается из RGB (см. RGB —> HSV).
3. Сколько потребуется памяти ? Я примерно понял из исходников GEGL, что там тупо в один проход пиксели "масштабируются", ничего не запоминается, не сравнивается и т.п.