diff --git a/contrib/exif-binner/README.md b/contrib/exif-binner/README.md new file mode 100644 index 00000000..fa7958b2 --- /dev/null +++ b/contrib/exif-binner/README.md @@ -0,0 +1,26 @@ +# exif_binner.py + +Bins multispectral drone images by spectral band, using EXIF data. Also verifies that each bin is complete (i.e. contains all expected bands) and can log errors to a CSV file. Excludes RGB images by default. + +## Requirements + +- [Pillow](https://pillow.readthedocs.io/en/stable/installation.html) library for reading images and EXIF data. +- [tqdm](https://github.com/tqdm/tqdm#installation) for progress bars - can be removed + +## Usage + +``` +exif_binner.py +``` + +Optional arguments: + +- `-b`/`--bands `: Number of expected bands per capture. Default: `5` +- `-s`/`--sequential `: Use sequential capture group in filenames rather than original capture ID. Default: `True` +- `-z`/`--zero_pad `: If using sequential capture groups, zero-pad the group number to this many digits. 0 for no padding, -1 for auto padding. Default: `5` +- `-w`/`--whitespace_replace `: Replace whitespace characters with this character. Default: `-` +- `-l`/`--logfile `: Write processed image metadata to this CSV file +- `-r`/`--replace_filename `: Use this instead of using the original filename in new filenames. +- `-f`/`--force`: Do not ask for processing confirmation. +- `-g`/`--no_grouping`: Do not apply grouping, only validate and add band name. +- Show these on the command line with `-h`/`--help`. diff --git a/contrib/exif-binner/exif_binner.py b/contrib/exif-binner/exif_binner.py old mode 100644 new mode 100755 index d0fab558..276793f0 --- a/contrib/exif-binner/exif_binner.py +++ b/contrib/exif-binner/exif_binner.py @@ -1,23 +1,25 @@ #!/usr/bin/env python3 +# Originally developed by Ming Chia at the Australian Plant Phenomics Facility (Australian National University node) + +# Usage: +# exif_binner.py + # standard libraries import sys import os - - -import PIL -from PIL import Image, ExifTags import shutil -from tqdm import tqdm import re import csv - import math import argparse -parser = argparse.ArgumentParser() -# Usage: -# python exif_binner.py +# other imports +import PIL +from PIL import Image, ExifTags +from tqdm import tqdm # optional: see "swap with this for no tqdm" below + +parser = argparse.ArgumentParser() # required args parser.add_argument("file_dir", help="input folder of images") @@ -77,9 +79,8 @@ images = [] print("Indexing images ...") -# Uses tqdm() for the progress bar, if not needed swap with -# for filename in os.listdir(file_dir): +# for filename in os.listdir(file_dir): # swap with this for no tqdm for filename in tqdm(os.listdir(file_dir)): old_path = os.path.join(file_dir, filename) file_name, file_ext = os.path.splitext(filename) @@ -143,6 +144,7 @@ images = sorted(images, key=lambda img: (img["DateTime"], img["name"])) # now sort and identify valid entries if not args.no_grouping: + # for this_img in images: # swap with this for no tqdm for this_img in tqdm(images): if not this_img["valid"]: # prefiltered in last loop continue @@ -166,6 +168,7 @@ os.makedirs(output_invalid, exist_ok=True) identifier = "" # then do the actual copy +# for this_img in images: # swap with this for no tqdm for this_img in tqdm(images): old_path = os.path.join(file_dir, this_img["name"]) file_name, file_ext = os.path.splitext(this_img["name"])