如何使用 python 将 3 张 TIFF 图像合并为 1 张 PNG 图片?
How to combine 3 TIFF images into 1 PNG image with python?
每个 RGB 颜色通道有 1 个 tif 图像,我想使用 python 将这 3 个图像组合成一个 RGB 图像,所有 3 个通道均为 png 格式。我已经尝试了几个使用 PIL 库的实验,但我无法得到它。
我上传了 3 张示例图片到 Google 驱动器 here。有人知道怎么做吗?
答案取决于您真正想要实现的目标...
如果您想准确合并 3 个通道,您可能应该使用 tifffile
模块来理解输入文件中的浮点值并在输出文件中准确表示它们。事实上,gdal
可能会更好,因为它理解文件中的 GeoTIFF 标签。 PIL
无法处理 RGB float32 图像。
如果你想要一些模糊地允许某种近似可视化的东西,如 PNG,你需要做一些工作来将你的值缩放到合理的(但不准确),因为 PNG 不能像你的图像包含的那样表示浮点数据.
这是您的频道与 tifffile
更准确的合并:
from tifffile import imread, imwrite
import numpy as np
r = imread('r.tif')
g = imread('g.tif')
b = imread('b.tif')
RGB = np.dstack((r,g,b))
imwrite('result.tif', RGB)
使用 PIL,您将使用 Image.merge()
,但您的数据是浮动的,因此您需要先将其转换为 uint8/uint16
才能获得可以存储在 PNG 中的内容:
from PIL import Image
import numpy as np
# Open images
red = Image.open('red_channel.tif')
green = Image.open('green_channel.tif')
blue = Image.open('blue_channel.tif')
# Convert PIL Images to Numpy arrays
npRed = np.array(red)
npGreen = np.array(green)
npBlue = np.array(blue)
# Get rid of the pesky -3.4e+38 marker for out-of-bounds pixels
npRed[npRed < 0] = 0
npBlue[npBlue < 0] = 0
npGreen[npGreen < 0] = 0
# Find maximum across all channels for scaling
max = np.max([npRed,npGreen,npBlue])
# Scale all channels equally to range 0..255 to fit in a PNG (could use 65,535 and np.uint16 instead)
R = (npRed * 255/max).astype(np.uint8)
G = (npGreen * 255/max).astype(np.uint8)
B = (npBlue * 255/max).astype(np.uint8)
# Build a PNG
RGB = np.dstack((R,G,B))
Image.fromarray(RGB).save('result.png')
每个 RGB 颜色通道有 1 个 tif 图像,我想使用 python 将这 3 个图像组合成一个 RGB 图像,所有 3 个通道均为 png 格式。我已经尝试了几个使用 PIL 库的实验,但我无法得到它。
我上传了 3 张示例图片到 Google 驱动器 here。有人知道怎么做吗?
答案取决于您真正想要实现的目标...
如果您想准确合并 3 个通道,您可能应该使用 tifffile
模块来理解输入文件中的浮点值并在输出文件中准确表示它们。事实上,gdal
可能会更好,因为它理解文件中的 GeoTIFF 标签。 PIL
无法处理 RGB float32 图像。
如果你想要一些模糊地允许某种近似可视化的东西,如 PNG,你需要做一些工作来将你的值缩放到合理的(但不准确),因为 PNG 不能像你的图像包含的那样表示浮点数据.
这是您的频道与 tifffile
更准确的合并:
from tifffile import imread, imwrite
import numpy as np
r = imread('r.tif')
g = imread('g.tif')
b = imread('b.tif')
RGB = np.dstack((r,g,b))
imwrite('result.tif', RGB)
使用 PIL,您将使用 Image.merge()
,但您的数据是浮动的,因此您需要先将其转换为 uint8/uint16
才能获得可以存储在 PNG 中的内容:
from PIL import Image
import numpy as np
# Open images
red = Image.open('red_channel.tif')
green = Image.open('green_channel.tif')
blue = Image.open('blue_channel.tif')
# Convert PIL Images to Numpy arrays
npRed = np.array(red)
npGreen = np.array(green)
npBlue = np.array(blue)
# Get rid of the pesky -3.4e+38 marker for out-of-bounds pixels
npRed[npRed < 0] = 0
npBlue[npBlue < 0] = 0
npGreen[npGreen < 0] = 0
# Find maximum across all channels for scaling
max = np.max([npRed,npGreen,npBlue])
# Scale all channels equally to range 0..255 to fit in a PNG (could use 65,535 and np.uint16 instead)
R = (npRed * 255/max).astype(np.uint8)
G = (npGreen * 255/max).astype(np.uint8)
B = (npBlue * 255/max).astype(np.uint8)
# Build a PNG
RGB = np.dstack((R,G,B))
Image.fromarray(RGB).save('result.png')