32  Getting image metadata

In this brief notebook we explore how to get image metadata, more specifically EXIF (Exchangeable image file format) data from a file. More about the format can be found on Wikipedia and the implementation is based on this answer. So let’s use some pictures on my personal database to see what sort of information we may extract.

To follow this notebook you will need pillow==12.0.0, ExifRead==3.5.1, and folium==0.20.0. Other versions might work, but since I am not making a requirements.txt for this notebook it is better to keep track of the versions it worked with. Methods for extracting data with be explained for both PIL and exifread, folium is there to do something actually usefull with the data. So let’s import the packages:

WarningAvoid verbose warnings
import warnings
warnings.filterwarnings("ignore")
from pathlib import Path
from PIL import Image, ExifTags
import exifread
import folium
import majordome.vision as mv
import tifffile

I put some images from my trip in 2018 to play with under the folder listed below. Here we make use of Python pathlib.Path to get all images matching the extension jpg in a list. We will use a single image here but in the end you can change index of the list and check the others.

media = Path(".").resolve().parent / "media" / "samples-metadata"
assert media.exists()

file_list = list(media.glob("*.jpg"))
len(file_list)
4

Next we select one image from the list. If you want to see it you can uncomment Image.open(selected) below. I keep it commented to keep the file size of this notebook small (since the images are already in the repository).

selected = file_list[1]
# Image.open(selected)

32.3 Scientific images

WarningScientific images

Work in progress…

sem_files = [f for f in (media / "tiff").glob("*")
             if f.suffix.lower() in (".tif", ".tiff")]
len(sem_files)
24
sem_selected = sem_files[0]
with tifffile.TiffFile(sem_selected) as tif:
    for page in tif.pages:
        print(page.tags)
TiffTag 254 NewSubfileType @4202 LONG @4210 = UNDEFINED
TiffTag 256 ImageWidth @4214 SHORT @4222 = 712
TiffTag 257 ImageLength @4226 SHORT @4234 = 484
TiffTag 258 BitsPerSample @4238 SHORT @4246 = 8
TiffTag 259 Compression @4250 SHORT @4258 = NONE
TiffTag 262 PhotometricInterpretation @4262 SHORT @4270 = MINISBLACK
TiffTag 273 StripOffsets @4274 LONG[49] @4398 = (5318, 12438, 19558, 26678, 337
TiffTag 277 SamplesPerPixel @4286 SHORT @4294 = 1
TiffTag 278 RowsPerStrip @4298 LONG @4306 = 10
TiffTag 279 StripByteCounts @4310 LONG[49] @4594 = (7120, 7120, 7120, 7120, 712
TiffTag 282 XResolution @4322 RATIONAL @4790 = (89, 3)
TiffTag 283 YResolution @4334 RATIONAL @4798 = (242, 9)
TiffTag 290 GrayResponseUnit @4346 SHORT @4354 = 3
TiffTag 291 GrayResponseCurve @4358 SHORT[256] @4806 = (2000, 2000, 2000, 1984,
TiffTag 296 ResolutionUnit @4370 SHORT @4378 = CENTIMETER
TiffTag 34680 FEI_SFEG @4382 ASCII[4192] @8 = {'DatabarData': {'Definition ': 1
meta = mv.load_metadata(sem_files[5], backend="HS")
meta
WARNING | RosettaSciIO | Could not determine pixel size; resulting Signal will not be calibrated (rsciio.tiff._api:488)
  • BitsPerSample = 8
  • Compression = <COMPRESSION.NONE: 1>
  • GrayResponseCurve <tuple>
    • [0] = 2000
    • [1] = 2000
    • [10] = 1921
    • [100] = 1215
    • [101] = 1215
    • [102] = 1215
    • [103] = 1200
    • [104] = 1200
    • [105] = 1176
    • [106] = 1176
    • [107] = 1176
    • [108] = 1160
    • [109] = 1160
    • [11] = 1921
    • [110] = 1137
    • [111] = 1137
    • [112] = 1137
    • [113] = 1121
    • [114] = 1121
    • [115] = 1098
    • [116] = 1098
    • [117] = 1098
    • [118] = 1082
    • [119] = 1082
    • [12] = 1921
    • [120] = 1058
    • [121] = 1058
    • [122] = 1058
    • [123] = 1043
    • [124] = 1043
    • [125] = 1019
    • [126] = 1019
    • [127] = 1019
    • [128] = 1003
    • [129] = 1003
    • [13] = 1905
    • [130] = 980
    • [131] = 980
    • [132] = 980
    • [133] = 964
    • [134] = 964
    • [135] = 941
    • [136] = 941
    • [137] = 941
    • [138] = 925
    • [139] = 925
    • [14] = 1905
    • [140] = 901
    • [141] = 901
    • [142] = 901
    • [143] = 886
    • [144] = 886
    • [145] = 862
    • [146] = 862
    • [147] = 862
    • [148] = 847
    • [149] = 847
    • [15] = 1882
    • [150] = 823
    • [151] = 823
    • [152] = 823
    • [153] = 807
    • [154] = 807
    • [155] = 784
    • [156] = 784
    • [157] = 784
    • [158] = 768
    • [159] = 768
    • [16] = 1882
    • [160] = 745
    • [161] = 745
    • [162] = 745
    • [163] = 729
    • [164] = 729
    • [165] = 705
    • [166] = 705
    • [167] = 705
    • [168] = 690
    • [169] = 690
    • [17] = 1882
    • [170] = 666
    • [171] = 666
    • [172] = 666
    • [173] = 650
    • [174] = 650
    • [175] = 627
    • [176] = 627
    • [177] = 627
    • [178] = 611
    • [179] = 611
    • [18] = 1866
    • [180] = 588
    • [181] = 588
    • [182] = 588
    • [183] = 572
    • [184] = 572
    • [185] = 549
    • [186] = 549
    • [187] = 549
    • [188] = 533
    • [189] = 533
    • [19] = 1866
    • [190] = 509
    • [191] = 509
    • [192] = 509
    • [193] = 494
    • [194] = 494
    • [195] = 470
    • [196] = 470
    • [197] = 470
    • [198] = 454
    • [199] = 454
    • [2] = 2000
    • [20] = 1843
    • [200] = 431
    • [201] = 431
    • [202] = 431
    • [203] = 415
    • [204] = 415
    • [205] = 392
    • [206] = 392
    • [207] = 392
    • [208] = 376
    • [209] = 376
    • [21] = 1843
    • [210] = 352
    • [211] = 352
    • [212] = 352
    • [213] = 337
    • [214] = 337
    • [215] = 313
    • [216] = 313
    • [217] = 313
    • [218] = 298
    • [219] = 298
    • [22] = 1843
    • [220] = 274
    • [221] = 274
    • [222] = 274
    • [223] = 258
    • [224] = 258
    • [225] = 235
    • [226] = 235
    • [227] = 235
    • [228] = 219
    • [229] = 219
    • [23] = 1827
    • [230] = 196
    • [231] = 196
    • [232] = 196
    • [233] = 180
    • [234] = 180
    • [235] = 156
    • [236] = 156
    • [237] = 156
    • [238] = 141
    • [239] = 141
    • [24] = 1827
    • [240] = 117
    • [241] = 117
    • [242] = 117
    • [243] = 101
    • [244] = 101
    • [245] = 78
    • [246] = 78
    • [247] = 78
    • [248] = 62
    • [249] = 62
    • [25] = 1803
    • [250] = 39
    • [251] = 39
    • [252] = 39
    • [253] = 23
    • [254] = 23
    • [255] = 0
    • [26] = 1803
    • [27] = 1803
    • [28] = 1788
    • [29] = 1788
    • [3] = 1984
    • [30] = 1764
    • [31] = 1764
    • [32] = 1764
    • [33] = 1749
    • [34] = 1749
    • [35] = 1725
    • [36] = 1725
    • [37] = 1725
    • [38] = 1709
    • [39] = 1709
    • [4] = 1984
    • [40] = 1686
    • [41] = 1686
    • [42] = 1686
    • [43] = 1670
    • [44] = 1670
    • [45] = 1647
    • [46] = 1647
    • [47] = 1647
    • [48] = 1631
    • [49] = 1631
    • [5] = 1960
    • [50] = 1607
    • [51] = 1607
    • [52] = 1607
    • [53] = 1592
    • [54] = 1592
    • [55] = 1568
    • [56] = 1568
    • [57] = 1568
    • [58] = 1552
    • [59] = 1552
    • [6] = 1960
    • [60] = 1529
    • [61] = 1529
    • [62] = 1529
    • [63] = 1513
    • [64] = 1513
    • [65] = 1490
    • [66] = 1490
    • [67] = 1490
    • [68] = 1474
    • [69] = 1474
    • [7] = 1960
    • [70] = 1450
    • [71] = 1450
    • [72] = 1450
    • [73] = 1435
    • [74] = 1435
    • [75] = 1411
    • [76] = 1411
    • [77] = 1411
    • [78] = 1396
    • [79] = 1396
    • [8] = 1945
    • [80] = 1372
    • [81] = 1372
    • [82] = 1372
    • [83] = 1356
    • [84] = 1356
    • [85] = 1333
    • [86] = 1333
    • [87] = 1333
    • [88] = 1317
    • [89] = 1317
    • [9] = 1945
    • [90] = 1294
    • [91] = 1294
    • [92] = 1294
    • [93] = 1278
    • [94] = 1278
    • [95] = 1254
    • [96] = 1254
    • [97] = 1254
    • [98] = 1239
    • [99] = 1239
  • GrayResponseUnit = 3
  • ImageLength = 484
  • ImageWidth = 712
  • NewSubfileType = <FILETYPE.UNDEFINED: 0>
  • PhotometricInterpretation = <PHOTOMETRIC.MINISBLACK: 1>
  • ResolutionUnit = <RESUNIT.CENTIMETER: 3>
  • RowsPerStrip = 10
  • SamplesPerPixel = 1
  • StripByteCounts <tuple>
    • [0] = 7120
    • [1] = 7120
    • [10] = 7120
    • [11] = 7120
    • [12] = 7120
    • [13] = 7120
    • [14] = 7120
    • [15] = 7120
    • [16] = 7120
    • [17] = 7120
    • [18] = 7120
    • [19] = 7120
    • [2] = 7120
    • [20] = 7120
    • [21] = 7120
    • [22] = 7120
    • [23] = 7120
    • [24] = 7120
    • [25] = 7120
    • [26] = 7120
    • [27] = 7120
    • [28] = 7120
    • [29] = 7120
    • [3] = 7120
    • [30] = 7120
    • [31] = 7120
    • [32] = 7120
    • [33] = 7120
    • [34] = 7120
    • [35] = 7120
    • [36] = 7120
    • [37] = 7120
    • [38] = 7120
    • [39] = 7120
    • [4] = 7120
    • [40] = 7120
    • [41] = 7120
    • [42] = 7120
    • [43] = 7120
    • [44] = 7120
    • [45] = 7120
    • [46] = 7120
    • [47] = 7120
    • [48] = 2848
    • [5] = 7120
    • [6] = 7120
    • [7] = 7120
    • [8] = 7120
    • [9] = 7120
  • StripOffsets <tuple>
    • [0] = 5317
    • [1] = 12437
    • [10] = 76517
    • [11] = 83637
    • [12] = 90757
    • [13] = 97877
    • [14] = 104997
    • [15] = 112117
    • [16] = 119237
    • [17] = 126357
    • [18] = 133477
    • [19] = 140597
    • [2] = 19557
    • [20] = 147717
    • [21] = 154837
    • [22] = 161957
    • [23] = 169077
    • [24] = 176197
    • [25] = 183317
    • [26] = 190437
    • [27] = 197557
    • [28] = 204677
    • [29] = 211797
    • [3] = 26677
    • [30] = 218917
    • [31] = 226037
    • [32] = 233157
    • [33] = 240277
    • [34] = 247397
    • [35] = 254517
    • [36] = 261637
    • [37] = 268757
    • [38] = 275877
    • [39] = 282997
    • [4] = 33797
    • [40] = 290117
    • [41] = 297237
    • [42] = 304357
    • [43] = 311477
    • [44] = 318597
    • [45] = 325717
    • [46] = 332837
    • [47] = 339957
    • [48] = 347077
    • [5] = 40917
    • [6] = 48037
    • [7] = 55157
    • [8] = 62277
    • [9] = 69397
  • XResolution = (89, 3)
  • YResolution = (242, 9)
  • fei_metadata
    • DatabarData
      • Definition = 177
      • FilterMode = 136
      • ImageName = A00118.TIF
      • flAccV = 20000.0
      • flIonAccV = 0.0
      • flIonMagn = 0.0
      • flIonSpot = 0.0
      • flIonWD = 0.0
      • flMagn = 0.01860000007
      • flSpot = 4.0
      • flWD = 11.368
      • iImageType = 1
      • lDetName = 2
      • lScanSpeed = 0
      • szUserText = A112 INC8
    • ImageDevice
      • DeviceName = 3
      • RatioXY = 1.333
      • SizeY = 93.0
    • MachineData
      • MachineNumber = 6882
      • MachineType = 3
      • Magic = 19544
      • NrOfVectors = 1
      • Version = 1370
      • XLFileType = 0
    • Vector
      • BeamShiftX = 0.00437
      • BeamShiftY = -0.0002
      • FWD = 11.368
      • HighTension = 20000.0
      • Magnification = 2500.0
      • NrOfScanPresets = 5
      • ProbeCurrent = 4.0
      • ScanRotation = 0.0
      • SpecimenRotation = -9626
      • SpecimenTilt = 1538462
      • StigmatorX = 1.53454
      • StigmatorY = 1.01185
      • flStageXPosition = -2590000
      • flStageYPosition = 15664355
    • Vector.IonColumn
      • ImageType = 12305
      • IonAperPresetNo = 2
      • IonBeamShiftX = 0.0
      • IonBeamShiftY = 0.0
      • IonBright0 = 0.0
      • IonBright1 = 0.0
      • IonBright2 = 0.0
      • IonBright3 = 0.0
      • IonContr0 = 0.0
      • IonContr1 = 0.0
      • IonContr2 = 0.0
      • IonContr3 = 0.0
      • IonMagn = 500.0
      • IonScanRot = 0.0
      • IonStigX = 0.0
      • IonStigY = 0.0
      • IonWD = 100.0
      • VectMask = 4
    • Vector.Sysscan
      • Application = 0
      • Index = 0
      • LineTimeIndex0 = 3
      • LineTimeIndex1 = 3
      • LineTimeIndex2 = 5
      • LineTimeIndex3 = 6
      • LineTimeIndex4 = 3
      • LinesPerFrameIndex0 = 2
      • LinesPerFrameIndex1 = 2
      • LinesPerFrameIndex2 = 2
      • LinesPerFrameIndex3 = 3
      • LinesPerFrameIndex4 = 2
      • Mode = 7
      • PositionX = 4.49438
      • PositionY = -25.3112
      • SSFilterMode = 136
      • SSPow2Frames = 0
      • SSResolution = 177
      • SizeX = 42.55618
      • SizeY = 49.58506
      • TVFilterMode = 107
      • TVPow2Frames = 2
      • TVResolution = 177
      • TvOver4 = 1
    • Vector.Video
      • MaxNrDetectors = 8
      • MaxNrNlimChannels = 2
    • Vector.Video.Channel.0
      • Brightness = 47.8
      • Contents = 64
      • Contrast = 77.554
      • MixFactor_Det_0 = 0.0
      • MixFactor_Det_1 = 0.0
      • MixFactor_Det_2 = 100.0
      • MixFactor_Det_3 = 0.0
      • MixFactor_Det_4 = 0.0
      • MixFactor_Det_5 = 0.0
      • MixFactor_Det_6 = 0.0
      • MixFactor_Det_7 = 0.0
      • MultiBrightness = 48.69
      • MultiContrast = 8.913
      • PrevMixFactor_Det_0 = 0.0
      • PrevMixFactor_Det_1 = 0.0
      • PrevMixFactor_Det_2 = 0.0
      • PrevMixFactor_Det_3 = 0.0
      • PrevMixFactor_Det_4 = 0.0
      • PrevMixFactor_Det_5 = 0.0
      • PrevMixFactor_Det_6 = 0.0
      • PrevMixFactor_Det_7 = 0.0
      • Selection_Det_0 = 0
      • Selection_Det_1 = 0
      • Selection_Det_2 = 1
      • Selection_Det_3 = 0
      • Selection_Det_4 = 0
      • Selection_Det_5 = 0
      • Selection_Det_6 = 0
      • Selection_Det_7 = 0
    • Vector.Video.Channel.1
      • Brightness = 0.0
      • Contents = 0
      • Contrast = 30.0
      • MixFactor_Det_0 = 0.0
      • MixFactor_Det_1 = 0.0
      • MixFactor_Det_2 = 0.0
      • MixFactor_Det_3 = 0.0
      • MixFactor_Det_4 = 0.0
      • MixFactor_Det_5 = 0.0
      • MixFactor_Det_6 = 0.0
      • MixFactor_Det_7 = 0.0
      • MultiBrightness = 48.69
      • MultiContrast = 8.913
      • PrevMixFactor_Det_0 = 0.0
      • PrevMixFactor_Det_1 = 0.0
      • PrevMixFactor_Det_2 = 0.0
      • PrevMixFactor_Det_3 = 0.0
      • PrevMixFactor_Det_4 = 0.0
      • PrevMixFactor_Det_5 = 0.0
      • PrevMixFactor_Det_6 = 0.0
      • PrevMixFactor_Det_7 = 0.0
      • Selection_Det_0 = 0
      • Selection_Det_1 = 0
      • Selection_Det_2 = 0
      • Selection_Det_3 = 0
      • Selection_Det_4 = 0
      • Selection_Det_5 = 0
      • Selection_Det_6 = 0
      • Selection_Det_7 = 0
    • Vector.Video.Detectors
      • ActualSelected = 2
      • Detector_0_Brightness = 46.822
      • Detector_0_Contrast = 42.767
      • Detector_0_Extra1 = 5.0
      • Detector_0_Name = 12
      • Detector_1_Brightness = 50.0
      • Detector_1_Contrast = 0.0
      • Detector_1_Extra1 = 5.0
      • Detector_1_Name = 56
      • Detector_2_Brightness = 47.8
      • Detector_2_Contrast = 77.554
      • Detector_2_Extra1 = 300.0
      • Detector_2_Name = 16
      • Detector_3_Brightness = 50.0
      • Detector_3_Contrast = 44.0
      • Detector_3_Extra1 = 300.0
      • Detector_3_Name = 52
      • Detector_4_Brightness = 50.0
      • Detector_4_Contrast = 30.0
      • Detector_4_Extra1 = 0.0
      • Detector_4_Name = 0
      • Detector_5_Brightness = 50.0
      • Detector_5_Contrast = 30.0
      • Detector_5_Extra1 = 0.0
      • Detector_5_Name = 0
      • Detector_6_Brightness = 50.0
      • Detector_6_Contrast = 30.0
      • Detector_6_Extra1 = 0.0
      • Detector_6_Name = 0
      • Detector_7_Brightness = 50.0
      • Detector_7_Contrast = 30.0
      • Detector_7_Extra1 = 0.0
      • Detector_7_Name = 0
      • NrDetectorsConnected = 4
# 257, 256
meta['ImageLength'], meta['ImageWidth']
(484, 712)
# K / flMag = actual magnification
K = 46.5

fei = meta["fei_metadata"]
fei["DatabarData"]["flAccV"] / 1000
fei["Vector"]["HighTension"] / 1000
fei["Vector"]["Magnification"] * fei["DatabarData"]["flMagn"] / K
1.000000003763441
defs = dict(sorted(ExifTags.TAGS.items(), key=lambda p: p[1]))