纯粹用numpy调整图像的对比度

新手上路,请多包涵

我正在尝试为灰度颜色的图像编写对比度调整,但到目前为止找不到正确的方法。这就是我想出的:

 import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
from scipy import misc
def fix_contrast(image):
    minimumColor = np.amin(image)
    maximumColor = np.amax(image)
    #avg = (minimumColor - maximumColor)/2 first attempt
    avg = np.mean(image) #second attempt
    colorDownMatrix = image < avg # also tried
    colorUpMatrix = image > avg
    #also tried:   colorUpMatrix = image > avg * 1.2
    # and : colorDownMatrix = image < avg* 0.3

    image = image - minimumColor*colorDownMatrix
    image = image + maximumColor*colorUpMatrix
    lessThen0 = image<0
    moreThen255 = image>255
    image[lessThen0] = 0
    image[moreThen255] = 255
    return image

我的一般尝试是将元素减少到 0,即它们“更接近”到 0 的像素,并将元素增加到 255,即“更接近”到 255 的元素。我尝试通过均值函数测量接近度,但在此之前通过算术平均值,但我所有的尝试都没有让我得到任何好的结果。

我正在处理的图像: 在此处输入图像描述

我的目标是: 目标图片

我离解决方案很近吗?任何提示/技巧都会很棒

原文由 barshopen 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 967
2 个回答

我正在学习 Python 和 numpy 并认为我会尝试实现 “查找表” (LUT)。它工作正常,输出图像具有从黑色到白色的完整范围,但我很高兴收到改进建议。

 #!/usr/local/bin/python3
import numpy as np
from PIL import Image

# Open the input image as numpy array, convert to greyscale and drop alpha
npImage=np.array(Image.open("cartoon.png").convert("L"))

# Get brightness range - i.e. darkest and lightest pixels
min=np.min(npImage)        # result=144
max=np.max(npImage)        # result=216

# Make a LUT (Look-Up Table) to translate image values
LUT=np.zeros(256,dtype=np.uint8)
LUT[min:max+1]=np.linspace(start=0,stop=255,num=(max-min)+1,endpoint=True,dtype=np.uint8)

# Apply LUT and save resulting image
Image.fromarray(LUT[npImage]).save('result.png')

在此处输入图像描述

关键词:Python、Numpy、PIL、Pillow、图像、图像处理、LUT、查找表、查找、对比度、拉伸。

原文由 Mark Setchell 发布,翻译遵循 CC BY-SA 4.0 许可协议

增加对比度(即拉开较暗和较亮的像素)的最简单方法就是在整个光谱(0 到 255)上“扩展”当前现有范围(144 到 216):

设置,与 此答案 中的方式相同。

 import numpy as np
from PIL import Image

pixvals = np.array(Image.open("image.png").convert("L"))

然后扩大范围

pixvals = ((pixvals - pixvals.min()) / (pixvals.max()-pixvals.min())) * 255
Image.fromarray(pixvals.astype(np.uint8))

结果实际上与 此答案 中的相同,只是代码略少: 在此处输入图像描述

现在,在这个图像中,这可能就足够了。然而,某些图像可能有一些像素非常接近 0 或 255,这会使该方法无效。

这里 numpy.percentile() 来救援。这个想法是“剪辑”允许像素存在的范围。

 minval = np.percentile(pixvals, 2)
maxval = np.percentile(pixvals, 98)
pixvals = np.clip(pixvals, minval, maxval)
pixvals = ((pixvals - minval) / (maxval - minval)) * 255
Image.fromarray(pixvals.astype(np.uint8))

这会导致对比度稍微高一点,因为所有低于 2% 和高于 98% 的值都被有效地去除了。 (按照您认为合适的方式使用这些值) 在此处输入图像描述

原文由 Johan Dettmar 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题