ELAI S.r.l.

La telecamera vede il pezzo: a quale distanza si trova davvero?

La telecamera vede il pezzo: a quale distanza si trova davvero? Un esempio svolto chiarisce metodo, ipotesi e limiti.

La telecamera vede il pezzo: a quale distanza si trova davvero?

Riconoscere il pezzo non significa conoscerne la distanza

Una camera riconosce il centro di un componente e restituisce un punto nell’immagine. Per guidare una presa robotica, però, servono coordinate nello spazio: dove si trova il pezzo, non soltanto dove appare. Quanto della distanza è già contenuto in quel pixel? Deriveremo un’ambiguità monoculare e il modo in cui due camere calibrate aggiungono una misura utile. Poi calcoleremo come un solo pixel di errore cambi la profondità. Tutti i risultati sono di geometria ideale eseguita, non misure su un robot.

Un pixel identifica un raggio, non un punto unico

Usiamo una camera a foro ideale. Un punto ha coordinate X e Z in metri nel piano orizzontale, con Z positivo lungo l’asse ottico; f è la focale in pixel. Misuriamo la coordinata u rispetto al centro principale già sottratto. La proiezione è u=fX/Z. Moltiplicare X e Z per lo stesso fattore positivo lascia u identico: l’immagine conserva il rapporto, non la scala metrica. Con f=800 pixel, (X, Z)=(0,2;2) e (0,4;4) producono entrambi u=80 pixel.

u = f X/Z; f (aX)/(aZ) = f X/Z, a>0

Questo non significa che qualsiasi sistema monoculare sia inutile. Un piano noto, una dimensione nota, movimento calibrato o conoscenze apprese possono aggiungere vincoli. Un modello di profondità monoculare usa regolarità e dati di addestramento; non cancella l’ambiguità della singola proiezione senza ipotesi aggiuntive. Se il pezzo può avere dimensioni sconosciute, scambiare “sembra piccolo” per “è lontano” è proprio una scelta di prior, non una misura geometrica garantita.

Due camere rendono osservabile una differenza

Poniamo una seconda camera a distanza B lungo X, con assi paralleli e stessa focale. Le immagini sono rettificate, le coordinate sono centrate e il medesimo punto è correttamente abbinato: non basta trovare due oggetti simili. Nella camera sinistra u_L=fX/Z; nella destra u_R=f(X−B)/Z. Sottraendo, X scompare e resta la disparità d=u_L−u_R=fB/Z. La baseline B fornisce la lunghezza nota che mancava alla singola vista.

d = u_L−u_R = fB/Z; Z = fB/d, d>0

Con f=800 pixel e B=0,1 m, il prodotto fB vale 80 pixel·metri. A Z=2 m la disparità è 40 pixel; a Z=10 m è 8 pixel. Nel primo esempio X=0,2 m dà u_L=80 e u_R=40: la differenza ricostruisce Z=80/40=2 m. I pixel si cancellano correttamente nell’unità della formula. Un valore negativo, zero o non valido non può essere trattato come una profondità positiva ordinaria senza verificare segni, convenzioni e validità dell’abbinamento.

Un pixel pesa molto di più quando il pezzo è lontano

Per interpretare la sensibilità, deriviamo Z rispetto a d mantenendo f e B fissi: dZ/dd=−fB/d². Una piccola perturbazione δd produce localmente δZ≈−fB δd/d². Il segno dice che aumentare la disparità riduce la profondità; il modulo dice quanto. A due metri vale 0,05 m per pixel; a dieci metri 1,25 m per pixel. Non è una deviazione standard o un intervallo di confidenza: descrive la pendenza locale della relazione geometrica.

Calcoliamo anche la perturbazione finita, senza linearizzare. Per d=40±1, Z va da 80/41≈1,951219 a 80/39≈2,051282 m. Per d=8±1, va da 80/9≈8,888889 a 80/7≈11,428571 m. Gli scarti non sono simmetrici intorno al valore nominale: invertire una quantità modifica la forma dell’incertezza. Se l’intervallo di disparità arriva a zero, la profondità non conserva un limite superiore finito in questo modello.

Z (m)d (px)Z(d+1) (m)Z(d−1) (m)
2.040.01.951222.051282
10.08.08.88888911.428571
La profondità cresce rapidamente quando la disparità si avvicina a zero. Le barre mostrano ±1 pixel, non un intervallo di confidenza. Geometria ideale, nessuna camera misurata.
La profondità cresce rapidamente quando la disparità si avvicina a zero. Le barre mostrano ±1 pixel, non un intervallo di confidenza. Geometria ideale, nessuna camera misurata.

La geometria non sostituisce la calibrazione e il confronto reale

Il tutorial OpenCV documenta la relazione stereo e mostra limiti di corrispondenza: texture scarsa, bordi e rumore. Non abbiamo eseguito StereoBM né confrontato reti di profondità. La formula presuppone un punto corretto in entrambe le immagini; un abbinamento sbagliato può produrre un numero finito ma privo del significato desiderato. Errori di focale, baseline, distorsione o sincronizzazione non sono inclusi nelle barre di ±1 pixel: quelle mantengono f e B esatti e perturbano soltanto d.

La robotica industriale e collaborativa è una direzione che EL-AI intende esplorare, non un’installazione dimostrata da questo esempio. Prima di usare una profondità per comandare una presa servono verifiche della camera, dei riferimenti camera-robot, dell’incertezza e del compito fisico. La derivazione non certifica sicurezza, precisione o successo della manipolazione. Anche la complessità della semplice inversione scalare non descrive il costo di trovare corrispondenze su un’intera immagine.

La risposta finale distingue quindi tre livelli: il pixel singolo dà una direzione, la geometria stereo calibrata può dare una distanza, la validazione fisica decide se quella distanza è abbastanza affidabile per il compito. Più lontano è il punto, più conta la precisione della disparità. Riconoscere bene il pezzo rimane utile, ma non basta a sapere dove portare la pinza.

OpenCV 4.13.0 — Stereo depth geometry.

import json,sys
from pathlib import Path
f=800.;B=.1
rows=[]
for Z in [2.,10.]:
 d=f*B/Z;rows.append(dict(Zm=Z,disparityPx=d,lowZm=f*B/(d+1),highZm=f*B/(d-1),localSensitivityMPerPx=f*B/d**2))
assert f*.2/2==f*.4/4==80
assert rows[0]['disparityPx']==40 and rows[1]['disparityPx']==8
r=dict(python=sys.version.split()[0],seed=None,scope='Ideal calibrated rectified pinhole geometry; no real camera or robot measurement',focalPx=f,baselineM=B,rows=rows,disparityGrid=list(range(2,81)),depthGrid=[f*B/d for d in range(2,81)],scaleAmbiguity=[[.2,2.,80.],[.4,4.,80.]])
Path(__file__).with_name('results.json').write_text(json.dumps(r,indent=2),encoding='utf8')

Codice, dati e istruzioni · JSON. Calcoli didattici eseguiti con Python 3.14.0; figure con Matplotlib 3.11.2. Analisi con assistenza AI, senza dichiarare peer review o revisione umana. Copertina originale ImageGen, illustrativa: non documenta persone, sedi o installazioni EL-AI. Fonti consultate il 25 ottobre 2026.