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

时间:2018-01-23 16:29:37

标签: python python-3.x 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的元素。我试图通过平均函数测量接近度但在此之前算术平均值,但我的所有尝试都没有让我得到任何好结果。

我正在处理的图片: enter image description here

我的目标是: goal picture

我是否接近解决方案?任何提示/提示都会很棒

3 个答案:

答案 0 :(得分:5)

我正在学习Python和numpy并且认为我尝试实现&#34; LookUp Table&#34; (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')

enter image description here

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

答案 1 :(得分:2)

您需要应用这样的映射曲线:

contrast

它使暗色调更暗,灯光更亮,并增加中等色调的范围。

为了实现这一点,我找到了最小值和最大值,然后创建了一个查找表,将缩小的剩余范围扩展到0到25​​5之间的整个范围。之后,我{{3} }。

这肯定会留下一些阻塞,因为源的漂亮渐变范围是以有损方式压缩的。要解决此问题,您可以考虑应用&#34;智能模糊&#34;该算法仅模糊它们之间具有低对比度的像素,并且不接触具有高对比度的像素。 (尽管如此,我还没有看到与numpy友好算法的良好链接。)

答案 2 :(得分:1)

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

设置,与this answer中的方法相同。

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))

结果实际上与this answer中的结果相同,只是代码少了一点: enter image description here

现在,在此图像中,这就足够了。但是,某些图像可能有一些像素实际上接近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%的值都将被有效去除。 (按照您认为合适的方式使用这些值) enter image description here