Last active
March 3, 2023 15:59
-
-
Save arstropica/3d66bd1312fbf76d8e0ff8f71a31fdd5 to your computer and use it in GitHub Desktop.
Finds the 2 most similar images in an image sequence or specific image.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
""" | |
Finds the 2 most similar images in an image sequence or specific image. | |
Requires: | |
- imgcompare==2.0.1 | |
- python==3.7.10 | |
""" | |
from imgcompare import is_equal, image_diff_percent, image_diff, ImageCompareException | |
import argparse | |
import pathlib | |
import math | |
import functools | |
extensions = ['.jpg', '.png', '.tif', '.tiff'] | |
parser = argparse.ArgumentParser(description='Process some images.') | |
parser.add_argument('-i', '--input', type=str, help='Path to reference image') | |
parser.add_argument('-t', '--target', type=str, help='Path to comparison image') | |
parser.add_argument('-d', '--dir', type=str, help='Path to directory of comparison images') | |
parser.add_argument('-c', '--cycle', type=int, help='Number of frames in an animation cycle') | |
parser.add_argument('-l', '--limit', type=int, help='Maximum number of total frames to compare') | |
parser.add_argument('-m', '--minimum', type=int, help='Minimum number of total frames to compare') | |
args = parser.parse_args() | |
template = "Comparison of {} to {}: {:.1f}%" | |
if (not args.input is None and not args.target is None): | |
percentage = 100 - image_diff_percent(args.input, args.target) | |
print(template.format(args.image, args.target, percentage)) | |
elif (not args.dir is None): | |
cycle = args.cycle if not args.cycle is None else 1 | |
minimum = args.minimum if not args.minimum is None else 0 | |
files = list(filter(lambda p: p.suffix in extensions, pathlib.Path(args.dir).glob('**/*'))) | |
files.sort() | |
n = len(files) | |
limit = args.limit if not args.limit is None else 0 | |
if (not args.input is None): | |
best = (cycle - 1, 0) | |
for c in range(cycle, n): | |
percentage = 100 - image_diff_percent(args.input, str(files[c].absolute())) | |
if (percentage > best[1]): | |
best = (c, percentage) | |
print(template.format(args.input, files[best[0]], best[1])) | |
else: | |
if (n > 0): | |
ranks = math.ceil(n / cycle) | |
buckets = [None] * cycle | |
for c in range(0, cycle): | |
buckets[c] = (c, c + cycle, 0) | |
for r in range(0, ranks): | |
i = (r * cycle) + c | |
for j in range(i, n, cycle): | |
if (i != j and (limit == 0 or j - i <= limit)) and (minimum == 0 or j - i >= minimum): | |
#print(files[i + j]) | |
percentage = 100 - image_diff_percent(str(files[i].absolute()), str(files[j].absolute())) | |
if (percentage > buckets[c][2]): | |
buckets[c] = (i, j, percentage) | |
best = functools.reduce(lambda a,b : a if a[2] > b[2] else b, buckets) | |
print(template.format(files[best[0]], files[best[1]], best[2])) | |
else: | |
parser.print_help() | |
parser.exit() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment