«Отверстия», которые вы видите на обработанном изображении, являются более темными областями исходного изображения, которые получили отрицательные значения с помощью вашего алгоритма затемнения. Я подозреваю, что эти значения вне диапазона записываются в новое изображение как положительные числа, поэтому они оказываются в верхней части шкалы яркости. Например, допустим, значение пикселя равно 10, а вы вычитаете 12 из всех пикселей, чтобы затемнить их немного. Этот пиксель опустится и станет -2. Когда вы записываете его обратно в файл, -2 представляется как 0xfe в шестнадцатеричном формате, и это 254, если вы берете его как число без знака.
Вы должны использовать алгоритм, который удерживает значения пикселей в допустимом диапазоне, или, по крайней мере, вы должны "фиксировать" значения в допустимом диапазоне. Типичная функция зажима, определенная как макрос C, будет:
#define clamp(p) (p < 0 ? 0 : (p > 255 ? 255 : p))
Если вы добавите вышеупомянутый макрос в свою функцию обработки, он позаботится о «дырах», но вместо этого у вас теперь будут темные цвета в этих местах.
Если вы готовы к чему-то более продвинутому, здесь, в Википедии , у них есть формулы яркости и контрастности, которые используются в GIMP. Они хорошо справятся с вашим изображением, если вы выберете правильные коэффициенты.