保存 tiff 堆栈时如何指定颜色图
How to specify colormap when saving tiff stack
我在 python 中使用 tifffile
来保存 3 通道 tiff 堆栈,然后我想将其读入 ImageJ 或 FIJI。这些 tiff 堆栈在 ImageJ 中作为复合材料打开,每个通道都分配了一个(可能是默认值)colormap/LUT。但是,分配的颜色并不是对我的图像有意义的颜色。 我的问题是在使用 tifffile
.
保存图像时,我不知道如何为每个通道指定颜色图
例如,我想要分配以下颜色图:
- 通道 0:灰色
- 通道 1:绿色
- 通道 2:红色
这是我用来保存文件的代码:
# save hyperstack
with tifffile.TiffWriter(filename, bigtiff=False, imagej=True) as tif:
for i in range(t_stack.shape[0]):
tif.save(t_stack[i], metadata={'Composite mode': 'composite'})
必须有元数据与保存通道颜色映射信息的 tiff 一起保存,因为我可以在 ImageJ 中手动编辑颜色分配,然后保存、关闭它,然后当我再次打开文件时,它会保留我的手动颜色图分配。所以我猜一定有一个元数据标签(也许是颜色图?)可以用来指定通道颜色,但我找不到任何关于使用什么标签或语法的信息。
自己创建私有 IJMetadata
(50839) 和 IJMetadataByteCounts
(50838) TIFF 标签,并将它们作为额外标签传递给 tifffile.imsave。 IJMetadata 包含二进制格式的应用程序内部元数据。颜色信息在 luts
元数据中:
import struct
import numpy
import tifffile
def imagej_metadata_tags(metadata, byteorder):
"""Return IJMetadata and IJMetadataByteCounts tags from metadata dict.
The tags can be passed to the TiffWriter.save function as extratags.
"""
header = [{'>': b'IJIJ', '<': b'JIJI'}[byteorder]]
bytecounts = [0]
body = []
def writestring(data, byteorder):
return data.encode('utf-16' + {'>': 'be', '<': 'le'}[byteorder])
def writedoubles(data, byteorder):
return struct.pack(byteorder+('d' * len(data)), *data)
def writebytes(data, byteorder):
return data.tobytes()
metadata_types = (
('Info', b'info', 1, writestring),
('Labels', b'labl', None, writestring),
('Ranges', b'rang', 1, writedoubles),
('LUTs', b'luts', None, writebytes),
('Plot', b'plot', 1, writebytes),
('ROI', b'roi ', 1, writebytes),
('Overlays', b'over', None, writebytes))
for key, mtype, count, func in metadata_types:
if key not in metadata:
continue
if byteorder == '<':
mtype = mtype[::-1]
values = metadata[key]
if count is None:
count = len(values)
else:
values = [values]
header.append(mtype + struct.pack(byteorder+'I', count))
for value in values:
data = func(value, byteorder)
body.append(data)
bytecounts.append(len(data))
body = b''.join(body)
header = b''.join(header)
data = header + body
bytecounts[0] = len(header)
bytecounts = struct.pack(byteorder+('I' * len(bytecounts)), *bytecounts)
return ((50839, 'B', len(data), data, True),
(50838, 'I', len(bytecounts)//4, bytecounts, True))
filename = 'FluorescentCells.tif'
image = tifffile.imread(filename)
grays = numpy.tile(numpy.arange(256, dtype='uint8'), (3, 1))
red = numpy.zeros((3, 256), dtype='uint8')
red[0] = numpy.arange(256, dtype='uint8')
green = numpy.zeros((3, 256), dtype='uint8')
green[1] = numpy.arange(256, dtype='uint8')
ijtags = imagej_metadata_tags({'LUTs': [grays, green, red]}, '>')
tifffile.imsave('test_ijmetadata.tif', image, byteorder='>', imagej=True,
metadata={'mode': 'composite'}, extratags=ijtags)
您可以将多个关键字参数传递给 tifffile 的 imsave 函数。
它没有很好的记录,所以我发现最有帮助的是阅读 TiffWriter class:
中 save 函数的文档字符串
https://github.com/blink1073/tifffile/blob/master/tifffile/tifffile.py#L750
对于 ImageJ 元数据规范,TiffWriter.save 然后引用 imagej_metadata_tags,您可以在其中查看哪些类型您可以存储在变量 metadata_types 中的数据(第 7749 行):
https://github.com/blink1073/tifffile/blob/master/tifffile/tifffile.py#L7710
metadata_types = (
('Info', b'info', 1, _string),
('Labels', b'labl', None, _string),
('Ranges', b'rang', 1, _doubles),
('LUTs', b'luts', None, _ndarray),
('Plot', b'plot', 1, _bytes),
('ROI', b'roi ', 1, _bytes),
('Overlays', b'over', None, _bytes))
您可以创建 LUT 以使用不同的颜色图可视化您的数据。
假设您的数据是 uint8,那么您需要的 LUT 的形状为 (3, 256)
对于 3 个颜色通道和 256 个强度值。因此,对于灰色、绿色和红色 LUT,您需要遵循以下原则:
import numpy as np
import tifffile
# Create a random test image
im_3frame = np.random.randint(0, 255, size=(3, 150, 250), dtype=np.uint8)
# Intensity value range
val_range = np.arange(256, dtype=np.uint8)
# Gray LUT
lut_gray = np.stack([val_range, val_range, val_range])
# Red LUT
lut_red = np.zeros((3, 256), dtype=np.uint8)
lut_red[0, :] = val_range
# Green LUT
lut_green = np.zeros((3, 256), dtype=np.uint8)
lut_green[1, :] = val_range
# Create ijmetadata kwarg
ijmeta = {'LUTs': [lut_gray, lut_red, lut_green]}
# Save image
tifffile.imsave(
save_name,
im_rgb,
imagej=True,
metadata={'mode': 'composite'},
ijmetadata=ijmeta,
)
我最近在寻找一种解决方案来保存带有 ImageJ 元数据的 tiff 文件时遇到了这个线程,除了灰色通道之外还有 3 个以上的颜色通道。上述解决方案非常有用,我将示例扩展到其他频道。
在 ImageJ 中,基于 RGB 配色方案,可以在复合模式下使用多达 7 个不同的颜色通道 - 红色、绿色和蓝色三种原色,两种原色的混合产生黄色、品红色和青色作为灰色通道。
要添加蓝色 LUT,您只需如上例所示为红色或绿色 LUT 定义一个 ndarray,但将 0 到 255 范围内的强度值分配给第三个数组,而其他两个数组(红色和绿色)用零填充。
lut_blue = np.zeros((3, 256), dtype=np.uint8)
lut_blue[2, :] = val_range
通过 'mixing' 例如原色红色和绿色现在可以生成黄色 LUT。
lut_yellow= np.zeros((3, 256), dtype='uint8')
lut_yellow[[0,1],:] = np.arange(256, dtype='uint8')
下面给出的示例将生成一个包含 7 个通道的 tiff 文件。 tiff 堆栈中图像的颜色分配定义为:
ijmeta = {'LUTs': [lut_gray, lut_red, lut_green, lut_blue, lut_yellow, lut_magenta, lut_cyan]}
并且可以根据需要进行调整。基于 Jenny Folkesson 示例的完整代码如下所示:
import numpy as np
from tifffile import imread, imsave
# Create a random test image
im_3frame = np.random.randint(0, 255, size=(7, 150, 250), dtype=np.uint8)
# Intensity value range
val_range = np.arange(256, dtype=np.uint8)
# Gray LUT
lut_gray = np.stack([val_range, val_range, val_range])
# Red LUT
lut_red = np.zeros((3, 256), dtype=np.uint8)
lut_red[0, :] = val_range
# Green LUT
lut_green = np.zeros((3, 256), dtype=np.uint8)
lut_green[1, :] = val_range
# Blue LUT
lut_blue = np.zeros((3, 256), dtype=np.uint8)
lut_blue[2, :] = val_range
# Yellow LUT
lut_yellow= np.zeros((3, 256), dtype='uint8')
lut_yellow[[0,1],:] = np.arange(256, dtype='uint8')
# Magenta LUT
lut_magenta= np.zeros((3, 256), dtype='uint8')
lut_magenta[[0,2],:] = np.arange(256, dtype='uint8')
# Cyan LUT
lut_cyan= np.zeros((3, 256), dtype='uint8')
lut_cyan[[1,2],:] = np.arange(256, dtype='uint8')
# Create ijmetadata kwarg
ijmeta = {'LUTs': [lut_gray, lut_red, lut_green, lut_blue, lut_yellow, lut_magenta, lut_cyan]}
# Save image
imsave(
'test.tif',
im_3frame,
imagej=True,
metadata={'mode': 'composite'},
ijmetadata=ijmeta,
)
我在 python 中使用 tifffile
来保存 3 通道 tiff 堆栈,然后我想将其读入 ImageJ 或 FIJI。这些 tiff 堆栈在 ImageJ 中作为复合材料打开,每个通道都分配了一个(可能是默认值)colormap/LUT。但是,分配的颜色并不是对我的图像有意义的颜色。 我的问题是在使用 tifffile
.
例如,我想要分配以下颜色图:
- 通道 0:灰色
- 通道 1:绿色
- 通道 2:红色
这是我用来保存文件的代码:
# save hyperstack
with tifffile.TiffWriter(filename, bigtiff=False, imagej=True) as tif:
for i in range(t_stack.shape[0]):
tif.save(t_stack[i], metadata={'Composite mode': 'composite'})
必须有元数据与保存通道颜色映射信息的 tiff 一起保存,因为我可以在 ImageJ 中手动编辑颜色分配,然后保存、关闭它,然后当我再次打开文件时,它会保留我的手动颜色图分配。所以我猜一定有一个元数据标签(也许是颜色图?)可以用来指定通道颜色,但我找不到任何关于使用什么标签或语法的信息。
自己创建私有 IJMetadata
(50839) 和 IJMetadataByteCounts
(50838) TIFF 标签,并将它们作为额外标签传递给 tifffile.imsave。 IJMetadata 包含二进制格式的应用程序内部元数据。颜色信息在 luts
元数据中:
import struct
import numpy
import tifffile
def imagej_metadata_tags(metadata, byteorder):
"""Return IJMetadata and IJMetadataByteCounts tags from metadata dict.
The tags can be passed to the TiffWriter.save function as extratags.
"""
header = [{'>': b'IJIJ', '<': b'JIJI'}[byteorder]]
bytecounts = [0]
body = []
def writestring(data, byteorder):
return data.encode('utf-16' + {'>': 'be', '<': 'le'}[byteorder])
def writedoubles(data, byteorder):
return struct.pack(byteorder+('d' * len(data)), *data)
def writebytes(data, byteorder):
return data.tobytes()
metadata_types = (
('Info', b'info', 1, writestring),
('Labels', b'labl', None, writestring),
('Ranges', b'rang', 1, writedoubles),
('LUTs', b'luts', None, writebytes),
('Plot', b'plot', 1, writebytes),
('ROI', b'roi ', 1, writebytes),
('Overlays', b'over', None, writebytes))
for key, mtype, count, func in metadata_types:
if key not in metadata:
continue
if byteorder == '<':
mtype = mtype[::-1]
values = metadata[key]
if count is None:
count = len(values)
else:
values = [values]
header.append(mtype + struct.pack(byteorder+'I', count))
for value in values:
data = func(value, byteorder)
body.append(data)
bytecounts.append(len(data))
body = b''.join(body)
header = b''.join(header)
data = header + body
bytecounts[0] = len(header)
bytecounts = struct.pack(byteorder+('I' * len(bytecounts)), *bytecounts)
return ((50839, 'B', len(data), data, True),
(50838, 'I', len(bytecounts)//4, bytecounts, True))
filename = 'FluorescentCells.tif'
image = tifffile.imread(filename)
grays = numpy.tile(numpy.arange(256, dtype='uint8'), (3, 1))
red = numpy.zeros((3, 256), dtype='uint8')
red[0] = numpy.arange(256, dtype='uint8')
green = numpy.zeros((3, 256), dtype='uint8')
green[1] = numpy.arange(256, dtype='uint8')
ijtags = imagej_metadata_tags({'LUTs': [grays, green, red]}, '>')
tifffile.imsave('test_ijmetadata.tif', image, byteorder='>', imagej=True,
metadata={'mode': 'composite'}, extratags=ijtags)
您可以将多个关键字参数传递给 tifffile 的 imsave 函数。 它没有很好的记录,所以我发现最有帮助的是阅读 TiffWriter class:
中 save 函数的文档字符串https://github.com/blink1073/tifffile/blob/master/tifffile/tifffile.py#L750
对于 ImageJ 元数据规范,TiffWriter.save 然后引用 imagej_metadata_tags,您可以在其中查看哪些类型您可以存储在变量 metadata_types 中的数据(第 7749 行):
https://github.com/blink1073/tifffile/blob/master/tifffile/tifffile.py#L7710
metadata_types = (
('Info', b'info', 1, _string),
('Labels', b'labl', None, _string),
('Ranges', b'rang', 1, _doubles),
('LUTs', b'luts', None, _ndarray),
('Plot', b'plot', 1, _bytes),
('ROI', b'roi ', 1, _bytes),
('Overlays', b'over', None, _bytes))
您可以创建 LUT 以使用不同的颜色图可视化您的数据。 假设您的数据是 uint8,那么您需要的 LUT 的形状为 (3, 256) 对于 3 个颜色通道和 256 个强度值。因此,对于灰色、绿色和红色 LUT,您需要遵循以下原则:
import numpy as np
import tifffile
# Create a random test image
im_3frame = np.random.randint(0, 255, size=(3, 150, 250), dtype=np.uint8)
# Intensity value range
val_range = np.arange(256, dtype=np.uint8)
# Gray LUT
lut_gray = np.stack([val_range, val_range, val_range])
# Red LUT
lut_red = np.zeros((3, 256), dtype=np.uint8)
lut_red[0, :] = val_range
# Green LUT
lut_green = np.zeros((3, 256), dtype=np.uint8)
lut_green[1, :] = val_range
# Create ijmetadata kwarg
ijmeta = {'LUTs': [lut_gray, lut_red, lut_green]}
# Save image
tifffile.imsave(
save_name,
im_rgb,
imagej=True,
metadata={'mode': 'composite'},
ijmetadata=ijmeta,
)
我最近在寻找一种解决方案来保存带有 ImageJ 元数据的 tiff 文件时遇到了这个线程,除了灰色通道之外还有 3 个以上的颜色通道。上述解决方案非常有用,我将示例扩展到其他频道。
在 ImageJ 中,基于 RGB 配色方案,可以在复合模式下使用多达 7 个不同的颜色通道 - 红色、绿色和蓝色三种原色,两种原色的混合产生黄色、品红色和青色作为灰色通道。
要添加蓝色 LUT,您只需如上例所示为红色或绿色 LUT 定义一个 ndarray,但将 0 到 255 范围内的强度值分配给第三个数组,而其他两个数组(红色和绿色)用零填充。
lut_blue = np.zeros((3, 256), dtype=np.uint8)
lut_blue[2, :] = val_range
通过 'mixing' 例如原色红色和绿色现在可以生成黄色 LUT。
lut_yellow= np.zeros((3, 256), dtype='uint8')
lut_yellow[[0,1],:] = np.arange(256, dtype='uint8')
下面给出的示例将生成一个包含 7 个通道的 tiff 文件。 tiff 堆栈中图像的颜色分配定义为:
ijmeta = {'LUTs': [lut_gray, lut_red, lut_green, lut_blue, lut_yellow, lut_magenta, lut_cyan]}
并且可以根据需要进行调整。基于 Jenny Folkesson 示例的完整代码如下所示:
import numpy as np
from tifffile import imread, imsave
# Create a random test image
im_3frame = np.random.randint(0, 255, size=(7, 150, 250), dtype=np.uint8)
# Intensity value range
val_range = np.arange(256, dtype=np.uint8)
# Gray LUT
lut_gray = np.stack([val_range, val_range, val_range])
# Red LUT
lut_red = np.zeros((3, 256), dtype=np.uint8)
lut_red[0, :] = val_range
# Green LUT
lut_green = np.zeros((3, 256), dtype=np.uint8)
lut_green[1, :] = val_range
# Blue LUT
lut_blue = np.zeros((3, 256), dtype=np.uint8)
lut_blue[2, :] = val_range
# Yellow LUT
lut_yellow= np.zeros((3, 256), dtype='uint8')
lut_yellow[[0,1],:] = np.arange(256, dtype='uint8')
# Magenta LUT
lut_magenta= np.zeros((3, 256), dtype='uint8')
lut_magenta[[0,2],:] = np.arange(256, dtype='uint8')
# Cyan LUT
lut_cyan= np.zeros((3, 256), dtype='uint8')
lut_cyan[[1,2],:] = np.arange(256, dtype='uint8')
# Create ijmetadata kwarg
ijmeta = {'LUTs': [lut_gray, lut_red, lut_green, lut_blue, lut_yellow, lut_magenta, lut_cyan]}
# Save image
imsave(
'test.tif',
im_3frame,
imagej=True,
metadata={'mode': 'composite'},
ijmetadata=ijmeta,
)