相等的 numpy 数组通过 Pillow 产生不同的图像
Equal numpy arrays produce different images via Pillow
我在一个简单的脚本中使用 numpy 和 Pillow 来应用图像过滤器。图像和内核的卷积实现后,出现了一些错误,我能够将其减少到一个非常棘手的情况。
import numpy as np
from PIL import Image
def image_to_array(image_path : str) -> np.array:
image = Image.open(image_path)
array = np.array(image)
array.reshape(-1, array.shape[2])
return array
def dont_filter_anything(matrix : np.ndarray, kernel : np.ndarray):
matrix_out = np.zeros(matrix.shape)
for (row_num, cell_num, channel_num), element in np.ndenumerate(matrix):
matrix_out[row_num][cell_num][channel_num] = element
return matrix_out
IDENTITY_FILTER = np.array([[0, 0, 0], [0, 1, 0], [0, 0, 0]])
第二个函数只是复制而不是产生卷积的结果。鉴于这些定义,我执行以下操作:
image1 = image_to_array('1.bmp')
image2 = dont_filter_anything(image1 , IDENTITY_FILTER)
assert np.all(image1 == image2)
Image.fromarray(image2 , mode='RGB').save('2.bmp')
Image.fromarray(image1 , mode='RGB').save('3.bmp')
断言说两个数组相等,但图片如下:
1.bmp 和 3.bmp:http://i.stack.imgur.com/EwwyY.png
2.bmp: http://i.stack.imgur.com/kz7pB.png
这里会出什么问题?
错误的原因可能在于数据类型和索引。
一、数据类型:
matrix_out = np.zeros(matrix.shape)
创建一个浮点数组,您应该将其替换为:
matrix_out = np.zeros_like(matrix)
或
matrix_out = np.zeros(matrix.shape, dtype=matrix.dtype)
保证in
矩阵和out
矩阵的数据类型相同。默认情况下 np.zeros
创建一个浮点数组。
二、索引:
matrix_out[row_num][cell_num][channel_num] = element
应替换为合适的(更快)numpy indexing 方法:
matrix_out[row_num, cell_num, channel_num] = element
这样,该函数将被重写为:
def dont_filter_anything(matrix, kernel):
matrix_out = np.zeros_like(matrix)
for (row_num, cell_num, channel_num), element in np.ndenumerate(matrix):
matrix_out[row_num, cell_num, channel_num] = element
return matrix_out
现在 PIL 可以正确保存图像 2.bmp
。
我在一个简单的脚本中使用 numpy 和 Pillow 来应用图像过滤器。图像和内核的卷积实现后,出现了一些错误,我能够将其减少到一个非常棘手的情况。
import numpy as np
from PIL import Image
def image_to_array(image_path : str) -> np.array:
image = Image.open(image_path)
array = np.array(image)
array.reshape(-1, array.shape[2])
return array
def dont_filter_anything(matrix : np.ndarray, kernel : np.ndarray):
matrix_out = np.zeros(matrix.shape)
for (row_num, cell_num, channel_num), element in np.ndenumerate(matrix):
matrix_out[row_num][cell_num][channel_num] = element
return matrix_out
IDENTITY_FILTER = np.array([[0, 0, 0], [0, 1, 0], [0, 0, 0]])
第二个函数只是复制而不是产生卷积的结果。鉴于这些定义,我执行以下操作:
image1 = image_to_array('1.bmp')
image2 = dont_filter_anything(image1 , IDENTITY_FILTER)
assert np.all(image1 == image2)
Image.fromarray(image2 , mode='RGB').save('2.bmp')
Image.fromarray(image1 , mode='RGB').save('3.bmp')
断言说两个数组相等,但图片如下:
1.bmp 和 3.bmp:http://i.stack.imgur.com/EwwyY.png
2.bmp: http://i.stack.imgur.com/kz7pB.png
这里会出什么问题?
错误的原因可能在于数据类型和索引。
一、数据类型:
matrix_out = np.zeros(matrix.shape)
创建一个浮点数组,您应该将其替换为:
matrix_out = np.zeros_like(matrix)
或
matrix_out = np.zeros(matrix.shape, dtype=matrix.dtype)
保证
in
矩阵和out
矩阵的数据类型相同。默认情况下np.zeros
创建一个浮点数组。二、索引:
matrix_out[row_num][cell_num][channel_num] = element
应替换为合适的(更快)numpy indexing 方法:
matrix_out[row_num, cell_num, channel_num] = element
这样,该函数将被重写为:
def dont_filter_anything(matrix, kernel):
matrix_out = np.zeros_like(matrix)
for (row_num, cell_num, channel_num), element in np.ndenumerate(matrix):
matrix_out[row_num, cell_num, channel_num] = element
return matrix_out
现在 PIL 可以正确保存图像 2.bmp
。