Fundamentos da Estimativa de Pose
A estimativa de pose da câmera envolve determinar a posição e orientação de um sistema de coordenadas da câmera em relação a um sistema de coordenadas do mundo, utilizando correspondências entre pontos 3D conhecidos no espaço e suas projeções 2D na imagem. O OpenCV fornece a função cv::solvePnP() para resolver este problema utilizando algoritmos PnP (Perspective-n-Point). Esta análise foca na aplicação prática com OpenCV 4.5.3.
Função cv::solvePnP()
A assinatura da função é:
bool cv::solvePnP(
InputArray pontosMundo,
InputArray pontosImagem,
InputArray matrizIntrinsica,
InputArray coefsDistorcao,
OutputArray vetorRot,
OutputArray vetorTrans,
bool utilizaAproximacaoInicial = false,
int metodo = SOLVEPNP_ITERATIVE
)
Parâmetros principais:
pontosMundo: Coordenadas 3D dos pontos de referência no sistema de coordenadas mundial. Formato N×3 ou 1×N/N×1 com 3 canais. Aceitastd::vector<cv::Point3f>oucv::Mat.pontosImagem: Coordenadas 2D das projeções correspondentes no plano da imagem. Formato N×2 ou 1×N/N×1 com 2 canais. Aceitastd::vector<cv::Point2f>oucv::Mat.matrizIntrinsica: Matriz 3×3 de parâmetros intrínsecos da câmera.coefsDistorcao: Vetor de coeficientes de distorção da lente.vetorRot: Vetor de rotação 3×1 retornado, representando a orientação.vetorTrans: Vetor de translação 3×1 retornado, representando a posição.utilizaAproximacaoInicial: Quando verdadeiro e usandoSOLVEPNP_ITERATIVE, os valores devetorRotevetorTransfornecidos são usados como inicialização.metodo: Algoritmo específico para resolver o problema PnP:SOLVEPNP_ITERATIVE: Método iterativo que minimiza o erro de reprojeção (padrão)SOLVEPNP_EPNP: Algoritmo eficiente baseado no artigo EPnPSOLVEPNP_P3P: Solução clássica do problema P3PSOLVEPNP_AP3P: Variante avançada de P3PSOLVEPNP_IPPE: Método para pontos planaresSOLVEPNP_IPPE_SQUARE: Versão especializada para marcadores quadradosSOLVEPNP_SQPNP: Algoritmo quadrado e robusto
Nota: As flags
SOLVEPNP_DLSeSOLVEPNP_UPNPforam descontinuadas no OpenCV 4.5.3, sendo automaticamente substituídas porSOLVEPNP_EPNP.
Conversão com cv::Rodrigues()
O vetorRot retornado está no formato de vetor de rotação (eixo-ângulo). Para obter uma matriz de rotação 3×3 ou ângulos de Euler, usa-se a transformação de Rodrigues:
void cv::Rodrigues(
InputArray entrada,
OutputArray saida,
OutputArray jacobiano = noArray()
)
Se entrada for um vetor de rotação 3×1, saida será a matriz de rotação 3×3, e vice-versa. O parâmetro jacobiano opcional retorna as derivadas parciais.
Inetrpretação dos Resultados
Vetor de Translação
O vetorTrans representa a translação do sistema de coordenadas do mundo em relação ao sistema da câmera. Cada componente (x, y, z) corresponde às coordenadas do origem do mundo expressas no sistema da câmera.
Considere um sistema de câmera múltipla onde a câmera secundária está posicionada à esquerda da principal. Se o vetor de trenslação da câmera secundária em relação à principal for [-120.5, 2.3, -5.8], isso significa:
- No sistema da câmera principle, a origem da câmera secundária está 120.5mm à esquerda (eixo x negativo)
- 2.3mm acima (eixo y positivo)
- 5.8mm atrás (eixo z negativo)
Esta interpretação é crucial: o vetor aponta da câmera de referência para o sistema de coordenadas alvo, expresso nas coordenadas da câmera de referência.
Matriz de Rotação
A matriz de rotação derivada de vetorRot expressa a orientação do sistema de coordenadas do mundo em relação ao sistema da câmera. Para visualizar, imagine rotacionar os eixos da câmera até que se alinhem paralelamente aos eixos do mundo.
Com um marcador planar perpendicular ao eixo óptico:
- Rotação positiva no eixo Z (anti-horário) aparece como rotação horária do marcador na imagem
- Rotação positiva no eixo X (anti-horário) corresponde ao marcador "caindo" para frente
- Rotação positiva no eixo Y (anti-horário) faz o lado esquerdo do marcador afundar em relação ao direito
Os ângulos de Euler calculados representam exatamente quanto cada eixo da câmera deve girar para se alinhar com o sistema de coordenadas do mundo.
Determinando a Posição da Câmera no Mundo
Dado que vetorRot e vetorTrans descrevem a transformação da câmera (C) para o mundo (W), podemos calcular a posição da câmera no sistema de coordenadas mundial.
Abordagem por Inversão da Transformação
A relação entre sistemas de coordenadas segue:
Alternativamente, usando a matriz de rotação completa R (3×3) e vetor de translação t:
// Transformação direta
cv::Mat pontoMundo = (cv::Mat_<double>(3,1) << 0, 0, 0);
cv::Mat pontoCamera = R * pontoMundo + t; // Resulta em t
// Transformação inversa para origem da câmera
cv::Mat pontoCameraZero = (cv::Mat_<double>(3,1) << 0, 0, 0);
cv::Mat pontoMundoCalculado = -R.t() * t; // Posição da câmera no mundo
</double></double>
Ambos os métodos convergem para o mesmo resultado: as coordenadas do centro óptico da câmera expressas no sistema de coordenadas mundial.
Notação e Convenções
Para transformações entre sistemas A e B:
R<sub>A</sub><sup>B</sup>: Rotação de A para B (B em relação a A)T<sub>A</sub><sup>B</sup>: Translação de A para B, representando a origem de A em coordenadas de B- Aplica-se sempre:
P<sub>B</sub> = R<sub>A</sub><sup>B</sup> · P<sub>A</sub> + T<sub>A</sub><sup>B</sup>
Esta convenção mantém consistência em cadeias de transformações e evita ambiguidades em aplicações de visão computacional multi-câmera.