我有欲伽玛校正应用到的灰度图像。手动地,我在Photoshop级别中调整中间滑块,而不会触碰黑点或白点,直到直方图的中值达到127或接近该值为止。我想通过python来做同样的事情。
我寻找了一个将伽玛值作为输入并生成输出图像的公式。然而,我只找到一个,其调整所述低和高值,而不是伽马(或中间色调)。
这里,R是在我的作为numpy的阵列图像的像素的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
我试图搜索的伽马滑块后面的公式将辫文档,并发现看起来像这样的代码。
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之间,并且它可能是一个日志或二次函数。我不确定这是否是正确的代码片段,因为它似乎需要高,低和像素值并产生伽玛值(我可能会误会),而我想输入伽玛值并获得校正后的图像。
的问题是,同时用这种方法产生的图像是接近我想要的,它不是相同的发言权Photoshop或辫形移动伽马滑块。
我在用代码图像处理一个业余爱好者,这是我在StackOverflow上的第一个问题,所以请原谅我的任何愚蠢的事我可能已经问。
答案 0 :(得分:1)
我认为这是正确的,但是在投入生产之前请彻底尝试:
#!/usr/bin/env python3
import numpy as np
import math
from PIL import Image
# Load starting image and ensure greyscale. Make into Numpy array for doing maths.
im = Image.open('start.png').convert('L')
imnp = np.array(im)/255
# DEBUG: print(imnp.max())
# DEBUG: print(imnp.min())
# DEBUG: print(imnp.mean()
# Calculate new gamma
gamma=math.log(imnp.mean())/math.log(0.5)
# Apply new gamma to image
new = ((imnp**(1/gamma))*255).astype(np.uint8)
# Convert back to PIL from Numpy and save
Image.fromarray(new).save('result.png')
这变成了:
对此:
如果您的图像较大,则可能值得对256个可能的灰度值进行LUT(查找表),然后应用该值而不是进行处理。
或者,如果您不想编写任何Python,则可以使用 ImageMagick ,它已安装在大多数Linux发行版中,并且可用于macOS和Windows。因此,只需在终端(或Windows上的命令提示符)中:
magick input.png -auto-gamma result.png