简体   繁体   English

Python图像分析:从共聚焦显微镜读取多维TIFF文件

[英]Python image analysis: reading a multidimensional TIFF file from confocal microscopy

I have a TIFF image file from a confocal microscope which I can open in ImageJ, but which I would like to get into Python. 我有一个共聚焦显微镜的TIFF图像文件,可以在ImageJ中打开它,但是我想进入Python。

The format of the TIFF is as follows: There are 30 stacks in the Z dimension. TIFF的格式如下:Z方向上有30个堆栈。 Each Z layer has three channels from different fluorescent markers. 每个Z层都有来自不同荧光标记的三个通道。 Each channel has a depth of 8 bits. 每个通道的深度为8位。 The image dimensions are 1024x1024. 图像尺寸为1024x1024。

I can, in principle, read the file with skimage (which I plan to use to further analyse the data) using the tifffile plugin. 原则上,我可以使用tifffile插件读取skimage文件(我打算将其用于进一步分析数据)。 However, what I get is not quite what I expect. 但是,我得到的并不是我所期望的。

merged = io.imread("merge.tif", plugin="tifffile")
merged.shape
# (30, 3, 3, 1024, 1024)
# (zslice, RGB?, channel?, height, width)
merged.dtype
# dtype('uint16')

What confused me initially was the fact that I get two axes of length 3. I think that this is because tifffile treats each channel as separate RGB images, but I can work around this by subsetting or using skimage.color.rgb2grey on the individual channels. 最初让我感到困惑的是,我得到了两个长度为3的轴。我认为这是因为tifffile将每个通道视为单独的RGB图像,但是我可以通过在单个通道上设置子集或使用skimage.color.rgb2grey来解决此问题。 。 What concerns me more is that the file is imported as a 16 bit image. 更令我担心的是该文件是作为16位图像导入的。 I can convert it back using skimage.img_as_ubyte , but afterwards, the histogram does no longer match the one I see in ImageJ. 我可以使用skimage.img_as_ubyte将其转换回去, 但是之后,直方图不再与我在ImageJ中看到的匹配。

I am not fixated on using skimage to import the file, but I would like to get the image into a numpy array eventually to use skimage's functionality on it. 我并不确定使用skimage导入文件,但是我想将图像最终转换为numpy数组以在其上使用skimage的功能。

I've encountered the same issue working on .tif files. 我在处理.tif文件时遇到了相同的问题。 I recommend to use bioformats python package . 我建议使用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

depending on data, one file can hold multiple images. 根据数据,一个文件可以保存多张图像。 Each image can be accessed as follows: 可以按以下方式访问每个图像:

    # 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

loading raw data of image 0 into numpy array is done like that: 将图像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

Hope this helps processing .tif files, Cheers! 希望这有助于处理.tif文件,干杯!

I am not sure if the 'hyperstack to stack' function is that what you want. 我不确定'hyperstack to stack'功能是否就是您想要的。 Hyperstacks are simply multidimensional images, could be 4D or 5D (width, hight, slices, channels (eg 3 for RGB) and time frames). 超级堆栈只是多维图像,可以是4D或5D(宽度,高度,切片,通道(例如,对于RGB为3)和时间范围)。 In ImageJ you have a slider for each dimension in a hyperstack. 在ImageJ中,超级堆栈中的每个维度都有一个滑块。

Stacks are just stacked 2D images that are somehow related and you have only one slider, in the simplest case it represents the z-slices in a 3D data set. 堆栈只是以某种方式相关的堆栈2D图像,并且只有一个滑块,在最简单的情况下,它表示3D数据集中的z切片。

The 'hyperstack to stack' function stacks all dimensions in your hyperstack. 'hyperstack to stack'功能可将超级堆栈中的所有尺寸堆叠在一起。 So if you have a hyperstack with 3 channels, 4 slices and 5 time frames (3 sliders) you will get a stack of 3x4x5 = 60 images (one slider). 因此,如果您有一个具有3个通道,4个切片和5个时间帧的超堆栈(3个滑块),则将获得3x4x5 = 60张图像的堆栈(一个滑块)。 Basically the same thing as you mentioned above with sliding through the focal planes on a per-channel basis. 与上面提到的基本相同,每个通道在焦平面上滑动。 You can go the other way around using 'stack to hyperstack' and make a hyperstack by defining which slices from your stack represent which dimension. 您可以通过使用'stack to hyperstack'另一种方法,并通过定义堆栈中的哪些切片代表哪个维度'stack to hyperstack'制作超堆栈。 In the example file I mentioned above just select order xyzct, 3 channels and 7 time points. 在上面提到的示例文件中,只需选择顺序xyzct,3个通道和7个时间点。

So if your tiff file has 2 sliders, it seems that it is a 4D hyperstack with hight, width, 30 slices and 3 channels. 因此,如果您的tiff文件具有2个滑条,则它似乎是具有高,宽,30个切片和3个通道的4D超级堆栈。 'hyperstack to stack' would stack all dimensions on top of each other, so you will get 3x30=90 slices . 'hyperstack to stack'将所有尺寸堆叠在一起,因此您将获得3x30=90 slices

However, according to the skimage tiff reader it seems that your tiff file is some kind of a 5D hyperstack. 但是,根据skimage tiff阅读器,您的tiff文件似乎是某种5D超堆栈。 Width, hight (1024x1024), 30 z-slices, 3 channels (RGB) and another dimension with 3 entries (eg time frames). 宽度,高(1024x1024),30个z切片,3个通道(RGB)和具有3个条目的另一个尺寸(例如时间范围)。

In order to find out what is wrong, I would suggest to compare the dimensions with 3 entries of the array you get from skimage. 为了找出问题所在,我建议将维度与从skimage获得的数组的3个条目进行比较。 Find out which one of them represents the RGB channels and what the other one is. 找出其中一个代表RGB通道,另一个代表什么。 You can for example use pyqtgraph's image function: 例如,您可以使用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))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM