将私人 tiff 标签转换为 python 字典

Convert private tiff tag into python dict

我正在尝试读取此文件的元数据:https://drive.google.com/file/d/10ZTLRazYbgm4pYEc3M7J7bP6590ZjNtY/view?usp=sharing

保存在私有标签中(34682,参见python TiffFileError: invalid tag value offset

我尝试了 的解决方案:

import tifffile
with tifffile.TiffFile('file.tif') as tif:
    tif_tags = {}
    for tag in tif.pages[0].tags.values():
        name, value = tag.name, tag.value
        tif_tags[name] = value

然而,这会将整个有趣的元数据保存为字典键中的一个字符串 'FEI_TITAN':

In [150]: tif_tags['FEI_TITAN']                                                                                                                                                                                    
Out[150]: '<?xml version="1.0"?>\r\n<Metadata xmlns:nil="http://schemas.fei.com/Metadata/v1/2013/07" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r\n  <Core>\r\n    <Guid>9b7da5e1-be22-4c15-9ea6-3ed4300318c5</Guid>\r\n    <UserID>Supervisor</UserID>\r\n    <ApplicationSoftware>xT</ApplicationSoftware>\r\n    <ApplicationSoftwareVersion>0</ApplicationSoftwareVersion>\r\n  </Core>\r\n  <Instrument>\r\n    <ControlSoftwareVersion>20.1.0.7012</ControlSoftwareVersion>\r\n    <Manufacturer>FEI Company</Manufacturer>\r\n    <InstrumentClass>Aquilos</InstrumentClass>\r\n    <InstrumentID>9925851</InstrumentID>\r\n    <ComputerName>AS-MPC</ComputerName>\r\n  </Instrument>\r\n  <Acquisition>\r\n    <AcquisitionDatetime>2021-10-12T12:27:43</AcquisitionDatetime>\r\n    <BeamType>Ion</BeamType>\r\n    <ColumnType>Sidewinder</ColumnType>\r\n  </Acquisition>\r\n  <Optics>\r\n    <Apertures>\r\n      <Aperture>\r\n        <Number>1</Number>\r\n        <Diameter>2.5E-05</Diameter>\r\n      </Aperture>\r\n    </Apertures>\r\n    <AccelerationVoltage>30000</AccelerationVoltage>\r\n    <SpotSize>1.7E-08</SpotSize>\r\n    <BeamCurrent>3E-11</BeamCurrent>\r\n    <FullScanFieldOfView>\r\n      <X>4.8020873382767222E-05</X>\r\n      <Y>3.2013915588511481E-05</Y>\r\n    </FullScanFieldOfView>\r\n    <ScanFieldOfView>\r\n      <X>4.8020873382767222E-05</X>\r\n      <Y>3.2013915588511481E-05</Y>\r\n    </ScanFieldOfView>\r\n    <WorkingDistance>0.018943079512039922</WorkingDistance>\r\n    <BeamShift>\r\n      <X>-7.4036727128018167E-07</X>\r\n      <Y>7.8283358087907821E-07</Y>\r\n    </BeamShift>\r\n    <StigmatorRaw>\r\n      <X>0</X>\r\n      <Y>0</Y>\r\n    </StigmatorRaw>\r\n  </Optics>\r\n  <StageSettings>\r\n    <StagePosition>\r\n      <X>-0.0030654519456763526</X>\r\n      <Y>0.0027469495002475459</Y>\r\n      <Z>0.018902786052566539</Z>\r\n      <Rotation>-1.256433216129438</Rotation>\r\n      <Tilt>\r\n        <Alpha>0.27925259026082394</Alpha>\r\n        <Beta>0</Beta>\r\n      </Tilt>\r\n    </StagePosition>\r\n  </StageSettings>\r\n  <ScanSettings>\r\n    <DwellTime>5E-07</DwellTime>\r\n    <ScanSize>\r\n      <Width>1536</Width>\r\n      <Height>1024</Height>\r\n    </ScanSize>\r\n    <ScanArea>\r\n      <X>0</X>\r\n      <Y>0</Y>\r\n      <Width>1536</Width>\r\n      <Height>1024</Height>\r\n    </ScanArea>\r\n    <LineTime>0.00078449999999999993</LineTime>\r\n    <LineIntegrationCount>1</LineIntegrationCount>\r\n    <LineInterlacing>1</LineInterlacing>\r\n    <FrameTime>0.80332799999999993</FrameTime>\r\n    <ScanRotation>3.1415926535897931</ScanRotation>\r\n  </ScanSettings>\r\n  <VacuumProperties>\r\n    <SamplePressure>0.00011099999999999989</SamplePressure>\r\n    <ElectronSourcePressure>4.0754869701231304E-08</ElectronSourcePressure>\r\n    <ElectronColumnPressure>1.5793422392106776E-07</ElectronColumnPressure>\r\n  </VacuumProperties>\r\n  <Detectors>\r\n    <ScanningDetector>\r\n      <DetectorName>ETD</DetectorName>\r\n      <DetectorType>ETD</DetectorType>\r\n      <Signal>SE</Signal>\r\n      <Gain>8.5319006280647329</Gain>\r\n      <Offset>-1.6069335895422618</Offset>\r\n      <GridVoltage>600</GridVoltage>\r\n      <ContrastNormalized>61.334819889093154</ContrastNormalized>\r\n      <BrightnessNormalized>43.305104160356954</BrightnessNormalized>\r\n    </ScanningDetector>\r\n    <ScanningDetector>\r\n      <DetectorName>ICE</DetectorName>\r\n      <DetectorType>ICE</DetectorType>\r\n      <Signal>SE</Signal>\r\n      <Gain>54.199464921714458</Gain>\r\n      <Offset>0.47536486052042992</Offset>\r\n      <GridVoltage>600</GridVoltage>\r\n      <ContrastNormalized>45.384756674519814</ContrastNormalized>\r\n      <BrightnessNormalized>54.754484092327296</BrightnessNormalized>\r\n    </ScanningDetector>\r\n  </Detectors>\r\n  <GasInjectionSystems>\r\n    <Gis>\r\n      <PortName>Port1</PortName>\r\n      <NeedleState>Retracted</NeedleState>\r\n      <Gases>\r\n        <Gas>\r\n          <GasType>G1</GasType>\r\n        </Gas>\r\n      </Gases>\r\n    </Gis>\r\n    <Gis>\r\n      <PortName>Port2</PortName>\r\n      <NeedleState>Retracted</NeedleState>\r\n      <Gases>\r\n        <Gas>\r\n          <GasType>G2</GasType>\r\n        </Gas>\r\n      </Gases>\r\n    </Gis>\r\n  </GasInjectionSystems>\r\n  <BinaryResult>\r\n    <AcquisitionUnit>Pixel</AcquisitionUnit>\r\n    <CompositionType>Single</CompositionType>\r\n    <ImageSize>\r\n      <X>1536</X>\r\n      <Y>1024</Y>\r\n    </ImageSize>\r\n    <FilterType>Integrate</FilterType>\r\n    <FilterFrameCount>1</FilterFrameCount>\r\n    <PixelSize>\r\n      <X unit="m" unitPrefixPower="1">3.1263589441905743E-08</X>\r\n      <Y unit="m" unitPrefixPower="1">3.1263589441905743E-08</Y>\r\n    </PixelSize>\r\n    <IntensityScale>1</IntensityScale>\r\n    <IntensityOffset>0</IntensityOffset>\r\n    <Gamma>1</Gamma>\r\n    <AcquisitionArea>\r\n      <X>0</X>\r\n      <Y>0</Y>\r\n      <Width>1</Width>\r\n      <Height>1</Height>\r\n    </AcquisitionArea>\r\n  </BinaryResult>\r\n  <CustomSectionGroup>\r\n    <CustomSection scope="StageCollection">\r\n      <StageCollection>\r\n        <Stage>\r\n          <Type>BulkStage</Type>\r\n          <X>-3.57633333333333 mm</X>\r\n          <Y>3.30025 mm</Y>\r\n          <Z>36.2439236111111 mm</Z>\r\n          <R>288.011679475735 &#x00b0;</R>\r\n          <AT>15.9999948400413 &#x00b0;</AT>\r\n          <BT />\r\n        </Stage>\r\n      </StageCollection>\r\n    </CustomSection>\r\n    <CustomSection scope="ApplicationInfo">\r\n      <ApplicationInfo>\r\n        <AutomationCoreVersion>1.675.2</AutomationCoreVersion>\r\n        <AutomationCoreCommitId>61efd0fd6a1b26289090960a7798059b497eeb42]</AutomationCoreCommitId>\r\n        <ApplicationName />\r\n        <ApplicationVersion />\r\n        <ApplicationCommitId />\r\n      </ApplicationInfo>\r\n    </CustomSection>\r\n  </CustomSectionGroup>\r\n</Metadata>'

有没有办法将这些条目检索为单独的字典键? 我已经尝试过 Convert a String representation of a Dictionary to a dictionary?,但两者都不适合我...

有什么想法吗?

你在这里得到的字符串结果被编码为xml。您可以在这里查看如何将 xml-string 转换为 dict:How to convert an XML string to a dictionary?

使用那里的答案之一,我做了以下事情:

In [6]: from xml.etree import cElementTree as ET

In [7]: ET.XML(tif_tags["FEI_TITAN"])
Out[7]: <Element 'Metadata' at 0x7f9be8207630>

In [8]: from copy import copy
   ...: 
   ...: def dictify(r,root=True):
   ...:     if root:
   ...:         return {r.tag : dictify(r, False)}
   ...:     d=copy(r.attrib)
   ...:     if r.text:
   ...:         d["_text"]=r.text
   ...:     for x in r.findall("./*"):
   ...:         if x.tag not in d:
   ...:             d[x.tag]=[]
   ...:         d[x.tag].append(dictify(x,False))
   ...:     return d
   ...: 

In [9]: dictify(ET.XML(tif_tags["FEI_TITAN"]))
Out[9]: 
{'Metadata': {'_text': '\n  ',
  'Core': [{'_text': '\n    ',
    'Guid': [{'_text': '9b7da5e1-be22-4c15-9ea6-3ed4300318c5'}],
    'UserID': [{'_text': 'Supervisor'}],
    'ApplicationSoftware': [{'_text': 'xT'}],
    'ApplicationSoftwareVersion': [{'_text': '0'}]}],
  'Instrument': [{'_text': '\n    ',
    'ControlSoftwareVersion': [{'_text': '20.1.0.7012'}],
    'Manufacturer': [{'_text': 'FEI Company'}],
    'InstrumentClass': [{'_text': 'Aquilos'}],
    'InstrumentID': [{'_text': '9925851'}],
    'ComputerName': [{'_text': 'AS-MPC'}]}],
  'Acquisition': [{'_text': '\n    ',
    'AcquisitionDatetime': [{'_text': '2021-10-12T12:27:43'}],
    'BeamType': [{'_text': 'Ion'}],
    'ColumnType': [{'_text': 'Sidewinder'}]}],
  'Optics': [{'_text': '\n    ',
    'Apertures': [{'_text': '\n      ',
      'Aperture': [{'_text': '\n        ',
        'Number': [{'_text': '1'}],
        'Diameter': [{'_text': '2.5E-05'}]}]}],
    'AccelerationVoltage': [{'_text': '30000'}],
    'SpotSize': [{'_text': '1.7E-08'}],
    'BeamCurrent': [{'_text': '3E-11'}],
    'FullScanFieldOfView': [{'_text': '\n      ',
      'X': [{'_text': '4.8020873382767222E-05'}],
      'Y': [{'_text': '3.2013915588511481E-05'}]}],
    'ScanFieldOfView': [{'_text': '\n      ',
      'X': [{'_text': '4.8020873382767222E-05'}],
      'Y': [{'_text': '3.2013915588511481E-05'}]}],
    'WorkingDistance': [{'_text': '0.018943079512039922'}],
    'BeamShift': [{'_text': '\n      ',
      'X': [{'_text': '-7.4036727128018167E-07'}],
      'Y': [{'_text': '7.8283358087907821E-07'}]}],
    'StigmatorRaw': [{'_text': '\n      ',
      'X': [{'_text': '0'}],
      'Y': [{'_text': '0'}]}]}],
  'StageSettings': [{'_text': '\n    ',
    'StagePosition': [{'_text': '\n      ',
      'X': [{'_text': '-0.0030654519456763526'}],
      'Y': [{'_text': '0.0027469495002475459'}],
      'Z': [{'_text': '0.018902786052566539'}],
      'Rotation': [{'_text': '-1.256433216129438'}],
      'Tilt': [{'_text': '\n        ',
        'Alpha': [{'_text': '0.27925259026082394'}],
        'Beta': [{'_text': '0'}]}]}]}],
  'ScanSettings': [{'_text': '\n    ',
    'DwellTime': [{'_text': '5E-07'}],
    'ScanSize': [{'_text': '\n      ',
      'Width': [{'_text': '1536'}],
      'Height': [{'_text': '1024'}]}],
    'ScanArea': [{'_text': '\n      ',
      'X': [{'_text': '0'}],
      'Y': [{'_text': '0'}],
      'Width': [{'_text': '1536'}],
      'Height': [{'_text': '1024'}]}],
    'LineTime': [{'_text': '0.00078449999999999993'}],
    'LineIntegrationCount': [{'_text': '1'}],
    'LineInterlacing': [{'_text': '1'}],
    'FrameTime': [{'_text': '0.80332799999999993'}],
    'ScanRotation': [{'_text': '3.1415926535897931'}]}],
  'VacuumProperties': [{'_text': '\n    ',
    'SamplePressure': [{'_text': '0.00011099999999999989'}],
    'ElectronSourcePressure': [{'_text': '4.0754869701231304E-08'}],
    'ElectronColumnPressure': [{'_text': '1.5793422392106776E-07'}]}],
  'Detectors': [{'_text': '\n    ',
    'ScanningDetector': [{'_text': '\n      ',
      'DetectorName': [{'_text': 'ETD'}],
      'DetectorType': [{'_text': 'ETD'}],
      'Signal': [{'_text': 'SE'}],
      'Gain': [{'_text': '8.5319006280647329'}],
      'Offset': [{'_text': '-1.6069335895422618'}],
      'GridVoltage': [{'_text': '600'}],
      'ContrastNormalized': [{'_text': '61.334819889093154'}],
      'BrightnessNormalized': [{'_text': '43.305104160356954'}]},
     {'_text': '\n      ',
      'DetectorName': [{'_text': 'ICE'}],
      'DetectorType': [{'_text': 'ICE'}],
      'Signal': [{'_text': 'SE'}],
      'Gain': [{'_text': '54.199464921714458'}],
      'Offset': [{'_text': '0.47536486052042992'}],
      'GridVoltage': [{'_text': '600'}],
      'ContrastNormalized': [{'_text': '45.384756674519814'}],
      'BrightnessNormalized': [{'_text': '54.754484092327296'}]}]}],
  'GasInjectionSystems': [{'_text': '\n    ',
    'Gis': [{'_text': '\n      ',
      'PortName': [{'_text': 'Port1'}],
      'NeedleState': [{'_text': 'Retracted'}],
      'Gases': [{'_text': '\n        ',
        'Gas': [{'_text': '\n          ', 'GasType': [{'_text': 'G1'}]}]}]},
     {'_text': '\n      ',
      'PortName': [{'_text': 'Port2'}],
      'NeedleState': [{'_text': 'Retracted'}],
      'Gases': [{'_text': '\n        ',
        'Gas': [{'_text': '\n          ', 'GasType': [{'_text': 'G2'}]}]}]}]}],
  'BinaryResult': [{'_text': '\n    ',
    'AcquisitionUnit': [{'_text': 'Pixel'}],
    'CompositionType': [{'_text': 'Single'}],
    'ImageSize': [{'_text': '\n      ',
      'X': [{'_text': '1536'}],
      'Y': [{'_text': '1024'}]}],
    'FilterType': [{'_text': 'Integrate'}],
    'FilterFrameCount': [{'_text': '1'}],
    'PixelSize': [{'_text': '\n      ',
      'X': [{'unit': 'm',
        'unitPrefixPower': '1',
        '_text': '3.1263589441905743E-08'}],
      'Y': [{'unit': 'm',
        'unitPrefixPower': '1',
        '_text': '3.1263589441905743E-08'}]}],
    'IntensityScale': [{'_text': '1'}],
    'IntensityOffset': [{'_text': '0'}],
    'Gamma': [{'_text': '1'}],
    'AcquisitionArea': [{'_text': '\n      ',
      'X': [{'_text': '0'}],
      'Y': [{'_text': '0'}],
      'Width': [{'_text': '1'}],
      'Height': [{'_text': '1'}]}]}],
  'CustomSectionGroup': [{'_text': '\n    ',
    'CustomSection': [{'scope': 'StageCollection',
      '_text': '\n      ',
      'StageCollection': [{'_text': '\n        ',
        'Stage': [{'_text': '\n          ',
          'Type': [{'_text': 'BulkStage'}],
          'X': [{'_text': '-3.57633333333333 mm'}],
          'Y': [{'_text': '3.30025 mm'}],
          'Z': [{'_text': '36.2439236111111 mm'}],
          'R': [{'_text': '288.011679475735 °'}],
          'AT': [{'_text': '15.9999948400413 °'}],
          'BT': [{}]}]}]},
     {'scope': 'ApplicationInfo',
      '_text': '\n      ',
      'ApplicationInfo': [{'_text': '\n        ',
        'AutomationCoreVersion': [{'_text': '1.675.2'}],
        'AutomationCoreCommitId': [{'_text': '61efd0fd6a1b26289090960a7798059b497eeb42]'}],
        'ApplicationName': [{}],
        'ApplicationVersion': [{}],
        'ApplicationCommitId': [{}]}]}]}]}}