57 lines
2.5 KiB
Python
Executable file
57 lines
2.5 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
# The Picture row's check (FORGE.md 14.18): the screenshots an original and its port took at the
|
|
# same moments (compare.sh with PORT_SHOTS=N and SINGE_SHOTS=<dir>), paired by number, and how much
|
|
# of each picture differs. A pixel differs when any channel is more than TOLERANCE apart, since
|
|
# the two runs decode the same video but may round a scaled frame differently.
|
|
#
|
|
# testScripts/ports/shotDiff.py <shots dir> [<out dir>]
|
|
#
|
|
# prints one line a pair and a summary; with <out dir>, writes each pair side by side with the
|
|
# differing pixels marked in the third panel, for a person to look at.
|
|
import os
|
|
import re
|
|
import sys
|
|
|
|
import numpy
|
|
from PIL import Image
|
|
|
|
TOLERANCE = 24 # Per channel, out of 255: video rounding, not a missing prompt
|
|
MARK = (255, 0, 255)
|
|
PAIR = re.compile(r"^(original|port)-shot-((?:run\d+-)?\d+)-(\w+)\.png$")
|
|
|
|
|
|
def main():
|
|
shots = sys.argv[1] if len(sys.argv) > 1 else sys.exit("usage: shotDiff.py <shots dir> [<out dir>]")
|
|
out = sys.argv[2] if len(sys.argv) > 2 else None
|
|
found = {}
|
|
|
|
for name in os.listdir(shots):
|
|
match = PAIR.match(name)
|
|
if match:
|
|
found.setdefault((match.group(2), match.group(3)), {})[match.group(1)] = os.path.join(shots, name)
|
|
if out:
|
|
os.makedirs(out, exist_ok=True)
|
|
worst = 0.0
|
|
for (number, why), pair in sorted(found.items()):
|
|
if "original" not in pair or "port" not in pair:
|
|
print("%s %-6s only the %s took it" % (number, why, "original" if "original" in pair else "port"))
|
|
continue
|
|
a = numpy.asarray(Image.open(pair["original"]).convert("RGB"), dtype=numpy.int16)
|
|
b = numpy.asarray(Image.open(pair["port"]).convert("RGB"), dtype=numpy.int16)
|
|
if a.shape != b.shape:
|
|
print("%s %-6s sizes differ: %s and %s" % (number, why, a.shape, b.shape))
|
|
continue
|
|
differs = (numpy.abs(a - b) > TOLERANCE).any(axis=2)
|
|
percent = 100.0 * differs.mean()
|
|
worst = max(worst, percent)
|
|
print("%s %-6s %6.2f%% of the picture differs" % (number, why, percent))
|
|
if out:
|
|
marked = a.copy()
|
|
marked[differs] = MARK
|
|
side = numpy.concatenate([a, b, marked], axis=1).astype(numpy.uint8)
|
|
Image.fromarray(side).save(os.path.join(out, "%s-%s.png" % (number, why)))
|
|
print("%d pairs; the worst differs in %.2f%% of its picture" % (len(found), worst))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|