mercoledì 8 ottobre 2025

Trasformazione rigida di immagine con algoritmo Kabsch

 Ho un problema...la camera di ripresa di un sistema di monitoraggio, per la quale era presupposta la staticita', si muove...come correggere a posteriore la traslazione e la rotazione?

Si tratta di una trasformazione rigida (solo rototraslazione...gli oggetti in scena non mutano la loro posizione relativa)...questo e' un esempio semplificato

Le due immagini rappresentano lo stesso foglio fotografato da sue posizioni differente. 


Si calcolano le coordinate pixel dei punti rossi nei due fogli (per la calibrazione) ...le coordinate dei punti neri saranno usate per la validazione 

L'algoritmo di Kabsch e' piuttosto intuitivo e si puo' leggere qui 

Nelle matrice A e B sono riportate le coordinate dei punti di calibrazione

La differenza finale e' stata di 2 pixel 

import numpy as np
import cv2

def create_affine_matrix_2x3(R, t, s):
    """
    Create a 2x3 affine transformation matrix for OpenCV.
    M = [s*R | t]
    """
    M = np.zeros((2, 3))
    M[:2, :2] = s * R
    M[:2, 2] = t
    return M

def kabsch_transform(A, B, with_scale=False):
    assert A.shape == B.shape
    N = A.shape[0]
    centroid_A = A.mean(axis=0)
    centroid_B = B.mean(axis=0)
    A_c = A - centroid_A
    B_c = B - centroid_B
    H = A_c.T @ B_c
    U, S, Vt = np.linalg.svd(H)
    R = Vt.T @ U.T
    # fix reflection
    if np.linalg.det(R) < 0:
        Vt[-1,:] *= -1
        R = Vt.T @ U.T
    if with_scale:
        varA = (A_c**2).sum()
        s = S.sum()/varA
    else:
        s = 1.0
    t = centroid_B - s * (R @ centroid_A)
    return R, t, s

A = np.array([[175,218],[528,123],[439,523],[218,726],[554,688]])
B = np.array([[110,263],[457,128],[410,541],[211,768],[543,692]])

print(A)
R, t, s = kabsch_transform(A, B)
print("\nRotation matrix R:")
print(R)
print("\nTranslation vector t:")
print(t)
print("\nScale s:")
print(s)
print("-----------------------------")

A1 = np.array([[218,726],[554,688]])
B1 = np.array([[211,768],[543,693]])

controllo_transformed = s * (A1 @ R.T) + t
print(controllo_transformed)
print(B1)
print("\nDifferenza:")
print(np.abs(controllo_transformed - B1).max())

image = cv2.imread("IMG_8947.jpg")
output_shape = (image.shape[1], image.shape[0])

M = create_affine_matrix_2x3(R, t, s)
transformed = cv2.warpAffine(image, M, output_shape,
                                 flags=cv2.INTER_LINEAR,
                                 borderMode=cv2.BORDER_CONSTANT,
                                 borderValue=0)
cv2.imwrite('finale.jpg',transformed)


 

Nessun commento:

Posta un commento

Algoritmo Reed Solomon

 Sto progettando una trasmissione radio di immagini ed uno dei vincoli e' che non e' garantita la perfetta qualita' della trasmi...