python 枕形图像灰度化的Gamma校正

6l7fqoea  于 2023-05-27  发布在  Python
关注(0)|答案(3)|浏览(156)

尝试在Dash应用程序中对图像执行伽马校正。但是原始的彩色图像在经过我的函数后变成了灰度。我使用Pillow Image.new("P", ...)表示颜色,而不是表示灰度的“L”。如果我使用Image.new("RGB",...),返回的图像是红色的。请帮帮我

def gamma_correct(gamma, url):
    im = Image.open(requests.get(url, stream=True).raw)
    
    gamma1 = gamma
    row = im.size[0]
    col = im.size[1]
    result_img1 = Image.new("RGB", (row, col))
    for x in range(1 , row):
        for y in range(1, col):
            r = pow(im.getpixel((x,y))[0]/255, (1/gamma1))*255
            g = pow(im.getpixel((x,y))[1]/255, (1/gamma1))*255
            b = pow(im.getpixel((x,y))[2]/255, (1/gamma1))*255
            result_img1.putpixel((x,y)[0], int(r))
            result_img1.putpixel((x,y)[1], int(g))
            result_img1.putpixel((x,y)[2], int(b))
2w3rbyxf

2w3rbyxf1#

记住“P”和“RGB”是不一样的。P是调色板模式,并且限于256种颜色。
彩色图像具有以下维度:(宽度、高度、通道),其中通道通常为= 3。
这看起来就像你在保存图像,所有的颜色值都在一个通道中,这意味着你最终得到一个像(width,tall,channels)这样的图像,通道= 1。这也是为什么当您使用Image.new(“RGB”,...)时会得到红色图像的原因,因为您的图像仅在第一个通道(R)中有数据。
@ChristophRackwitz在他的两个评论中都是正确的。大多数情况下,处理图像的库实际上处理的是尺寸(高度,宽度,通道),所以如果你从磁盘加载一个图像,比如说,(1920,1080,3),内存中的对象实际上有尺寸(1080,1920,3)。此外,一些软件(如opencv)甚至默认将通道视为BGR而不是RGB
RGB图像有3个通道,它们是每种颜色的值。这意味着对于图像中的每个像素,有3个颜色值,一个用于红色通道(R),一个用于绿色(G),一个用于蓝色(B)。
尝试调试图像修改过程,即:

for x in range(1 , row):
    for y in range(1, col):
            print(im.getpixel(x,y))
            r = pow(im.getpixel((x,y))[0]/255, (1/gamma1))*255
            g = pow(im.getpixel((x,y))[1]/255, (1/gamma1))*255
            b = pow(im.getpixel((x,y))[2]/255, (1/gamma1))*255
            print(im.getpixel(x,y))

这两个print语句将打印一个三维数组。检查每个通道的值是否符合预期,前后都是如此

t3irkdon

t3irkdon2#

错误是您只向putpixel()方法传递了一个通道(即R)参数。你需要传递一个RGB值的元组。

def gamma_correct(gamma, path):
    im = Image.open(path)
    gamma1 = gamma
    row = im.size[0]
    col = im.size[1]
    result_img1 = Image.new(mode="RGB", size=(row, col), color=0)
    for x in range(row):
        for y in range(col):
            r = pow(im.getpixel((x, y))[0] / 255, (1 / gamma1)) * 255
            g = pow(im.getpixel((x, y))[1] / 255, (1 / gamma1)) * 255
            b = pow(im.getpixel((x, y))[2] / 255, (1 / gamma1)) * 255
            # add
            color = (int(r), int(g), int(b))
            result_img1.putpixel((x, y), color)
    #show
    result_img1.show()
lstz6jyr

lstz6jyr3#

一个可以
1.使用LUT用PIL实现伽马校正,使用ImageFilter.Color3DLUT.generate()生成LUT,使用lambda函数作为回调,
1.使用Image类中的point()方法,
不需要在像素上迭代。

γ = 0.4
img = Image.open('dark_house.png') # open the image

使用LUT:

LUT = ImageFilter.Color3DLUT.generate((11,11,11), lambda r, g, b: (r**γ, g**γ, b**γ))
img_out = img.filter(LUT)

绘制输入/输出图像:

plt.imshow(np.hstack((np.array(img), np.array()))), plt.axis('off')
plt.title('original and γ-corrected image', size=20)
plt.show()

或者,您可以使用Image中的point()方法,只需一行代码:

img_out = img.point(lambda x: ((x/255)**γ)*255)

再次如上绘图以获得以下输出:

您也可以使用opencv-pythoncv2.LUT()来实现函数γ_correct(),以获得类似的输出。

def γ_correct(img, γ):
    table = [((i / 255) ** γ) * 255 for i in range(256)]
    table = np.array(table, np.uint8)
    return cv2.LUT(img, table)

img = np.array(img)
img_out = γ_correct(img, γ)

绘图如上

我们可以将该实现的效率与time.time()进行比较。

相关问题