简体   繁体   English

无法获得TIFF图像分辨率

[英]Cannot get tiff image resolution

I'm trying to read 16 bit .tif microscope images from https://data.broadinstitute.org/bbbc/BBBC006/ and analyze them using https://github.com/sakoho81/pyimagequalityranking/tree/master/pyimq however I got an error in the part of the code that loads the tif image. 我正在尝试从https://data.broadinstitute.org/bbbc/BBBC006/读取16位.tif显微镜图像并使用https://github.com/sakoho81/pyimagequalityranking/tree/master/pyimq对其进行分析在加载tif图像的代码部分出现错误。 It uses the PIL tiffimageplugin: https://pillow.readthedocs.io/en/3.0.0/_modules/PIL/TiffImagePlugin.html and when it tries to get the resolution tag, it gives me a keyerror Any ideas why? 它使用PIL tiffimageplugin: https ://pillow.readthedocs.io/en/3.0.0/_modules/PIL/TiffImagePlugin.html,当它尝试获取分辨率标签时,它给了我一个keyerror提示为什么? Advice? 忠告? Fixes? 修复?

Thanks! 谢谢!

import os
import numpy
import scipy.ndimage.interpolation as itp
import argparse
from PIL import Image
from PIL.TiffImagePlugin import X_RESOLUTION, Y_RESOLUTION
from matplotlib import pyplot as plt
from math import log10, ceil, floor



def get_image_from_imagej_tiff(cls, path):
    """
    A class method for opening a ImageJ tiff file. Using this method
    will enable the use of correct pixel size during analysis.
    :param path: Path to an image
    :return:     An object of the MyImage class
    """
    assert os.path.isfile(path)
    assert path.endswith(('.tif', '.tiff'))
    print(path) #my own little debug thingamajig
    image = Image.open(path)

    xresolution = image.tag.tags[X_RESOLUTION][0][0] #line that errors out
    yresolution = image.tag.tags[Y_RESOLUTION][0][0]

    #data = utils.rescale_to_min_max(numpy.array(image), 0, 255)

    if data.shape[0] == 1:
        data = data[0]

    return cls(images=data, spacing=[1.0/xresolution, 1.0/yresolution])

terminal input: 终端输入:

pyimq.main --mode=directory --mode=analyze --mode=plot --working-directory=/home/myufa/predxion/BBBC/a_1_s1 --normalize-power --result=fstd --imagej

output: 输出:

Mode option is ['directory', 'analyze', 'plot']
/home/myufa/predxion/BBBC/a_1_s1/z0_a_1_s1_w1.tif
Traceback (most recent call last):
  File "/home/myufa/.local/bin/pyimq.main", line 11, in <module>
    load_entry_point('PyImageQualityRanking==0.1', 'console_scripts', 'pyimq.main')()
  File "/home/myufa/anaconda3/lib/python3.7/site-packages/PyImageQualityRanking-0.1-py3.7.egg/pyimq/bin/main.py", line 148, in main
  File "/home/myufa/anaconda3/lib/python3.7/site-packages/PyImageQualityRanking-0.1-py3.7.egg/pyimq/myimage.py", line 81, in get_image_from_imagej_tiff
KeyError: 282

Edit: Here's what I got when I tried some suggestions/indexed the tag, which makes even less sense 编辑:这是当我尝试一些建议/将标签编入索引时得到的内容,这更没有意义了

I guess the tiff in question isn't following the normal image conventions. 我猜有问题的tiff不遵循正常的图像约定。 The [XY]Resolution tags, number 282 and 283, are mandatory or required in a whole bunch of specifications, but none the less may not be present in all applications. 整个规范中,编号为282和283的[XY]分辨率标签是强制性的或必需的,但是并非所有应用程序中都没有。 I have some TIFFs (DNG format) that wouldn't load with PIL (Pillow) at all; 我有一些TIFF(DNG格式)根本无法与PIL(枕头)一起加载; that prompted me to write a script to dump the primary tag structure: 这促使我编写了一个脚本来转储主要标签结构:

# TIFF structure program
import struct
import PIL.TiffTags

class DE:
    def __init__(self, tiff):
        self.tiff = tiff
        (self.tag, self.type, self.count, self.valueoroffset) = struct.unpack(
            tiff.byteorder+b'HHI4s', self.tiff.file.read(12))
        # TODO: support reading the value
    def getstring(self):
        offset = struct.unpack(self.tiff.byteorder+b'I', self.valueoroffset)[0]
        self.tiff.file.seek(offset)
        return self.tiff.file.read(self.count)

class IFD:
    def __init__(self, tiff):
        self.tiff = tiff
        self.offset = tiff.file.tell()
        (self.len,) = struct.unpack(self.tiff.byteorder+b'H', self.tiff.file.read(2))
    def __len__(self):
        return self.len
    def __getitem__(self, index):
        if index>=self.len or index<0:
            raise IndexError()
        self.tiff.file.seek(self.offset+2+12*index)
        return DE(self.tiff)
    def nextoffset(self):
        self.tiff.file.seek(self.offset+2+12*self.len)
        (offset,) = struct.unpack(self.tiff.byteorder+b'I', self.tiff.file.read(4))
        return (offset if offset!=0 else None)

class TIFF:
    def __init__(self, file):
        self.file = file
        header = self.file.read(8)
        self.byteorder = {b'II': b'<', b'MM': b'>'}[header[:2]]
        (magic, self.ifdoffset) = struct.unpack(self.byteorder+b'HI', header[2:])
        assert magic == 42
    def __iter__(self):
        offset = self.ifdoffset
        while offset:
            self.file.seek(offset)
            ifd = IFD(self)
            yield ifd
            offset = ifd.nextoffset()

def main():
    tifffile = open('c:/users/yann/pictures/img.tiff', 'rb')
    tiff = TIFF(tifffile)
    for ifd in tiff:
        print(f'IFD at {ifd.offset}, {ifd.len} entries')
        for entry in ifd:
            print(f' tag={entry.tag} {PIL.TiffTags.lookup(entry.tag).name}')

if __name__=='__main__':
    main()

A quicker way, since you at least have the image object, might be: 由于至少拥有image对象,因此一种更快的方法可能是:

import pprint, PIL.TiffTags
pprint.pprint(list(map(PIL.TiffTags.lookup, img.tag)))

One of these might give you a clue what the actual contents of the TIFF are. 其中之一可能为您提供了TIFF实际内容的线索。 Since PIL could load it, it probably has pixel counts but not physical resolution. 由于PIL可以加载它,因此它可能具有像素数,但没有物理分辨率。

Figured out a quick fix, writing 想出一个快速解决方案,编写

image.tag[X_RESOLUTION]

before 之前

xresolution = image.tag.tags[X_RESOLUTION][0][0]

made the info available in the tag.tags dictionary for some reason. 由于某种原因使信息在tag.tags词典中可用。 Can anyone chime in and explain why this might be? 任何人都可以鸣叫并解释为什么会这样吗? Would love to learn/make sure I didn't mess it up 很想学习/确保我没有弄乱它

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

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