Skip to content

Instantly share code, notes, and snippets.

@arstropica
Last active March 3, 2023 15:59
Show Gist options
  • Save arstropica/3d66bd1312fbf76d8e0ff8f71a31fdd5 to your computer and use it in GitHub Desktop.
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.
#!/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