Correção de distorção usando pontos 3D do Kinect

15

Com o XNA, estou exibindo um retângulo simples que é projetado no chão. O projetor pode ser colocado em uma posição arbitrária. Obviamente, o retângulo projetado fica distorcido de acordo com a posição e o ângulo do projetor. Um Kinect examina o chão procurando os quatro cantos. Agora, meu objetivo é transformar o retângulo original para que a projeção não seja mais distorcida, basicamente pré-deformando o retângulo.

Minha primeira abordagem foi fazer tudo em 2D: primeiro, calcule uma transformação de perspectiva (usando OpenCVs warpPerspective()) dos pontos digitalizados para os pontos do retângulo interno e aplique o inverso ao retângulo. Isso parecia funcionar, mas era muito lento, pois não podia ser renderizado na GPU.

A segunda abordagem foi fazer tudo em 3D para usar os recursos de renderização do XNA. Primeiro, eu exibia um avião, digitalizava seus cantos com o Kinect e mapeia os pontos 3D recebidos para o plano original. Teoricamente, eu poderia aplicar o inverso da transformação de perspectiva no plano, como fiz na abordagem 2D. No entanto, como o XNA trabalha com uma matriz de exibição e projeção, não posso simplesmente chamar uma função como warpPerspective()e obter o resultado desejado. Eu precisaria calcular os novos parâmetros para a visão e a matriz de projeção da câmera.

Pergunta: É possível calcular esses parâmetros e dividi-los em duas matrizes (visualização e projeção)? Caso contrário, existe outra abordagem que eu poderia usar?

philllies
fonte
11
O XNA usa uma matriz View e Projection, mas acho que o resultado final = vetor * visão * projeção. Por que não tentar transformar uma matriz de identidade e projeção em uma matriz de perspectiva inversa e ver se isso funciona? (Não 100% de certeza que este é exatamente o que acontece)
Roy T.
11
Como exatamente você calculou uma transformação de perspectiva warpPespective? Não estou familiarizado com o OpenCV, mas ler o documento parece que essa função apenas aplica uma perspectiva a uma imagem. Ou estou confuso? De qualquer forma, talvez adicionar mais detalhes sobre sua primeira implementação ajudaria.
Laurent Couvidou
Você pode dar uma olhada na biblioteca PCL ( pointclouds.org ). A conversão da imagem em profundidade do kinect fornece uma nuvem de pontos com a câmera na origem, apontando ao longo do eixo z. Você poderia usar o ransac ou outro algoritmo para procurar o avião.
Exilyth 19/07/12

Respostas:

1

Como a álgebra vetorial é compatível com GPU, normalizações e produtos de ponto podem ser usados ​​para encontrar os quatro cantos do plano original da seguinte maneira:

insira a descrição da imagem aqui

Dado o ponto do projetor (P), o ponto projetado (B), um ponto arbitrário no plano que contém o retângulo distorcido (Q) e o vetor normal para esse plano (n), o ponto de interseção (A) do linha de P a B, e o avião é dado por

s = -dot_product(n, P - Q) / dot_product(n, normalized(B - P)) 
A = P + s * normalized(B-P)

Fonte http://geomalgorithms.com/a05-_intersect-1.html section Interseção de plano de linha

rraallvv
fonte