【问题标题】:Change contrast of image in PIL在 PIL 中更改图像的对比度
【发布时间】:2018-11-27 22:29:09
【问题描述】:

我有一个程序应该改变对比度,但我觉得它并没有真正改变对比度。它将某些区域变为红色,而我不希望它。如果您能告诉我如何删除它们,谢谢。 代码如下:

from PIL import Image


def change_contrast(img, level):

    img = Image.open("C:\\Users\\omar\\Desktop\\Site\\Images\\obama.png")
    img.load()

    factor = (259 * (level+255)) / (255 * (259-level))
    for x in range(img.size[0]):
        for y in range(img.size[1]):
            color = img.getpixel((x, y))
            new_color = tuple(int(factor * (c-128) + 128) for c in color)
            img.putpixel((x, y), new_color)

    return img

result = change_contrast('C:\\Users\\omar\\Desktop\\Site\\Images\\test_image1.jpg', 100)
result.save('C:\\Users\\omar\\Desktop\\Site\\Images\\test_image1_output.jpg')
print('done')

这是图像及其结果:

如果这是实际的对比方法,请随时告诉我

【问题讨论】:

  • 我无法重现这个。我试过你的代码,输出图像看起来不错。 i.stack.imgur.com/QhR3n.jpg
  • 您的代码包含两种不同的加载输入图像的尝试。您的test_image1.jpg 将不会被使用,因为您在函数体中硬编码了obama.png。你确定你使用的是你认为你正在使用的输入文件吗?

标签: python python-3.x python-imaging-library


【解决方案1】:

我无法重现您的错误。在我的平台 (debian) 上,只有 Pillow fork 可用,所以如果您使用的是较旧的 PIL 包,这可能是原因。

无论如何,有一个内置方法Image.point() 可以进行这种操作。它将映射到每个通道中的每个像素,这应该比在 python 中执行三个嵌套循环要快。

def change_contrast(img, level):
    factor = (259 * (level + 255)) / (255 * (259 - level))
    def contrast(c):
        return 128 + factor * (c - 128)
    return img.point(contrast)

change_contrast(Image.open('barry.png'), 100)

您的输出看起来像是在单个通道中溢出(红色)。我看不出有什么理由会发生这种情况。但是,如果您的level 高于 259,则输出会反转。类似的事情可能是最初的错误的原因。

def change_contrast_multi(img, steps):
    width, height = img.size
    canvas = Image.new('RGB', (width * len(steps), height))
    for n, level in enumerate(steps):
        img_filtered = change_contrast(img, level)
        canvas.paste(img_filtered, (width * n, 0))
    return canvas

change_contrast_multi(Image.open('barry.png'), [-100, 0, 100, 200, 300])

一种可能的解决方法是确保对比度过滤器仅返回 [0-255] 范围内的值,因为该错误似乎是由某种负值溢出引起的。

def change_contrast(img, level):
    factor = (259 * (level + 255)) / (255 * (259 - level))
    def contrast(c):
        value = 128 + factor * (c - 128)
        return max(0, min(255, value))
    return img.point(contrast)

【讨论】:

  • 好吧,这正是我想要的,我想制作一个与比例相关的对比度修饰符。我会尝试一下,看看它是否有效。如果是,我会接受它作为答案。
  • 为什么当我在普通 Numpy 中构建它并在表示为 Numpy 数组的图像上使用它时,相同的功能不起作用?
  • 我的回答中对此进行了解释。 point 是 Image 类的一个方法。
  • @Alex 我发现了这个麻烦:python (128 + (img_arr - 128) * 1 != 128 + (img_arr - 128) * 1.0).sum() Out[14]: 21893 这是因为类型转换
  • @Alex 使用转换为 int16 python (128 + (img_arr - 128) * 1 != 128 + (img_arr - 128) * 1.0).sum() Out[17]: 21893 img_arr = img_arr.astype(dtype = np.int16) (128 + (img_arr - 128) * 1 != 128 + (img_arr - 128) * 1.0).sum() Out[19]: 0
【解决方案2】:

PIL 模块中已经建立了一个名为contrast 的类。你可以简单地使用它。

from PIL import Image, ImageEnhance
image = Image.open(':\\Users\\omar\\Desktop\\Site\\Images\\obama.png')
scale_value=scale1.get()
image = ImageEnhance.Contrast(image).enhance(scale_value)
image.show()

【讨论】:

  • 是的,但我无法调整对比度。我想要一个定义应用于照片的对比度级别的比例,并且此命令无法调整,或者我不知道如何调整。如果您需要我正在开发的其他适用于我正在谈论的内容的程序,请告诉我,我会将其放在帖子中。
  • 您想提高对比度吗? o
  • 是的,根据用户选择的级别,照片与原始照片的对比度更高。我应该发布其他程序吗?
  • 不需要。使用contrast.enhance() 方法获得比原始方法更多的对比。通过用户选择进入增强方法。让我知道它是否有效。
  • image = ImageEnhance.Contrast(image).enhance(scale_value)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-21
相关资源
最近更新 更多