首页 > 解决方案 > 用'abs'和numpy反转图像

问题描述

img = Image.open(path)
data_origin = np.asarray( img, dtype='uint8' )
data = np.array(data_origin) # 300 x 300 x 4

1)for i in range(data.shape[0]): # invert colors
    for j in range(data.shape[1]):
        for k in range(3): # only first three dims r g b
            data[i,j,k] = abs(data[i,j,k] - 255)

2)data[:,:,:3] = np.abs(data[:,:,:3] - 255) # why does it work worse?
''''
applying max pooling
...
end

当我将数组转换为图像并查看它时,已通过第一种方法反转的图像具有更好的质量,然后是第二种方法反转的图像。我不明白为什么。你能帮助我吗?

第一种方法

第二种方法

标签: imagenumpypooling

解决方案


data在同一个对象上执行两种方法时要注意的一个错误。但是,我已经在自己的图像上尝试了您的方法,结果不正确。

您可以通过将计算改写为 来修复方法二中的行为255 - data[:,:,:3]。此解决方案假定您的图像对于 (R,G,B) 的最大值为 (255, 255, 255)。

# old method
data[:,:,:3] = np.abs(data[:,:,:3] - 255) 

# new method
data[:,:,:3] = 255 - data[:,:,:3]

您可以通过运行代码来验证此方法

img = Image.open(path)
data = np.asarray(img, dtype='uint8' )
experiment_1 = np.copy(data)
experiment_2 = np.copy(data)

# Perform method 1 on experiment_1
# ...
# Perform method 2 on experiment_2
# ...

print(np.all(experiment_1 == experiment_2))

如果您想了解代码为什么会这样,那是因为您的代码data_origin数组是 datatype np.uint8uint8是一个 8 位的无符号整数,这意味着它只能是 [0,255] 中的值。将 uint8 减去 255 不会产生负数,但会溢出 x - 255。

例如,

a = np.array([10, 100, 125, 250], dtype='uint8')
print(a - 255) # incorrect
>> array([ 11, 101, 126, 251], dtype=uint8)

print(255 - a) # correct
>> array([245, 155, 130,   5], dtype=uint8)

尽管np.abs(data[:,:,:3] - 255)应该表现得像255 - data[:,:,:3](因为在范围 [0, 255] 中f(x) = abs(x-255)等于域),但数据类型会导致此转换不正确。f(x) = 255 -x

此代码的另一个修复方法是替换dtype='uint8'dtype='int32'(因为 int32 允许负值)。但是,我不推荐这种解决方案,因为 int32 比 uint8 大得多。


推荐阅读