opensfm/actions/extract_metadata.py (51 lines of code) (raw):

import copy import logging from functools import partial from opensfm import exif from opensfm.dataset_base import DataSetBase logger = logging.getLogger(__name__) logging.getLogger("exifread").setLevel(logging.WARNING) def run_dataset(data: DataSetBase): """Extract metadata from images' EXIF tag.""" exif_overrides = {} if data.exif_overrides_exists(): exif_overrides = data.load_exif_overrides() camera_models = {} for image in data.images(): if data.exif_exists(image): logging.info("Loading existing EXIF for {}".format(image)) d = data.load_exif(image) else: logging.info("Extracting EXIF for {}".format(image)) d = _extract_exif(image, data) if image in exif_overrides: d.update(exif_overrides[image]) data.save_exif(image, d) if d["camera"] not in camera_models: camera = exif.camera_from_exif_metadata(d, data) camera_models[d["camera"]] = camera # Override any camera specified in the camera models overrides file. if data.camera_models_overrides_exists(): overrides = data.load_camera_models_overrides() if "all" in overrides: for key in camera_models: camera_models[key] = copy.copy(overrides["all"]) camera_models[key].id = key else: for key, value in overrides.items(): camera_models[key] = value data.save_camera_models(camera_models) def _extract_exif(image, data: DataSetBase): with data.open_image_file(image) as fp: d = exif.extract_exif_from_file( fp, partial(data.image_size, image), data.config["use_exif_size"], name=image, ) if data.config["unknown_camera_models_are_different"] and ( not d["model"] or d["model"] == "unknown" ): d["model"] = f"unknown_{image}" if data.config.get("default_projection_type"): d["projection_type"] = data.config.get("default_projection_type") d["camera"] = exif.camera_id(d) return d