我有一个来自共聚焦显微镜的TIFF图像文件,我可以在ImageJ中打开,但我想进入Python。
TIFF格式如下:在Z维度上有30个堆栈。每个Z层有三个来自不同荧光标记的通道。每个通道的深度为8位。图片尺寸为1024x1024。
原则上,我可以使用tifffile插件使用skimage读取文件(我计划使用它来进一步分析数据)。然而,我得到的并不完全是我所期望的。
merged = io.imread("merge.tif", plugin="tifffile")
merged.shape
# (30, 3, 3, 1024, 1024)
# (zslice, RGB?, channel?, height, width)
merged.dtype
# dtype('uint16')
最初让我困惑的是我得到了两个长度为3的轴。我认为这是因为tifffile将每个通道视为单独的RGB图像,但我可以通过子集或在单个通道上使用skimage.color.rgb2grey
来解决这个问题。更让我担心的是,该文件是以16位图像的形式导入的。我可以用skimage.img_as_ubyte
转换回来,但是之后,直方图不再匹配我在ImageJ中看到的。
我不固定使用skimage导入文件,但我想让图像进入numpy数组最终使用skimage的功能。
我在处理.tif文件时遇到过同样的问题。我建议使用bioformats python包。
import javabridge
import bioformats
javabridge.start_vm(class_path=bioformats.JARS)
path_to_data = '/path/to/data/file_name.tif'
# get XML metadata of complete file
xml_string = bioformats.get_omexml_metadata(path_to_data)
ome = bioformats.OMEXML(xml_string) # be sure everything is ascii
print ome.image_count
根据数据的不同,一个文件可以保存多个图像。每个图像都可以通过以下方式访问:
# read some metadata
iome = ome.image(0) # e.g. first image
print iome.get_Name()
print iome.get_ID()
# get pixel meta data
print iome.Pixels.get_DimensionOrder()
print iome.Pixels.get_PixelType()
print iome.Pixels.get_SizeX()
print iome.Pixels.get_SizeY()
print iome.Pixels.get_SizeZ()
print iome.Pixels.get_SizeT()
print iome.Pixels.get_SizeC()
print iome.Pixels.DimensionOrder
将图像0的原始数据加载到numpy数组中,如下所示:
reader = bioformats.ImageReader(path_to_data)
raw_data = []
for z in range(iome.Pixels.get_SizeZ()):
# returns 512 x 512 x SizeC array (SizeC = number of channels)
raw_image = reader.read(z=z, series=0, rescale=False)
raw_data.append(raw_image)
raw_data = np.array(raw_data) # 512 x 512 x SizeC x SizeZ array
希望这有助于处理。tif文件,干杯!
我不确定'hyperstack to stack'
函数是否是您想要的。hyperstack是简单的多维图像,可以是4D或5D(宽度,高度,切片,通道(例如3为RGB)和时间框架)。在ImageJ中,hyperstack中的每个维度都有一个滑块。
堆栈只是堆叠的2D图像,它们在某种程度上是相关的,你只有一个滑块,在最简单的情况下,它代表了3D数据集中的z切片。
'hyperstack to stack'
函数在超堆栈中堆叠所有维度。所以,如果你有一个超堆栈3通道,4片和5个时间框架(3个滑块),你会得到一个3x4x5 = 60
图像堆栈(一个滑块)。基本上和你上面提到的在每个通道的基础上滑动通过焦平面是一样的。您可以使用'stack to hyperstack'
的另一种方式,通过定义堆栈中的哪个切片代表哪个维度来创建超级堆栈。在我上面提到的示例文件中,只选择订单xyzct, 3通道和7个时间点。
因此,如果您的tiff文件有2个滑块,那么它似乎是一个具有高度,宽度,30个切片和3个通道的4D超堆栈。'hyperstack to stack'
会将所有维度堆叠在一起,所以你会得到3x30=90 slices
。
然而,根据skimage tiff阅读器,您的tiff文件似乎是某种5D超堆栈。宽度,高度(1024x1024), 30个z-切片,3个通道(RGB)和另一个维度,3个条目(例如时间框架)。
为了找出问题所在,我建议将维度与从skimage获得的数组的3个条目进行比较。找出其中哪个代表RGB通道,另一个是什么。例如,您可以使用pyqtgraph的图像函数:
import pyqtgraph as pg
merged = io.imread("merge.tif", plugin="tifffile")
#pg.image takes the dimensions in the following order: z-slider,x,y,RGB channel
#if merged.shape = (30, 3, 3, 1024, 1024), you have to compare the 1st and 2nd dimension
pg.image(merged[:,0,:,:,:].transpose(0, 2, 3, 1))
pg.image(merged[:,1,:,:,:].transpose(0, 2, 3, 1))
pg.image(merged[:,2,:,:,:].transpose(0, 2, 3, 1))
pg.image(merged[:,:,0,:,:].transpose(0, 2, 3, 1))
pg.image(merged[:,:,1,:,:].transpose(0, 2, 3, 1))
pg.image(merged[:,:,2,:,:].transpose(0, 2, 3, 1))