Python - 使用PIL实现灰度转换公式

3
我希望用自己的代码制作灰度图像。
from PIL import Image

path = "people.jpg"

img = Image.open(path)
img = img.convert("LA")
img.save("new_image.png")

我替换了img.convert()为我的公式,但是它没有起作用。

from PIL import Image

path = "people.jpg"

img = Image.open(path)
rgb = img.convert("RGB")
width,height = rgb.size

for x in range(width):
    for y in range(height):
        red,green,blue = rgb.getpixel((x,y))
        value = red * 299/1000 + green * 587/1000 + blue * 114/1000
        value = int(value)
        rgb.putpixel((x,y),value)


rgb.save("new.png")

你有什么想法出了问题吗?新图片的背景是红色的。


2
你正在更新一张RGB图像,因此需要使用类似于rgb.putpixel((x,y),(value, value, value))的东西。 - martineau
1
有点离题,但第一个代码片段创建了一个带有alpha通道的灰度图像,而第二个则创建了一个没有任何alpha通道的RGB图像。除了您的主要问题之外,关于alpha通道,您究竟想发生什么? - martineau
2个回答

3
正如martineau所提到的,rgb被初始化为RGB(三色)图像,因此它需要RGB值。你想要灰度图像,只需要一个通道。这里有两个选项:
  1. 按照martineau的建议,仅仅将rgb.putpixel((x,y),value)替换为rgb.putpixel((x, y), (value, value, value))。这样将会给它正确的三种颜色值。
  2. 在将像素放入图片之前使用Image.new('L',...)创建一个新的灰度图像。
下面是如何实现第二个选项的方法(请注意我在使用Python 2.7):
from PIL import Image

path = "people.jpg"

img = Image.open(path)
width, height = rgb.size
gray = Image.new('L', (width, height))

for x in xrange(width):
    for y in xrange(height):
        r, g, b = img.getpixel((x, y))
        value = r * 299.0/1000 + g * 587.0/1000 + b * 114.0/1000
        value = int(value)
        gray.putpixel((x, y), value)

gray.save("new.png")

另外,如果速度是一个问题,考虑使用putdata()代替putpixel()。(这不是重点,所以我不会过多阐述。)


1
如果我没有其他事情要做(所以没有时间像你一样写一个适当的答案),那么基本上这就是我会建议的。+1 - martineau

0

灰度图像每个像素将具有两个值的元组 - (亮度值,255)。创建一个新的灰度图像并为每个像素设置值即可。

greyim=Image.new("LA",(width,height))

for x in range(width):
    for y in range(height):
        red,green,blue = rgb.getpixel((x,y))
        value = red * 299/1000 + green * 587/1000 + blue * 114/1000
        greyim.putpixel((x,y),(value,255))

你正在创建一个带有alpha(透明度)通道的灰度图像,模式为“LA”。你似乎根本没有使用任何透明度,所以也许一个简单的灰度图像(模式“L”)也可以工作。然后你会调用putpixel((x,y), value)。 - Michiel Overtoom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接