У меня есть изображение в градациях серого, к которому я хочу применить гамма-коррекцию.Вручную я настраиваю средний ползунок на уровнях фотошопа, не касаясь черных или белых точек, пока медианное значение гистограммы не достигнет 127 или где-то близко к нему.Я хочу сделать то же самое с помощью Python.
Я искал формулу, которая принимает значение гаммы в качестве входных данных и создает выходное изображение.Однако я нашел только один, который регулирует низкие и высокие значения, а не гамму (или средние тона).
Здесь R - это красное RGB-значение пикселей в моем изображении в виде массива, H - высокоевход и L низкий вход.Я начинаю с L = 0 и H = 255 и продолжаю передавать различные значения в функцию, пока возвращаемое изображение не будет иметь медиану 127 на гистограмме.
def get_levelcorrected_image(R,H,L):
temp=((R-L)*255.0)/(H-L)
temp[temp<0]=0
temp[temp>255]=255
temp[temp==255]=0 #added this line because for some reason there were a lot of white pixels where it should have been dark
final = temp.astype('uint8')
return final
Я попытался найти в документации gimp формулуза ползунком гаммы, и нашел код, который был похож на это.
if (gray)
{
gdouble input;
gdouble range;
gdouble inten;
gdouble out_light;
gdouble lightness;
/* Calculate lightness value */
lightness = GIMP_RGB_LUMINANCE (gray->r, gray->g, gray->b);
input = gimp_levels_config_input_from_color (channel, gray);
range = config->high_input[channel] - config->low_input[channel];
if (range <= 0)
goto out;
input -= config->low_input[channel];
if (input < 0)
goto out;
/* Normalize input and lightness */
inten = input / range;
out_light = lightness / range;
/* See bug 622054: picking pure black or white as gamma doesn't
* work. But we cannot compare to 0.0 or 1.0 because cpus and
* compilers are shit. If you try to check out_light using
* printf() it will give exact 0.0 or 1.0 anyway, probably
* because the generated code is different and out_light doesn't
* live in a register. That must be why the cpu/compiler mafia
* invented epsilon and defined this shit to be the programmer's
* responsibility.
*/
if (out_light <= 0.0001 || out_light >= 0.9999)
goto out;
/* Map selected color to corresponding lightness */
config->gamma[channel] = log (inten) / log (out_light);
config->gamma[channel] = CLAMP (config->gamma[channel], 0.1, 10.0);
g_object_notify (G_OBJECT (config), "gamma");
Я знаю, что значение гамма-входа должно быть между 0,1 и 10, и что это, вероятно, логарифмическая или квадратичная функция.Я не уверен, что это правильный фрагмент кода, так как он, кажется, принимает высокие, низкие и пиксельные значения и производит гамма-значение (я могу ошибаться), тогда как я хочу ввести гамма-значение и получить исправленное изображение.
Проблема в том, что хотя изображение, полученное с помощью этого метода, близко к тому, что я хочу, это не то же самое, что перемещение слайдера гаммы в фотошопе или gimp.
Я любительпри манипулировании изображениями с помощью кода, и это мой первый вопрос в StackOverFlow, поэтому, пожалуйста, прости меня за все глупости, которые я мог спросить.