Epipolar Geometry
A geometria epipolar relaciona duas vistas de uma cena, restringindo a correspondência de cada ponto a uma linha na outra imagem. Ela é a base da profundidade estéreo e do mapeamento 3D.
Em visão computacional, a geometria epipolar descreve a relação geométrica entre duas vistas de câmara da mesma cena. Um pixel numa imagem corresponde a um raio de possíveis pontos 3D, e esse raio projeta-se na segunda imagem como uma linha, a linha epipolar, sobre a qual tem de estar a correspondência do pixel. A restrição depende apenas dos parâmetros internos das câmaras e da pose relativa, independentemente da estrutura da cena, e transforma a procura de uma correspondência de uma busca na imagem inteira para uma busca ao longo de uma linha. Isso faz da geometria epipolar a base da visão estéreo, da estrutura a partir do movimento e do SLAM visual que orienta robôs e headsets. Multiple View Geometry in Computer Vision, de Richard Hartley e Andrew Zisserman, é a referência padrão.
Epípolos, linhas epipolares e plano epipolar#
Os dois centros das câmaras e qualquer ponto da cena definem um plano, o plano epipolar. A linha que une os centros das câmaras é a linha de base e atravessa cada plano de imagem no epípolo, a imagem do centro da outra câmara, que pode estar fora do enquadramento ou no infinito. Cada plano epipolar intersecta cada imagem numa linha epipolar, também chamada epilinha; por isso, todas as linhas epipolares de uma imagem passam pelo seu epípolo. À medida que o ponto da cena desliza ao longo do raio de visão da primeira câmara, a sua projeção na segunda imagem desliza ao longo da linha epipolar.
Matrizes fundamental e essencial#
A matriz fundamental F, uma matriz 3 × 3 de posto dois, capta toda a relação em coordenadas de píxeis. Para pontos correspondentes x e x′ escritos na forma homogénea (x, y, 1), a restrição epipolar é x′ᵀ F x = 0, e o produto F x fornece os coeficientes da linha epipolar de x na segunda imagem. Quando as câmaras são calibradas através da calibração de câmaras, a matriz essencial E = K′ᵀ F K expressa a mesma restrição em coordenadas normalizadas e decompõe-se na rotação relativa R e na translação t como E = [t]ₓ R. Christopher Longuet-Higgins introduziu a matriz essencial e o algoritmo dos oito pontos em 1981, e Olivier Faugeras, Quang-Tuan Luong e Richard Hartley desenvolveram a matriz fundamental não calibrada no início da década de 1990. Como E define apenas a direção de t, duas vistas, por si só, dão a forma da cena até uma escala desconhecida, e uma linha de base ou dimensão de objeto conhecida define a escala.
Ambas as matrizes são estimadas a partir de pontos-chave correspondentes, como características SIFT, com um estimador robusto, como o RANSAC, que ajusta repetidamente a matriz a uma amostra mínima de correspondências e mantém o modelo com o qual a maioria das correspondências concorda. Este exemplo cria duas vistas de 100 pontos, substitui 20 correspondências por outras aleatórias e incorretas e estima F com a variante MAGSAC do RANSAC do OpenCV:
import cv2
import numpy as np
rng = np.random.default_rng(0)
K = np.array([[800.0, 0, 320], [0, 800.0, 240], [0, 0, 1]]) # intrinsics shared by both cameras
# 100 scene points seen by two cameras; the second sits 0.5 m to the right, turned 5 degrees
points = rng.uniform([-2, -1, 4], [2, 1, 8], (100, 3))
rvec = np.array([0.0, np.radians(5), 0.0])
tvec = -cv2.Rodrigues(rvec)[0] @ np.array([0.5, 0.0, 0.0])
x1 = cv2.projectPoints(points, np.zeros(3), np.zeros(3), K, None)[0].reshape(-1, 2) + rng.normal(0, 0.5, (100, 2))
x2 = cv2.projectPoints(points, rvec, tvec, K, None)[0].reshape(-1, 2) + rng.normal(0, 0.5, (100, 2))
x2[:20] = rng.uniform([0, 0], [640, 480], (20, 2)) # replace 20 matches with wrong ones
# Robust estimation keeps the matches that agree with a single fundamental matrix
F, inliers = cv2.findFundamentalMat(x1, x2, cv2.USAC_MAGSAC, 1.0)
kept = inliers.ravel() == 1
print(f"Kept {kept[20:].sum()} of 80 true matches and {kept[:20].sum()} of 20 wrong ones")
# Each point in image 1 defines a line a*x + b*y + c = 0 in image 2 that its match must lie on
lines = cv2.computeCorrespondEpilines(x1, 1, F).reshape(-1, 3)
dist = np.abs((lines[:, :2] * x2).sum(axis=1) + lines[:, 2])
print(f"Median distance to epipolar line: {np.median(dist[20:]):.2f} px (true), {np.median(dist[:20]):.0f} px (wrong)")
print(f"Wrong match that survived: {dist[:20][kept[:20]].round(2)} px from its line")Mantém 75 das 80 correspondências verdadeiras e rejeita 19 das 20 incorretas. As correspondências verdadeiras ficam a uma mediana de 0,43 píxeis das suas linhas epipolares, devido ao ruído de meio píxel, e as incorretas ficam a 144 píxeis. A única correspondência incorreta que sobrevive acaba por ficar a 0,61 píxeis da sua linha, pois a restrição limita uma correspondência a uma linha e apenas a aparência pode selecionar o ponto certo ao longo dela.
Uma rotação pura não tem linha de base, e um único plano ajusta-se igualmente bem a muitas matrizes fundamentais; por isso, ambos os casos são tratados com uma homografia, o mapeamento 3 × 3 entre vistas de um plano. O ORB-SLAM inicializa o seu mapa ajustando em paralelo uma homografia e uma matriz fundamental, e mantém a que explica melhor as correspondências.
Retificação, disparidade e profundidade#
A retificação transforma um par estéreo para que as suas linhas epipolares se tornem horizontais e alinhadas, colocando cada correspondência na mesma linha da imagem. Os métodos de correspondência estéreo pesquisam então cada linha, e o deslocamento entre colunas das correspondências, a disparidade d, fornece a profundidade Z = f × B / d para a distância focal f e a linha de base B, que é como os sistemas estéreo produzem mapas de estimativa de profundidade. O benchmark estéreo KITTI avalia esses métodos em cenas retificadas de condução autónoma.
Aplicações para além do estéreo#
Na reconstrução 3D, o COLMAP verifica cada par de imagens ajustando matrizes fundamentais, essenciais ou de homografia e descarta pares e correspondências sem suporte geométrico suficiente. Os pipelines de correspondência de imagens usam a mesma verificação para rejeitar correspondências falsas, e o registo de imagens utiliza a ramificação da homografia acima quando a cena é plana ou a câmara apenas roda, como na criação de panoramas. Entre dois fotogramas de uma câmara em movimento, a restrição epipolar só se aplica a superfícies estáticas; por isso, os vetores de fluxo ótico que a violam revelam objetos em movimento independente. A captura multicâmara da pose humana associa a mesma pessoa entre vistas com base na proximidade das suas articulações às linhas epipolares umas das outras, antes de triangular um esqueleto 3D; um modelo de estimativa de pose Ultralytics YOLO26 fornece 17 pontos-chave corporais COCO por pessoa em cada vista.










