更改 Numpy 中的对比度

Ale*_*lex 3 python numpy

我想编写一个纯 Numpy 函数来更改 RGB 图像(表示为 Numpy uint8 数组)的对比度,但是,我编写的函数不起作用,我不明白为什么。

这是一个示例图像:

在此输入图像描述

这是一个使用 PIL 且工作正常的函数:

def change_contrast(img, factor):
    def contrast(pixel):
        return 128 + factor * (pixel - 128)
    return img.point(contrast)

from PIL import Image

img = Image.fromarray(img.astype(np.uint8))
img1 = change_contrast(img, factor=2.0)
Run Code Online (Sandbox Code Playgroud)

输出:

在此输入图像描述

现在这是一个纯 Numpy 函数,在我看来,它与上面的其他函数执行完全相同的操作,但它根本不起作用:

def change_contrast2(img, factor):
    return 128 + factor * (img - 128)

img1 = change_contrast2(img, factor=2.0)
Run Code Online (Sandbox Code Playgroud)

其中img是 Numpy 数组。输出是这样的:

在此输入图像描述

我不明白发生了什么事,如果有任何提示我会很高兴!

Pau*_*zer 5

您看到的是无符号整数下溢:

>>> a = np.array((64, 128, 192), dtype=np.uint8)
>>> a
array([ 64, 128, 192], dtype=uint8)
>>> a-128
array([192,   0,  64], dtype=uint8) # note the "wrong" value at pos 0
Run Code Online (Sandbox Code Playgroud)

避免这种情况的一种方法是强制或类型提升:

factor = float(factor)
np.clip(128 + factor * img - factor * 128, 0, 255).astype(np.uint8)
Run Code Online (Sandbox Code Playgroud)

由于因子是浮点型,因此产品的 dtypefactor * img被提升为浮点型。由于浮点数可以处理负数,因此可以消除下溢。

为了能够转换回uint8我们剪辑到可以用这种类型表达的范围。