TIFF图像保存失败求助:PIL等库无法保存重建后的图像
问题:分割TIFF图像重建后无法保存为TIFF格式
我有一张TIFF图像,将其分割为多个数组后重建为另一张图像。我希望将重建后的图像保存为TIFF格式以保留精确分辨率,但无法理解为何PIL等库无法实现。我尝试使用PIL保存,但似乎存在维度问题。我可以通过plt可视化该图像,但无法将其保存为TIFF格式(这是我工作中唯一可使用的格式)。我已尝试使用PIL并重塑数组,但仍未解决问题。
以下是我的代码:
from skimage import io import matplotlib.pyplot as plt import numpy as np import imageio import PIL from PIL import Image # read the image stack img=io.imread(r'C:\Users\pheni\Downloads\PICTURE.tiff') # show the image plt.imshow(img,cmap='gray') numpydata=np.array(img) plt.imshow(numpydata) x0=767 y0=228 pitch1=61 pitch2=61 N=numpydata[int(y0-pitch2/2):int(y0+pitch2/2),int(x0-pitch1/2):int(x0+pitch1/2)] plt.imshow(N) Tableau=np.zeros((66,66,pitch1,pitch2)) Image4=np.zeros([66,66]); for i in range(0,56): for j in range(0,56): Tableau[i,j,:,:]=numpydata[int(y0+i*pitch2-pitch2/2):int(y0+i*pitch2+pitch2/2), int(x0+j*pitch1-pitch1/2):int(x0+j*pitch1+pitch1/2)] Image4[i,j]=np.sum(Tableau[i,j,:,:]); plt.imshow(Image4)
解决方案
问题根源
你的Image4是**(66,66)的float类型数组**,PIL保存TIFF时对数据类型和格式有严格要求:
- 单通道灰度图需为2D数组,但数据类型通常要求是uint8/uint16等整数类型(TIFF支持浮点,但部分专业软件兼容性差);
- 直接用
Image.fromarray(Image4)会因float类型或格式不匹配报错。
修复步骤
1. 归一化并转换数据类型
将Image4的数值映射到TIFF支持的整数范围,根据数据精度需求选择类型:
# 归一化到0-255,转换为uint8(适用于普通精度需求) Image4_normalized = (Image4 - Image4.min()) / (Image4.max() - Image4.min()) * 255 Image4_uint8 = Image4_normalized.astype(np.uint8) # 若需高精度,转换为uint16(0-65535范围) # Image4_uint16 = ((Image4 - Image4.min()) / (Image4.max() - Image4.min()) * 65535).astype(np.uint16)
2. 用PIL保存TIFF并保留分辨率
转换为PIL Image对象后,直接保存并指定分辨率:
# 创建PIL图像对象 img_pil = Image.fromarray(Image4_uint8) # 设置分辨率(单位:dpi),可替换为原图的分辨率数值 img_pil.save('reconstructed_image.tiff', dpi=(300, 300), format='TIFF')
3. 备选方案:用skimage/io直接保存
如果PIL仍有问题,skimage的io模块可直接处理浮点数组或整数数组:
# 保存浮点类型TIFF(仅推荐专业软件读取) io.imsave('reconstructed_float.tiff', Image4) # 保存归一化后的uint16类型TIFF io.imsave('reconstructed_uint16.tiff', Image4_uint16)
额外优化:读取原图分辨率复用
如果需要和原图保持一致的分辨率,可从原图元数据中读取后复用:
from skimage import metadata # 读取原图分辨率 img_metadata = metadata.read_metadata(r'C:\Users\pheni\Downloads\PICTURE.tiff') dpi = img_metadata.get('dpi', (300, 300)) # 保存时使用该分辨率 img_pil.save('reconstructed_image.tiff', dpi=dpi, format='TIFF')
内容的提问来源于stack exchange,提问作者Rosario night
相关产品推荐
相关产品推荐

