相等的numpy数组通过Pillow生成不同的图像

时间:2015-08-07 12:11:10

标签: python arrays python-3.x numpy 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')

Assertion说两个数组相等,但这里是图片:

1.bmp和3.bmp:http://i.stack.imgur.com/EwwyY.png

2.bmp:http://i.stack.imgur.com/kz7pB.png

这里可能出现什么问题?

1 个答案:

答案 0 :(得分:2)

错误的原因可能是数据类型和索引。

  • 首先,数据类型:

    matrix_out = np.zeros(matrix.shape)
    

    创建一个float数组,你应该用:

    替换它
    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