image - 用'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
当我将数组转换为图像并查看它时,已通过第一种方法反转的图像具有更好的质量,然后是第二种方法反转的图像。我不明白为什么。你能帮助我吗?
解决方案
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.uint8
。uint8
是一个 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 大得多。
推荐阅读
- ios - 退款通知的 iOS App 特定与 Master 共享密钥
- rust - `dyn` 和泛型有什么区别?
- java - 在尝试使用“spring-boot-starter-websocket”插件之前,有人遇到过这个错误吗?
- javascript - 如何使用 socket.io、nodejs 和 vanilla js 在不向客户端公开密钥的情况下加密和解密数据?
- c# - 在 Blazor 中打开新窗口时如何插入参数
- javascript - 在 iframe 弹出窗口上显示下载无 PDF 文件的链接
- java - java中是否有类似python的where方法
- python - 使用 diff() 减去行
- r - 如何在每个条上添加测试?
- java - 自定义类型数据集如何调用 groupBy 方法?