|
|
|
|
@ -1,7 +1,11 @@ |
|
|
|
|
import signal |
|
|
|
|
import threading |
|
|
|
|
import os |
|
|
|
|
import sys |
|
|
|
|
import xxhash |
|
|
|
|
import cv2 |
|
|
|
|
import numpy as np |
|
|
|
|
import time |
|
|
|
|
|
|
|
|
|
""" |
|
|
|
|
Copyright 2025 - Robert Strutts MIT License |
|
|
|
|
@ -25,6 +29,21 @@ Processing time scales with area, so 4x downscale = ~16x faster initial alignmen |
|
|
|
|
Memory usage significantly reduced |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
start = time.perf_counter() |
|
|
|
|
|
|
|
|
|
def kill_all(): |
|
|
|
|
print("KILLING PROCESS") |
|
|
|
|
os.kill(os.getpid(), signal.SIGKILL) # Force kernel-level termination |
|
|
|
|
|
|
|
|
|
def exit_handler(signum, frame): |
|
|
|
|
threading.Thread(target=kill_all).start() # Run in separate thread |
|
|
|
|
# CTRL+C will Exit NOW!!! |
|
|
|
|
signal.signal(signal.SIGINT, exit_handler) |
|
|
|
|
|
|
|
|
|
def timer(): |
|
|
|
|
end = time.perf_counter() |
|
|
|
|
print(f"Execution took {end - start:.4f} seconds") |
|
|
|
|
|
|
|
|
|
def align_with_downscaling(img1, img2, downscale_factor=4, try_common_rotations=True): |
|
|
|
|
""" |
|
|
|
|
Aligns images using a multi-scale approach with initial downscaling |
|
|
|
|
@ -383,7 +402,8 @@ if __name__ == "__main__": |
|
|
|
|
if (hash1 == hash2): |
|
|
|
|
print("xxHash found duplicates") |
|
|
|
|
print("✅ Perfect match - images are identical") |
|
|
|
|
print("No transformation needed") |
|
|
|
|
print("No transformation needed") |
|
|
|
|
timer() |
|
|
|
|
exit(1) |
|
|
|
|
else: |
|
|
|
|
print("Done hashing...") |
|
|
|
|
@ -396,10 +416,12 @@ if __name__ == "__main__": |
|
|
|
|
w2, h2 = get_image_dimensions_cv(large_img2) |
|
|
|
|
if w != w2 and w != h2: |
|
|
|
|
print("Diffent Resolutions") |
|
|
|
|
timer() |
|
|
|
|
exit(0) |
|
|
|
|
|
|
|
|
|
if h != h2 and h != w2: |
|
|
|
|
print("Diffent Resolutions") |
|
|
|
|
timer() |
|
|
|
|
exit(0) |
|
|
|
|
|
|
|
|
|
print("Done loading images...") |
|
|
|
|
@ -427,9 +449,11 @@ if __name__ == "__main__": |
|
|
|
|
|
|
|
|
|
if matrix_score == 1.0 and is_score != "scores": |
|
|
|
|
print("✅ Perfect Matrix score, should be identical") |
|
|
|
|
timer() |
|
|
|
|
exit(1) |
|
|
|
|
if matrix_score == 0.0 and is_score != "scores": |
|
|
|
|
print("❌ Significant transformation required") |
|
|
|
|
timer() |
|
|
|
|
exit(0) |
|
|
|
|
if is_score == "scores": |
|
|
|
|
score = find_duplicate_with_rotation(large_img1, aligned) |
|
|
|
|
@ -453,6 +477,7 @@ if __name__ == "__main__": |
|
|
|
|
print(f"Matrix deviation score: {matrix_score:.4f}") |
|
|
|
|
print(f"Decomposed similarity: {decomposed_score:.4f}") |
|
|
|
|
print(f"Combined similarity: {combined_score:.4f}") |
|
|
|
|
timer() |
|
|
|
|
exit(exit_code) |
|
|
|
|
|
|
|
|
|
""" |
|
|
|
|
|