I am trying to create a code which loads two images, and the use keys to align the two images manually by translating, rotating and zooming the second image relative to the first one. But this code does not even show the image. Also, it seems I cannot use the cv2 keyboard methods, therefore I an using kbhit. Also, I am unable to use pyside6 to try some other package.
However, here is the code so far, maybe it can be simply "fixed"?
import cv2
import numpy as np
import kbhit
import time
# ---------------- CONFIG ----------------
BASE_IMAGE_PATH = "Input/RIMG_20250222_074457.jpg"
OVERLAY_IMAGE_PATH = "Input/RIMG_20250308_072815.jpg"
OUTPUT_IMAGE_PATH = "overlay_aligned.png"
MOVE_STEP = 5 # pixels per key press
ROTATE_STEP = 1.0 # degrees per key press
ZOOM_STEP = 0.02 # scale per key press
# ---------------------------------------
keyboard = kbhit.KBHit()
def transform_overlay(img, tx, ty, angle, scale):
print("rendering ...")
h, w = img.shape[:2]
# Center of the image
center = (w // 2, h // 2)
# Rotation + scaling
M = cv2.getRotationMatrix2D(center, angle, scale)
# Translation
M[0, 2] += tx
M[1, 2] += ty
transformed = cv2.warpAffine(
img,
M,
(w, h),
flags=cv2.INTER_LINEAR,
borderMode=cv2.BORDER_CONSTANT,
borderValue=(0, 0, 0)
)
return transformed, M
def main():
base = cv2.imread(BASE_IMAGE_PATH)
overlay = cv2.imread(OVERLAY_IMAGE_PATH)
if base is None or overlay is None:
raise FileNotFoundError("Could not load images")
# Resize overlay to match base if needed
overlay = cv2.resize(overlay, (base.shape[1], base.shape[0]))
tx, ty = 0, 0
angle = 0.0
scale = 1.0
print("Controls:")
print("Arrow keys: move overlay")
print("A / D: rotate")
print("W / S: zoom in / out")
print("R: reset")
print("SPACE: save aligned overlay")
print("ESC: exit")
while True:
transformed, M = transform_overlay(overlay, tx, ty, angle, scale)
# Blend images for visualization
blended = cv2.addWeighted(base, 0.6, transformed, 0.4, 0)
cv2.namedWindow("Alignment Tool", cv2.WINDOW_NORMAL)
cv2.imshow("Alignment Tool", blended)
while not keyboard.kbhit():
time.sleep(0.1)
pass
if keyboard.kbhit():
key = ord(keyboard.getch())
print(key)
if key == 27: # ESC
break
elif key == ord('r'):
tx, ty, angle, scale = 0, 0, 0.0, 1.0
elif key == ord('a'):
angle -= ROTATE_STEP
elif key == ord('d'):
angle += ROTATE_STEP
elif key == ord('w'):
scale += ZOOM_STEP
elif key == ord('s'):
scale = max(0.1, scale - ZOOM_STEP)
elif key == 32: # SPACE
cv2.imwrite(OUTPUT_IMAGE_PATH, transformed)
print(f"Saved aligned overlay to {OUTPUT_IMAGE_PATH}")
# Arrow keys (OpenCV key codes)
elif key == ord('j'): # left
tx -= MOVE_STEP
elif key == ord('k'): # right
tx += MOVE_STEP
elif key == ord('i'): # up
ty -= MOVE_STEP
elif key == ord('m'): # down
ty += MOVE_STEP
cv2.destroyAllWindows()
if __name__ == "__main__":
main()