如何将分离的RGB数组重新转换为图像(Python 16位处理场景)
问题分析与解决方案
你的核心问题在于16位图像数据与Pillow的兼容性,以及不必要的Pillow中转导致格式损坏。以下是针对性的修复步骤和代码:
关键问题点
- FITS图像读取后通常是
uint16或浮点型的3通道数组(维度为(3, H, W)),而Pillow的Image.fromarray('RGB')默认处理8位数据,直接传入16位数组会导致格式错误。 - 无需通过Pillow中转,直接使用numpy数组让imageio保存,更适配16位图像的处理流程。
修复后的代码
import imageio.v3 as iio import numpy as np def load_pic(): filename = "FinalStacked.fit" print(f"loading {filename}") # 读取FITS图像,保留原始数据类型 picky = iio.imread(filename, plugin="FITS") shape = picky.shape print(f"Image loaded, size = {shape}, dtype = {picky.dtype}") # 拆分RGB通道(FITS的通道维度在前) reds = picky[0] greens = picky[1] blues = picky[2] return reds, greens, blues, shape def finish(reds, greens, blues): # 将通道从(3, H, W)转为(H, W, 3),符合imageio保存的格式 out = np.dstack((reds, greens, blues)) # 处理数据类型:如果是浮点型,先归一化到0-65535再转uint16(PNG支持16位无符号整数) if out.dtype.kind == 'f': out = (out - out.min()) / (out.max() - out.min()) * 65535 out = out.astype(np.uint16) # 直接用imageio保存numpy数组,指定格式为PNG 16位 iio.imwrite("done.png", out, plugin="pillow", format="PNG", mode="RGB;16") print("图像保存完成") reds, greens, blues, shape = load_pic() finish(reds, greens, blues)
额外说明
- 避免使用全局变量:改用函数返回值传递数据,代码更健壮。
- 数据类型处理:FITS图像可能是浮点型(比如天文图像常用的float32),需要先归一化到16位无符号整数的范围(0-65535)才能正确保存为PNG。
- imageio保存时指定
mode="RGB;16",确保以16位RGB格式写入PNG,避免自动降级为8位。
内容的提问来源于stack exchange,提问作者Geoff Horton
相关产品推荐
相关产品推荐

