File size: 2,044 Bytes
489147e
ee565af
489147e
a65ad61
489147e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ee565af
489147e
 
 
 
 
 
 
 
 
 
 
 
ee565af
489147e
 
 
 
 
 
 
 
 
 
 
 
 
a65ad61
ee565af
489147e
 
ee565af
489147e
ee565af
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import numpy as np
import torch
from PIL import Image

from transformers import AutoImageProcessor, AutoModel

# Modello base (addestrato su ImageNet) -- dimensione media.
# Puoi anche provare "google/vit-base-patch16-224" (senza -in21k),
# "openai/clip-vit-base-patch32", o altri modelli vision.
MODEL_NAME = "google/vit-base-patch16-224-in21k"

processor = AutoImageProcessor.from_pretrained(MODEL_NAME)
model = AutoModel.from_pretrained(MODEL_NAME)
model.eval()  # Modalità di sola inferenza

def get_embedding(pil_image: Image.Image) -> np.ndarray:
    """
    Converte l'immagine PIL in embedding (vettore) usando il modello Vit.
    """
    # Prepara i tensori per il modello
    inputs = processor(images=pil_image, return_tensors="pt")
    with torch.no_grad():
        outputs = model(**inputs)
    
    # outputs.last_hidden_state: [batch_size, seq_len, hidden_size]
    # Usiamo il mean pooling sui token dell'immagine per ottenere un vettore unico
    embeddings = outputs.last_hidden_state.mean(dim=1).squeeze()
    return embeddings.cpu().numpy()

def compare_signatures(pil_image1: Image.Image, pil_image2: Image.Image) -> float:
    """
    Estrae gli embedding da due firme e calcola la similarità (cosine similarity).
    Maggiore il valore, più simili (1 = identiche, 0 = ortogonali, -1 = opposte).
    """
    emb1 = get_embedding(pil_image1)
    emb2 = get_embedding(pil_image2)
    
    # Calcoliamo la cos similarity
    cos_sim = np.dot(emb1, emb2) / (np.linalg.norm(emb1) * np.linalg.norm(emb2))
    return cos_sim


import gradio as gr

def gradio_compare_signatures(img1, img2):
    # Confronta le due firme e ritorna la similarità
    if img1 is None or img2 is None:
        return "Carica entrambe le firme."
    sim = compare_signatures(img1, img2)
    return f"Similarità (cosine): {sim:.4f}"

demo = gr.Interface(
    fn=gradio_compare_signatures,
    inputs=[gr.Image(type="pil"), gr.Image(type="pil")],
    outputs="text",
    title="Signature Similarity"
)

if __name__ == "__main__":
    demo.launch()