将看似相同的数组写入两个图像文件会导致不同的结果
Writing seemingly same array to two image files leads to different results
我正在尝试使用 PIL 库读写 tiff 图像。在测试时,我注意到保存以不同方式生成的看似相同的 numpy 数组会导致磁盘上出现不同的图像。为什么会这样,我该如何解决?
出于测试目的,我创建了一个 image with GIMP (upscaled from 8x8),我将其保存为 TIF,读取到一个 numpy 数组并写回一个 tif 文件:
img_gimp = Image.open('img_gimp.tif')
imgarray_gimp = np.array(img_gimp)
img_gimp = Image.fromarray(imgarray_gimp, mode = 'I;16')
img_gimp.save('final_gimp.tif')
结果和预期的一样,和原图是一样的。到目前为止一切顺利。
现在我直接在 python 代码中生成了相同的图像:
imgarray_direct = np.zeros(shape = (8, 8)).astype(int)
for i in range(2):
for j in range(2):
image[i][j] = 65535
正在将此数组写入磁盘...
img_direct = Image.fromarray(imgarray_direct, mode = 'I;16')
img_direct.save('final_direct.tif')
没有给我预期的结果,而是我发现了这个:
image generated by for loop (upscaled from 8x8)
正在做
print(np.array_equal(imgarray_gimp, imgarray_direct))
给出True
,再看print(imgarray_gimp)
和print(imgarray_direct)
,看不出有什么区别。
这是有意为之的行为吗?如果是,原因是什么?
感谢您的回答!
正如@MarkSetchell 在评论中暗示的那样,问题是您的原始数据 numpy 数组的 dtype
与您之后提供的 PIL 图像 mode
字符串不匹配。更改传递给 astype
的参数或简单地在创建数组时传递正确的类型为我解决了这个问题。修改后的代码如下所示:
import numpy as np
from PIL import Image
#Generate raw image data (16-bit!)
image_data = np.zeros(shape = (8, 8), dtype=np.uint16)#this is the big change
for i in range(2):
for j in range(2):
image_data[i][j] = 65535
#Save image as TIF to disk
image_direct = Image.fromarray(image_data, mode = 'I;16')
image_direct.save('final_direct.tif')
附带说明一下,我很惊讶您使用的模式字符串 I;16
是有效的;我在 pillow's documentation.
中找不到关于它的任何提及
我正在尝试使用 PIL 库读写 tiff 图像。在测试时,我注意到保存以不同方式生成的看似相同的 numpy 数组会导致磁盘上出现不同的图像。为什么会这样,我该如何解决?
出于测试目的,我创建了一个 image with GIMP (upscaled from 8x8),我将其保存为 TIF,读取到一个 numpy 数组并写回一个 tif 文件:
img_gimp = Image.open('img_gimp.tif')
imgarray_gimp = np.array(img_gimp)
img_gimp = Image.fromarray(imgarray_gimp, mode = 'I;16')
img_gimp.save('final_gimp.tif')
结果和预期的一样,和原图是一样的。到目前为止一切顺利。
现在我直接在 python 代码中生成了相同的图像:
imgarray_direct = np.zeros(shape = (8, 8)).astype(int)
for i in range(2):
for j in range(2):
image[i][j] = 65535
正在将此数组写入磁盘...
img_direct = Image.fromarray(imgarray_direct, mode = 'I;16')
img_direct.save('final_direct.tif')
没有给我预期的结果,而是我发现了这个: image generated by for loop (upscaled from 8x8)
正在做
print(np.array_equal(imgarray_gimp, imgarray_direct))
给出True
,再看print(imgarray_gimp)
和print(imgarray_direct)
,看不出有什么区别。
这是有意为之的行为吗?如果是,原因是什么?
感谢您的回答!
正如@MarkSetchell 在评论中暗示的那样,问题是您的原始数据 numpy 数组的 dtype
与您之后提供的 PIL 图像 mode
字符串不匹配。更改传递给 astype
的参数或简单地在创建数组时传递正确的类型为我解决了这个问题。修改后的代码如下所示:
import numpy as np
from PIL import Image
#Generate raw image data (16-bit!)
image_data = np.zeros(shape = (8, 8), dtype=np.uint16)#this is the big change
for i in range(2):
for j in range(2):
image_data[i][j] = 65535
#Save image as TIF to disk
image_direct = Image.fromarray(image_data, mode = 'I;16')
image_direct.save('final_direct.tif')
附带说明一下,我很惊讶您使用的模式字符串 I;16
是有效的;我在 pillow's documentation.