import warnings
warnings.filterwarnings("ignore")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:
from pathlib import Path
from PIL import Image, ExifTags
import exifread
import folium
import majordome.vision as mv
import tifffileI 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.1 Using PIL.Image (not recommended)
Using the well-known PIL.Image is not the recommended way and we choose to present it first so that we can explore further the recommended way. The image object has a method getexif (commented line) that provides (i) little data and in (ii) a nonsense format. Using the private method (you should not to do so) _getexif gets more data, but good luck making any proper use of it…
# XXX: public method, but provides little data:
# exif_data = Image.open(selected).getexif().items()
data = Image.open(selected)._getexif().items()
data = {k: v for k, v in data if k != 37500}
data{34853: {0: b'\x02\x02\x00\x00',
1: 'N',
2: (45.0, 20.0, 53.0),
3: 'E',
4: (14.0, 3.0, 4.0),
5: b'\x00',
6: 397.0,
7: (12.0, 5.0, 34.0),
29: '2018:05:22'},
296: 2,
34665: 214,
271: 'samsung',
272: 'SM-G955F',
305: 'G955FXXU1CRD7',
274: 6,
306: '2018:05:22 14:05:36',
531: 1,
282: 72.0,
283: 72.0,
36864: b'0220',
37121: b'\x01\x02\x03\x00',
37377: 9.78,
36867: '2018:05:22 14:05:36',
36868: '2018:05:22 14:05:36',
37378: 1.53,
37379: 7.61,
37380: 0.0,
37381: 1.53,
37383: 5,
37385: 0,
37386: 4.2,
37510: b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
40961: 1,
40962: 4032,
41990: 0,
37520: '0546',
37521: '0546',
37522: '0546',
40963: 3024,
33434: 0.001141552511415525,
40965: 852,
33437: 1.7,
42016: 'F12LLJA00VM F12LLKL01GM\n',
34850: 2,
34855: 40,
41986: 0,
40960: b'0100',
41987: 0,
41989: 26}
Currently PIL.ExifTags has an attribute TAGS for helping with the names. Nonetheless, it only maps a set of standard tags and not all the ones you may find in an image. The following snippet extends the above and illustrates how to use it:
data = Image.open(selected)._getexif().items()
data = {ExifTags.TAGS.get(k, k): v for k, v in data if k != 37500}
data{'GPSInfo': {0: b'\x02\x02\x00\x00',
1: 'N',
2: (45.0, 20.0, 53.0),
3: 'E',
4: (14.0, 3.0, 4.0),
5: b'\x00',
6: 397.0,
7: (12.0, 5.0, 34.0),
29: '2018:05:22'},
'ResolutionUnit': 2,
'ExifOffset': 214,
'Make': 'samsung',
'Model': 'SM-G955F',
'Software': 'G955FXXU1CRD7',
'Orientation': 6,
'DateTime': '2018:05:22 14:05:36',
'YCbCrPositioning': 1,
'XResolution': 72.0,
'YResolution': 72.0,
'ExifVersion': b'0220',
'ComponentsConfiguration': b'\x01\x02\x03\x00',
'ShutterSpeedValue': 9.78,
'DateTimeOriginal': '2018:05:22 14:05:36',
'DateTimeDigitized': '2018:05:22 14:05:36',
'ApertureValue': 1.53,
'BrightnessValue': 7.61,
'ExposureBiasValue': 0.0,
'MaxApertureValue': 1.53,
'MeteringMode': 5,
'Flash': 0,
'FocalLength': 4.2,
'UserComment': b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
'ColorSpace': 1,
'ExifImageWidth': 4032,
'SceneCaptureType': 0,
'SubsecTime': '0546',
'SubsecTimeOriginal': '0546',
'SubsecTimeDigitized': '0546',
'ExifImageHeight': 3024,
'ExposureTime': 0.001141552511415525,
'ExifInteroperabilityOffset': 852,
'FNumber': 1.7,
'ImageUniqueID': 'F12LLJA00VM F12LLKL01GM\n',
'ExposureProgram': 2,
'ISOSpeedRatings': 40,
'ExposureMode': 0,
'FlashPixVersion': b'0100',
'WhiteBalance': 0,
'FocalLengthIn35mmFilm': 26}
Notice in above the presence of tag 'GPSInfo', which contains GPS data. We can again use ExifTags to get more meaningful names for the GPS tags as follows:
data_gps = data["GPSInfo"]
gps_info = {ExifTags.GPSTAGS.get(k, k): v for k, v in data_gps.items()}
gps_info{'GPSVersionID': b'\x02\x02\x00\x00',
'GPSLatitudeRef': 'N',
'GPSLatitude': (45.0, 20.0, 53.0),
'GPSLongitudeRef': 'E',
'GPSLongitude': (14.0, 3.0, 4.0),
'GPSAltitudeRef': b'\x00',
'GPSAltitude': 397.0,
'GPSTimeStamp': (12.0, 5.0, 34.0),
'GPSDateStamp': '2018:05:22'}
Theses ideas are implemented in majordome.vision.load_metadata so that you don’t have to deal with the low-level details. Here is how to use it:
data = mv.load_metadata(selected, backend="PIL")
del data["MakerNote"] # too long
data{'GPSInfo': {'GPSVersionID': b'\x02\x02\x00\x00',
'GPSLatitudeRef': 'N',
'GPSLatitude': (45.0, 20.0, 53.0),
'GPSLongitudeRef': 'E',
'GPSLongitude': (14.0, 3.0, 4.0),
'GPSAltitudeRef': b'\x00',
'GPSAltitude': 397.0,
'GPSTimeStamp': (12.0, 5.0, 34.0),
'GPSDateStamp': '2018:05:22'},
'ResolutionUnit': 2,
'ExifOffset': 214,
'Make': 'samsung',
'Model': 'SM-G955F',
'Software': 'G955FXXU1CRD7',
'Orientation': 6,
'DateTime': '2018:05:22 14:05:36',
'YCbCrPositioning': 1,
'XResolution': 72.0,
'YResolution': 72.0,
'ExifVersion': b'0220',
'ComponentsConfiguration': b'\x01\x02\x03\x00',
'ShutterSpeedValue': 9.78,
'DateTimeOriginal': '2018:05:22 14:05:36',
'DateTimeDigitized': '2018:05:22 14:05:36',
'ApertureValue': 1.53,
'BrightnessValue': 7.61,
'ExposureBiasValue': 0.0,
'MaxApertureValue': 1.53,
'MeteringMode': 5,
'Flash': 0,
'FocalLength': 4.2,
'UserComment': b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
'ColorSpace': 1,
'ExifImageWidth': 4032,
'SceneCaptureType': 0,
'SubsecTime': '0546',
'SubsecTimeOriginal': '0546',
'SubsecTimeDigitized': '0546',
'ExifImageHeight': 3024,
'ExposureTime': 0.001141552511415525,
'ExifInteroperabilityOffset': 852,
'FNumber': 1.7,
'ImageUniqueID': 'F12LLJA00VM F12LLKL01GM\n',
'ExposureProgram': 2,
'ISOSpeedRatings': 40,
'ExposureMode': 0,
'FlashPixVersion': b'0100',
'WhiteBalance': 0,
'FocalLengthIn35mmFilm': 26}
32.2 Using exifread (recommended)
This small and embedable package exifread provides what it takes to get EXIF data from an image in a well formated dictionary. The following snippet illustrates how to do so:
with open(selected, "rb") as reader:
exif_data = exifread.process_file(reader).items()
exif_data = {k:v for k, v in exif_data if k != "JPEGThumbnail"}
exif_data{'Image Make': (0x010F) ASCII=samsung @ 162,
'Image Model': (0x0110) ASCII=SM-G955F @ 170,
'Image Orientation': (0x0112) Short=Rotated 90 CW @ 42,
'Image XResolution': (0x011A) Ratio=72 @ 146,
'Image YResolution': (0x011B) Ratio=72 @ 154,
'Image ResolutionUnit': (0x0128) Short=Pixels/Inch @ 78,
'Image Software': (0x0131) ASCII=G955FXXU1CRD7 @ 180,
'Image DateTime': (0x0132) ASCII=2018:05:22 14:05:36 @ 194,
'Image YCbCrPositioning': (0x0213) Short=Centered @ 114,
'Image ExifOffset': (0x8769) Long=214 @ 126,
'GPS GPSVersionID': (0x0000) Byte=[2, 2, 0, 0] @ 892,
'GPS GPSLatitudeRef': (0x0001) ASCII=N @ 904,
'GPS GPSLatitude': (0x0002) Ratio=[45, 20, 53] @ 996,
'GPS GPSLongitudeRef': (0x0003) ASCII=E @ 928,
'GPS GPSLongitude': (0x0004) Ratio=[14, 3, 4] @ 1020,
'GPS GPSAltitudeRef': (0x0005) Byte=0 @ 952,
'GPS GPSAltitude': (0x0006) Ratio=397 @ 1044,
'GPS GPSTimeStamp': (0x0007) Ratio=[12, 5, 34] @ 1064,
'GPS GPSDate': (0x001D) ASCII=2018:05:22 @ 1052,
'Image GPSInfo': (0x8825) Long=882 @ 138,
'Thumbnail ImageWidth': (0x0100) Long=504 @ 1098,
'Thumbnail ImageLength': (0x0101) Long=376 @ 1110,
'Thumbnail Compression': (0x0103) Short=JPEG (old-style) @ 1122,
'Thumbnail Orientation': (0x0112) Short=Rotated 90 CW @ 1134,
'Thumbnail XResolution': (0x011A) Ratio=72 @ 1202,
'Thumbnail YResolution': (0x011B) Ratio=72 @ 1210,
'Thumbnail ResolutionUnit': (0x0128) Short=Pixels/Inch @ 1170,
'Thumbnail JPEGInterchangeFormat': (0x0201) Long=1218 @ 1182,
'Thumbnail JPEGInterchangeFormatLength': (0x0202) Long=29581 @ 1194,
'EXIF ExposureTime': (0x829A) Ratio=1/876 @ 592,
'EXIF FNumber': (0x829D) Ratio=17/10 @ 600,
'EXIF ExposureProgram': (0x8822) Short=Program Normal @ 248,
'EXIF ISOSpeedRatings': (0x8827) Short=40 @ 260,
'EXIF ExifVersion': (0x9000) Undefined=0220 @ 272,
'EXIF DateTimeOriginal': (0x9003) ASCII=2018:05:22 14:05:36 @ 608,
'EXIF DateTimeDigitized': (0x9004) ASCII=2018:05:22 14:05:36 @ 628,
'EXIF ComponentsConfiguration': (0x9101) Undefined=YCbCr @ 308,
'EXIF ShutterSpeedValue': (0x9201) Signed Ratio=489/50 @ 648,
'EXIF ApertureValue': (0x9202) Ratio=153/100 @ 656,
'EXIF BrightnessValue': (0x9203) Signed Ratio=761/100 @ 664,
'EXIF ExposureBiasValue': (0x9204) Signed Ratio=0 @ 672,
'EXIF MaxApertureValue': (0x9205) Ratio=153/100 @ 680,
'EXIF MeteringMode': (0x9207) Short=Pattern @ 380,
'EXIF Flash': (0x9209) Short=Flash did not fire @ 392,
'EXIF FocalLength': (0x920A) Ratio=21/5 @ 688,
'EXIF MakerNote': (0x927C) Undefined=[7, 0, 1, 0, 7, 0, 4, 0, 0, 0, 48, 49, 48, 48, 2, 0, 4, 0, 1, 0, ... ] @ 754,
'EXIF UserComment': (0x9286) Undefined= @ 714,
'EXIF SubSecTime': (0x9290) ASCII=0546 @ 696,
'EXIF SubSecTimeOriginal': (0x9291) ASCII=0546 @ 702,
'EXIF SubSecTimeDigitized': (0x9292) ASCII=0546 @ 708,
'EXIF FlashPixVersion': (0xA000) Undefined=0100 @ 476,
'EXIF ColorSpace': (0xA001) Short=sRGB @ 488,
'EXIF ExifImageWidth': (0xA002) Long=4032 @ 500,
'EXIF ExifImageLength': (0xA003) Long=3024 @ 512,
'Interoperability InteroperabilityIndex': (0x0001) ASCII=R98 @ 862,
'Interoperability InteroperabilityVersion': (0x0002) Undefined=[48, 49, 48, 48] @ 874,
'EXIF InteroperabilityOffset': (0xA005) Long=852 @ 524,
'EXIF ExposureMode': (0xA402) Short=Auto Exposure @ 536,
'EXIF WhiteBalance': (0xA403) Short=Auto @ 548,
'EXIF FocalLengthIn35mmFilm': (0xA405) Short=26 @ 560,
'EXIF SceneCaptureType': (0xA406) Short=Standard @ 572,
'EXIF ImageUniqueID': (0xA420) ASCII=F12LLJA00VM F12LLKL01GM
@ 728}
There is a bunch of information above, but let’s imagine here you forgot where a picture was taken. Well, if your camera or cellphone has a GPS embedded you get find out with the extracted metadata. The following function extracts the latitude and logitude from the format exported by exifread for you and provides the results in degrees.
def get_exif_location(exif_data):
""" Returns the latitude and longitude from exif data.
Based on https://gist.github.com/snakeye/fdc372dbf11370fe29eb which
by its way is based on https://gist.github.com/erans/983821.
"""
def to_degress(value):
""" Convert the GPS coordinates stored in the EXIF to degrees. """
d = float(value.values[0].num) / float(value.values[0].den)
m = float(value.values[1].num) / float(value.values[1].den)
s = float(value.values[2].num) / float(value.values[2].den)
return d + m / 60 + s / 3600
lat, lon = None, None
gps_lat_val = exif_data.get("GPS GPSLatitude", None)
gps_lat_ref = exif_data.get("GPS GPSLatitudeRef", None)
gps_lon_val = exif_data.get("GPS GPSLongitude", None)
gps_lon_ref = exif_data.get("GPS GPSLongitudeRef", None)
if gps_lat_val and gps_lat_ref and gps_lon_val and gps_lon_ref:
lat = to_degress(gps_lat_val)
lon = to_degress(gps_lon_val)
lat = -lat if gps_lat_ref.values[0] != "N" else lat
lon = -lon if gps_lon_ref.values[0] != "E" else lon
return lat, lonSo here we go, we get the coordinates from the image and with help of folium we check on the map where it was taken.
coordinates = get_exif_location(exif_data)
m = folium.Map(location=coordinates)
folium.Marker(coordinates).add_to(m)
mAgain, this is implemented in majordome.vision.load_metadata:
data = mv.load_metadata(selected, backend="EXIFREAD")
del data["JPEGThumbnail"] # too long
data{'Image Make': (0x010F) ASCII=samsung @ 162,
'Image Model': (0x0110) ASCII=SM-G955F @ 170,
'Image Orientation': (0x0112) Short=Rotated 90 CW @ 42,
'Image XResolution': (0x011A) Ratio=72 @ 146,
'Image YResolution': (0x011B) Ratio=72 @ 154,
'Image ResolutionUnit': (0x0128) Short=Pixels/Inch @ 78,
'Image Software': (0x0131) ASCII=G955FXXU1CRD7 @ 180,
'Image DateTime': (0x0132) ASCII=2018:05:22 14:05:36 @ 194,
'Image YCbCrPositioning': (0x0213) Short=Centered @ 114,
'Image ExifOffset': (0x8769) Long=214 @ 126,
'GPS GPSVersionID': (0x0000) Byte=[2, 2, 0, 0] @ 892,
'GPS GPSLatitudeRef': (0x0001) ASCII=N @ 904,
'GPS GPSLatitude': (0x0002) Ratio=[45, 20, 53] @ 996,
'GPS GPSLongitudeRef': (0x0003) ASCII=E @ 928,
'GPS GPSLongitude': (0x0004) Ratio=[14, 3, 4] @ 1020,
'GPS GPSAltitudeRef': (0x0005) Byte=0 @ 952,
'GPS GPSAltitude': (0x0006) Ratio=397 @ 1044,
'GPS GPSTimeStamp': (0x0007) Ratio=[12, 5, 34] @ 1064,
'GPS GPSDate': (0x001D) ASCII=2018:05:22 @ 1052,
'Image GPSInfo': (0x8825) Long=882 @ 138,
'Thumbnail ImageWidth': (0x0100) Long=504 @ 1098,
'Thumbnail ImageLength': (0x0101) Long=376 @ 1110,
'Thumbnail Compression': (0x0103) Short=JPEG (old-style) @ 1122,
'Thumbnail Orientation': (0x0112) Short=Rotated 90 CW @ 1134,
'Thumbnail XResolution': (0x011A) Ratio=72 @ 1202,
'Thumbnail YResolution': (0x011B) Ratio=72 @ 1210,
'Thumbnail ResolutionUnit': (0x0128) Short=Pixels/Inch @ 1170,
'Thumbnail JPEGInterchangeFormat': (0x0201) Long=1218 @ 1182,
'Thumbnail JPEGInterchangeFormatLength': (0x0202) Long=29581 @ 1194,
'EXIF ExposureTime': (0x829A) Ratio=1/876 @ 592,
'EXIF FNumber': (0x829D) Ratio=17/10 @ 600,
'EXIF ExposureProgram': (0x8822) Short=Program Normal @ 248,
'EXIF ISOSpeedRatings': (0x8827) Short=40 @ 260,
'EXIF ExifVersion': (0x9000) Undefined=0220 @ 272,
'EXIF DateTimeOriginal': (0x9003) ASCII=2018:05:22 14:05:36 @ 608,
'EXIF DateTimeDigitized': (0x9004) ASCII=2018:05:22 14:05:36 @ 628,
'EXIF ComponentsConfiguration': (0x9101) Undefined=YCbCr @ 308,
'EXIF ShutterSpeedValue': (0x9201) Signed Ratio=489/50 @ 648,
'EXIF ApertureValue': (0x9202) Ratio=153/100 @ 656,
'EXIF BrightnessValue': (0x9203) Signed Ratio=761/100 @ 664,
'EXIF ExposureBiasValue': (0x9204) Signed Ratio=0 @ 672,
'EXIF MaxApertureValue': (0x9205) Ratio=153/100 @ 680,
'EXIF MeteringMode': (0x9207) Short=Pattern @ 380,
'EXIF Flash': (0x9209) Short=Flash did not fire @ 392,
'EXIF FocalLength': (0x920A) Ratio=21/5 @ 688,
'EXIF MakerNote': (0x927C) Undefined=[7, 0, 1, 0, 7, 0, 4, 0, 0, 0, 48, 49, 48, 48, 2, 0, 4, 0, 1, 0, ... ] @ 754,
'EXIF UserComment': (0x9286) Undefined= @ 714,
'EXIF SubSecTime': (0x9290) ASCII=0546 @ 696,
'EXIF SubSecTimeOriginal': (0x9291) ASCII=0546 @ 702,
'EXIF SubSecTimeDigitized': (0x9292) ASCII=0546 @ 708,
'EXIF FlashPixVersion': (0xA000) Undefined=0100 @ 476,
'EXIF ColorSpace': (0xA001) Short=sRGB @ 488,
'EXIF ExifImageWidth': (0xA002) Long=4032 @ 500,
'EXIF ExifImageLength': (0xA003) Long=3024 @ 512,
'Interoperability InteroperabilityIndex': (0x0001) ASCII=R98 @ 862,
'Interoperability InteroperabilityVersion': (0x0002) Undefined=[48, 49, 48, 48] @ 874,
'EXIF InteroperabilityOffset': (0xA005) Long=852 @ 524,
'EXIF ExposureMode': (0xA402) Short=Auto Exposure @ 536,
'EXIF WhiteBalance': (0xA403) Short=Auto @ 548,
'EXIF FocalLengthIn35mmFilm': (0xA405) Short=26 @ 560,
'EXIF SceneCaptureType': (0xA406) Short=Standard @ 572,
'EXIF ImageUniqueID': (0xA420) ASCII=F12LLJA00VM F12LLKL01GM
@ 728}
This is not forensics level but can be pretty useful. For instance, some microscopes store all the setup under which a picture was taken. If that is the case, you don’t need to keep taking all those boring notes while doing your analysis, and leave image labeling for some automated post-processing in Python.
32.3 Scientific 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")
metaWARNING | 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"] / K1.000000003763441
defs = dict(sorted(ExifTags.TAGS.items(), key=lambda p: p[1]))