Inverse perspective mapping em python usando warpPerspective

Este artigo descreve as duas experiências no âmbito da visão artificial efectuadas numa simulação no gazebo com recurso ao método warpPerspective em python

Em python o método warpPerspective permite calcular como uma imagem seria vista de outra perspectiva.

dst = cv2.warpPerspective(src, transform_mat, dsize[, dst[, flags[, borderMode[, borderValue]]]] )

src: imagem original
transform_mat: matriz da transformação
dsize: tamanho da imagem gerada (w,h)
flags: (opcional) métodos de interpolação

A matriz da transformação é o ponto essencial sendo composta pelos elementos descritos na seguinte imagem.

O principal problema na aplicação deste método é a obtenção da matriz da transformação.

Para isso existem dois métodos no python, em ambos os casos são necessárias as coordenadas de 4 pontos, na imagem de origem e na imagem de destino.

  • transform_mat , status = cv2.findHomography(pts_src, pts_dst)
  • transform_mat = cv2.getPerspectiveTransform(pts_src, pts_dst)

# pts_src: coordenadas de 4 pontos na imagem original
# pts_dst: coordenadas desses 4 pontos na imagem transformada

No caso desta abordagem  para obter a vista superior (bird eye view) pelo método IPM, usaremos apenas o método getPerspectiveTransform.

Para descobrir as novas coordenadas dos quatro pontos foram colocadas em prática duas experiências no Gazebo.

Nestas experiências foi usado um programa de manipulação de perspectiva de modo a facilitar o calculo dos pontos. No entanto, o processo pode ser efectuado sem a ele se recorrer.

Experiência sem manter proporções

Foi montando o seguinte ambiente no gazebo. Um objecto rectangular e plano, de espessura desprezível, foi colocado à frente de uma viatura equipada com uma camera, de modo a ocupar todo o campo de imagem longitudinal.


imagem 1

Note-se que a quadricula tem 25 cm de lado, e que o centro da viatura e o centro da zona cinzenta estão sobre o mesmo eixo. A zona cinzenta tem 50 cm de largura. A imagem da camera existente da viatura, visualizada com o image view, é a seguinte.


imagem 2

Visualização com o programa de transformação, onde se constata que para os parâmetros exibidos a imagem é igual.


imagem 3

Visualização com o mesmo programa alterando apenas o parâmetro correspondente ao pitch


imagem 4

Com base na imagem 2 foram seleccionados os pontos dos 4 vertices do trapézio cinzento. Que têm as seguintes coordenadas, no sentido dos ponteiros do relógio, iniciando no topo superior esquerdo:

[200,0], [478,0], [200,479], [478,479]

Com base na imagem 4 foram seleccionados, os 4 pontos de correspondentes na imagem transformada.

[288, 0], [391, 0], [113, 479], [563, 479]

Estes pontos foram inseridos no seguinte programa (programa1), que quando executado, e conforme esperado, produziu uma imagem semelhante à da imagem 4.

import cv2
import numpy as np

img = cv2.imread('image2.jpg')


# define points coordinates
dst_pts = np.array([[200,0], [478,0], [200,479], [478,479]], dtype=np.float32)
src_pts = np.array([[288, 0], [391, 0], [113, 479], [563, 479]], dtype=np.float32)

# compute IPM matrix and apply it
transform_matrix = cv2.getPerspectiveTransform(src_pts, dst_pts)
ipm = cv2.warpPerspective(img, transform_matrix, img.shape[:2][::-1], flags=cv2.INTER_CUBIC)

# display image
cv2.imshow('ipm', ipm)
cv2.waitKey()

De seguida, aplicamos exactamente a mesma transformação à seguinte imagem.


image 5

O resultado da transformação obtida é o seguinte:


imagem 6

Nesta  imagem (6) verifica-se a compressão da distância que acontece na altura da imagem. Isto acontece porque, para o mesmo campo angular de visão, o deslocamento ao longo dos 45º de arco de circunferência, de A1 para A2, provoca a aproximação do ponto a a b, até serem coincidentes.

Esta situação está ilustrada na imagem seguinte.


imagem 7

Experiência mantendo as proporções

Foi montando o seguinte ambiente no gazebo. Um objecto quadrado e plano, com 1 m de aresta e de espessura desprezível, foi colocado à frente de uma viatura equipada com uma camera.


imagem 8

A aresta mais próxima do quadrado, dista 1 metro da projecção vertical da camera sobre a estrada.

A quadricula tem 25 cm de lado, e que o centro da viatura e o centro da zona cinzenta estão sobre o mesmo eixo.

Neste caso a imagem da camera existente da viatura, visualizada com o image view, é a seguinte.


imagem 9

Desta vez omitimos a exibição da imagem no programa de transformação, já que se sabe ser igual a imagem 9.

Quando se aplica um pitch de 37º (à pouco foi usado 36) o aspecto da imagem transformada fica o seguinte.


imagem 10

Neste programa de transformação não acontece o efeito de compressão, o efeito da compressão resultou da escolha, na experiência anterior de transformar os pontos apenas quanto à componente transversal da coordenadas, mantendo as coordenadas longitudinais iguais.

No entanto, o quadrado não aparece todo visível, pelo que se torna necessário ajustar a distancia do quadrado ao carro de modo a que se consiga ver todo.


image 11


image 12


image 13

Após procurar ajustar a distância do quadrado à viatura, ficando conforme visível nas imagens 11, 12 e 13, conclui que sem mudar outros parâmetros era impossível visualizar o quadrado de 1 metro na sua totalidade, pelo que reduzi o tamanho para 50 cm.


image 14


image 15

image 16

As imagens 14, 15 e 16, exibem, respectivamente, o ambiente no gazebo, a perspectiva da camera, e a perspectiva transformada.

Neste caso o quadrado é integralmente visível, no entanto, quando medido ao pormenor ele continua a estar comprimido na altura, já que o seu tamanho em pixels é de 279 x 259.

Aplicando ao programa1 os seguintes pontos:

source: [218, 191], [462, 191], [530, 374], [151, 374]
destination: [202, 145], [480, 145], [480, 404], [202, 404]

verificou-se que para a mesma imagem (imagem 15) correspondia uma imagem semelhante à da imagem 16.

Como a discrepância na dimensão dos pixels do quadrado é de 20 pixels, foi efectuada uma alteração na coordenada y dos dois primeiros pontos de destino. Globalmente ficou assim.

destination: [202, 125], [480, 125], [480, 404], [202, 404]

O resultado melhorou bastante, e o quadrado ficou com 279 x 279 px, pelo que também se pode  concluir que nesta vista existem 558 pixels por metro.

Aplicando esta nova transformação a imagem 5, obteve-se então a seguinte imagem que está menos comprimida.

Conclusão, para obter empiricamente as coordenadas dos pontos dos quatro pontos na imagem de origem e respectivas as coordenadas dos pontos na imagem de destino, deve-se usar um quadrado de dimensões conhecidas que esteja inteiramente visível.

Referencias

https://theailearner.com/tag/cv2-warpperspective/

Geometry of Image Formation

https://www.edmundoptics.com/knowledge-center/application-notes/imaging/understanding-focal-length-and-field-of-view/

 

Tentativa de estimar distancias e pixels por metro no gazebo

De modo a tentar estimar o numero de pixels por metro e a distancia de objectos no gazebo, efectuei a experiência que descrevo neste artigo

Foi colocado no pavimento um quadrado com um metro de largo, que está visível à frente do veiculo.

O veiculo tem uma camera instalada a cerca de 547 milímetros do solo com cerca de 55,5 graus de inclinação face ao pavimento, com uma distancia focal de 563 (px).

A imagem que a camera publica, visível abaixo, permite ver toda a sua largura, que é 1 metro. Esta imagem está em perspectiva, o que não impede que se aplique a equação acima. Para a aplicar só falta determinar a largura, daquela face do quadrado em pixels.

As coordenadas dos pixels nos vertices dessa face são: 148, 246 e 618, 246, pelo que, a distancia que está aquela face, a 1 metro correspondem 417 pixels.

Sendo assim aplicando a equação para calcular a distância aproximada com base numa imagem: Distancia = (distancia_focal x largura ) / pixels

Distancia = (563 x 1) / 417 = 1.35 metros

Considerando a imagem do gazebo, é perceptível que o centro do carro dista 1.5 metros da face do quadrado que estamos a considerar. Tendo em conta que o carro tem cerca de 26 cm de comprimento, e que a câmara está recuada 5 cm da frente da viatura, podemos concluir que distancia real será de 1.42m, ou seja próxima do valor calculado.

No entanto é de salientar que

Consideramos agora a transformação para birds eye view exibida na imagem abaixo.

Neste caso a largura da face do rectângulo, que tem 1 metro, é de 517 pixels.

No entanto se aplicarmos a mesma equação temos: Distancia = 1.08 metros

Este valor tem uma grande discrepância face a distancia real, e não permitiu esclarecer as duvidas que tenho sobre o efeito da altura real da camera, e o facto do tamanho da imagem transformada pelo método ipm ser directamente proporcional a distancia, ou seja quando a distancia aumenta, o tamanho também aumenta, é como se a camera fica-se mais próxima.

 

 

 

Estimar a distância de um objecto a uma câmera

Para estimar a distancia de um objecto a uma câmara só são necessárias 3 dados, e aplicar a seguinte equação:

A distância focal (F) da câmara, que pode ser encontrada nas especificações da câmara, ou usando os métodos para estimar a distância focal. A distância focal deve estar expressa em pixels.

A largura (W), ou altura (H), do objecto real, caso use a altura, deve trocar o W por H na equação. Quanto mais exacta for a medida usada mais precisa vai ser a estimativa da distância. A dimensão pode estar expressa em qualquer unidade, sendo que a distancia será expressa na unidade usada.

A largura, ou altura, (P), em pixels, do objecto na imagem, em conformidade com a medida que foi usada no objecto real.

Depois, basta aplicar na equação acima para obter a distância (D), nas mesmas unidades de W.

 

Estimar a distância focal de uma camera

Este artigo é sobre como estimar a distância focal de uma câmara, quando a mesma não se encontra disponível nas especificações da câmara. Para se obter a distância focal de uma camera Podem ser utilizados dois métodos.

Um método, que não será abordado neste artigo, consiste na utilização de um padrão de xadrez com dimensões conhecidas e após tirar várias fotografias com diferentes orientações, efectuar cálculos para encontrar os parâmetros intrínsecos da camera (distancia focal, centro e coeficientes de distorção das lentes).

O outro método de obter a uma estimativa aproximada da distância focal é o que vamos abordar aqui.

A distância focal é usada em vários processos de calculo relacionadas com imagens fotográficas, como por exemplo calculo de distancias.

Traduções

  • Distância Focal = Focal Length,
  • Campo de Visão = Field of View
  • Plano da imagem = image Plane (largura da imagem)

Com base na imagem abaixo, podemos deduzir as relações entre o campo de visão (alpha), a distância a focal (f) e o plano da imagem (w).

No caso das cameras de video, as unidades do plano de imagem são em pixels, pelo que no final a distancia focal calculada também é expressa em pixels.

Grosso modo, considerando que o triângulo formado pelo centro da lente e os dois extremos do plano da imagem (w), pode ser dividido em dois rectângulos equivalentes, e seja (beta) o ângulo entre o cateto adjacente e a hipotenusa, então (alpha) = 2 x (beta).
Sabendo que a tg(beta) é igual ao cateto oposto (w/2) a dividir pelo  cateto adjacente (f) então:

tg(beta) = (w/2)/f que é equivalente a tg(beta) = w/(2f), daqui decorre que

(beta) = arctg(w/(2f)), considerando que (alpha) = 2 (beta) então:

Com esta equação sabendo a distancia focal e a largura do plano de imagem conhecemos o ângulo do campo de visão horizontal (HFOV).

Esta equação pode ser reproduzida para a altura do plano de imagem (h) e assim saber o ângulo do campo de visão vertical (VFOV).

Resolvendo em ordem à distancia focal (f) temos:

seja (alpha) = a

a = 2 arctg (w/(2f))

a /2  = arctg(w/(2f))

tg(a/2) = w/(2f)

f = w/(2 tg(a/2))

Sabendo que a cotangente é o inverso da tangente, chegaremos a equação:

Ou seja, com a equação acima sabendo a largura da imagem (w) em pixels e o ângulo do campo de visão (alpha) podemos obter a distancia focal (f) em pixels.

Saber a largura, ou a altura da imagem é fácil, no entanto, é necessário saber o ângulo do campo de visão horizontal (HFOV), e este nem sempre é informado nas especificações das cameras.
Muitas vezes as especificações de  informam o campo de visão diagonal (DFOV) da câmara.

Neste caso, como a diagonal do plano da imagem (linha a tracejado) (d), é a hipotenusa do triângulo rectângulo, com a largura (w) e altura (h) da imagem como catetos, logo pela aplicação do teorema de Pitágoras,

d = sqrt(w² + h²)

Podemos fazer uma aproximação com a seguinte equação, onde simplesmente se substituiu w por d:

Se pretendermos calcular o HFOV e o VFOV a partir do DFOV então teremos que aplicar estas equações extra:

Método prático de estimar a distância focal

Existe uma forma mais fácil e prática de estimar a distância focal. Este método implica tirar uma foto a um objecto de largura (W) ou altura (H) conhecida,  e tirar-lhe uma fotografia a uma distancia conhecida (D).
Sabendo a sua largura, ou altura, em pixels (P)

Para estimar a distância focal de uma câmara  (F), pode-se então usar a seguinte equação:

Se usar a altura H, deve-se trocar o W por H na equação acima.

Exemplos de aplicação

Exemplo 1: a camera Microsoft lifecam vx-800, cujas especificações apenas indicam o DFOV de 59º

Nesta camera, para uma imagem com 640 x 480, temos uma diagonal
d = 783.

Aplicando a ultima equação, temos:

f = (783/2) cotg(59º/2) = 392 * 1.7675 = 693

Distância focal = 693 pixels

Exemplo 2: a camera Logitech HD webcam C525, cujas especificações apenas indicam o DFOV de 69º

Nesta camera, para uma imagem com 640 x 480, temos uma diagonal
d = 783.

Aplicando a ultima equação, temos:

f = (783/2) cotg(69º/2) = 392 * 1.455 = 570

Distância focal = 570 pixels

 

Referencias

https://medium.com/@arnaldog12/como-calcular-a-dist%C3%A2ncia-de-um-objeto-pra-c%C3%A2mera-ef1173171f0

http://www.therandomlab.com/2013/03/logitech-c920-and-c910-fields-of-view.html

https://en.wikipedia.org/wiki/Pinhole_camera_model