5.22. Correção de lente e perspectiva¶
Duas classes de correção geométrica deformam a imagem de maneiras que um mapeamento retângulo-para-retângulo não consegue. A correção de lente desfaz a distorção radial que uma lente grande-angular real introduz – o abaulamento olho-de-peixe que curva linhas retas da cena, transformando-as em curvas visíveis perto dos cantos do quadro. A correção de perspectiva desfaz o efeito trapezoidal (keystone) que ocorre quando a lente não está apontada perpendicularmente à cena – a deformação trapezoidal que transforma um retângulo conhecido no mundo real em um blob não retangular na imagem. Ambas as correções desfazem, após a captura ser concluída, efeitos de origem óptica.
5.22.1. Distorção radial de lente¶
O material sobre efeitos reais de lente descreve a distorção barril que as lentes grande-angular baratas introduzem. Os pixels perto do centro do quadro ficam aproximadamente onde o modelo de câmera estenopeica prevê; os pixels perto das bordas são abaulados para fora por uma quantidade que cresce com o quadrado da distância radial em relação ao eixo óptico. Uma linha reta na cena que passa perto da borda do quadro se curva visivelmente na imagem capturada, e qualquer algoritmo clássico de visão de máquina que assume que linhas retas permanecem retas – detecção de cantos de AprilTag, seguimento de bordas, navegação por seguimento de linha – obtém a resposta errada perto dos cantos.
lens_corr() desfaz a distorção. O método executa o mapeamento inverso: cada pixel de saída é amostrado a partir da posição na entrada de onde a lente o teria abaulado para fora, e o resultado é uma imagem geometricamente reta.
img.lens_corr(strength=1.8)
O parâmetro strength é o cerne da correção. É um único número que descreve o quão fortemente a lente abaula; um valor próximo de 1.0 é uma correção suave para uma lente moderadamente grande-angular, e valores de até cerca de 2.0 são razoáveis para um olho-de-peixe forte. O padrão de 1.8 é um bom ponto de partida para as lentes de fábrica da OpenMV Cam; o valor correto para qualquer lente específica é uma questão de experimentar alguns e observar a imagem.
Os dois parâmetros secundários geralmente ficam bem em seus valores padrão. zoom (padrão 1.0) escala a saída – um valor maior que um recorta para fora para compensar a maneira como a correção de lente empurra os cantos mais para fora; valores menores deixam mais da cena corrigida visível ao custo de incluir pixels em branco nas bordas da imagem. x_corr e y_corr deslocam o centro da correção para longe do centro geométrico da imagem, o que é útil quando a lente não está opticamente centralizada sobre o sensor (um caso incomum, mas que vale a pena conhecer).
Um pipeline típico: capturar, executar lens_corr() uma vez para endireitar a geometria e, em seguida, executar o que quer que a aplicação realmente faça com o resultado.
5.22.2. Correção de rotação 3D¶
A outra classe de distorção geométrica é a deformação de perspectiva que ocorre quando o plano do sensor não está paralelo ao plano da cena. O caso clássico é uma placa de sinalização ou uma placa de matrícula vista de baixo: o topo da placa está mais distante da lente do que a base, então ele projeta menor, e a imagem capturada mostra o retângulo como um trapézio com a borda superior mais curta que a borda inferior.
A solução é aplicar uma rotação 3D ao quadro capturado que virtualmente reorienta o plano do sensor para ficar paralelo ao plano da cena. A matemática é o mesmo mapeamento de perspectiva que a detecção de AprilTag usa para recuperar a pose de uma tag a partir de seus quatro cantos, executado de forma inversa: dada uma rotação, a operação mapeia cada pixel de saída de volta à posição de entrada de onde a rotação teria vindo.
rotation_corr() executa essa correção:
img.rotation_corr(x_rotation=10.0, y_rotation=0.0, z_rotation=0.0)
Os três parâmetros de rotação estão em graus e descrevem rotações em torno dos eixos x, y e z de uma câmera virtual centralizada na imagem. x_rotation inclina a câmera para cima ou para baixo (a correção natural para uma foto de uma parede tirada ao nível do solo); y_rotation gira a câmera horizontalmente para a esquerda ou para a direita; z_rotation gira a câmera em torno de seu eixo óptico (a correção natural para uma montagem desnivelada).
x_translation e y_translation movem a câmera virtual lateralmente sem rotacioná-la. zoom (padrão 1.0) escala a saída. fov (padrão 60.0) descreve o campo de visão vertical da câmera, usado para calcular a projeção – o valor deve corresponder à lente real para manter a geometria consistente.
Para uma combinação arbitrária de inclinação e giro horizontal, múltiplas rotações não nulas se compõem em uma única chamada. A ordem das operações é fixa dentro da implementação; a aplicação apenas fornece os ângulos e o resultado é produzido.
5.22.3. Retificando um retângulo conhecido¶
A forma mais comumente útil de rotation_corr() é o argumento nomeado corners=, que recebe uma lista de quatro tuplas (x, y) descrevendo os cantos de um retângulo conhecido na imagem de entrada. O método calcula qual rotação 3D teria mapeado um retângulo verdadeiro para aqueles quatro pontos específicos, aplica o inverso dessa rotação à imagem inteira e retorna um resultado no qual o retângulo conhecido volta a ser retangular:
plate_corners = [(45, 80), (300, 60), (310, 180), (40, 200)]
img.rotation_corr(corners=plate_corners)
O uso clássico é exatamente o que o nome sugere: uma placa de matrícula (ou qualquer outra característica retangular) fotografada de um ângulo oblíquo. Um estágio anterior detecta a placa e relata as posições de seus quatro cantos na imagem capturada; passar esses cantos para rotation_corr() produz uma imagem na qual a placa aparece como um retângulo verdadeiro, pronta para qualquer estágio de reconhecimento de caracteres ou correspondência de modelos que venha a seguir.
Quando a forma de quatro cantos resolve o problema que uma aplicação está tentando resolver, ela é dramaticamente mais útil do que a forma de seis parâmetros. A aplicação não precisa estimar nenhum ângulo de rotação; ela apenas entrega quatro pontos ao método e deixa o método descobrir o resto. A forma de seis parâmetros é útil quando nenhum retângulo identificável está visível na cena e a rotação precisa ser ajustada manualmente a partir de conhecimento externo (um ângulo de montagem calibrado, por exemplo).