Você está na página 1de 18

UNIVERSIDADE FEDERAL DO ABC

Calibração de Câmeras e Correção de Distorção


[ESZA019-17] Visão Computacional
Prof. Dr. Filipe Ieda Fazanaro

Isabelle Diniz Orlandi

Santo André, 12 de agosto de 2018


SUMÁRIO

1 RESUMO 2

2 METODOLOGIA 3
2.1 Calibração de Câmera e Remoção de Distorções . . . . . . . . . . . . . . . . . 3
2.2 Projeção de Sistemas de Coordenadas em Imagens . . . . . . . . . . . . . . . . 5
2.3 Projeção de Linhas Epipolares em Imagens Obtidas num Sistema de Duas
Câmeras . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.4 Mapa de Disparidade . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

3 RESULTADOS 10
3.1 Calibração de Câmera e Remoção de Distorções . . . . . . . . . . . . . . . . . 10
3.2 Projeção de Sistemas de Coordenadas em Imagens . . . . . . . . . . . . . . . . 12
3.3 Projeção de Linhas Epipolares em Imagens Obtidas num Sistema de Duas
Câmeras . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3.4 Mapa de Disparidade . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

4 CONCLUSÕES 15

BIBLIOGRAFIA 17

1
1. RESUMO

Este trabalho apresenta a metodologia e resultados de quatro programas desenvolvidos


para a disciplina de Visão Computacional que envolvem operações de calibração de câmeras,
obtenção de parâmetros intrínsecos e extrínsecos da câmera e coeficientes de distorção, projeção
de linhas epipolares e trata do início do estudo da disparidade entre imagens. Os programas
foram desenvolvidos utilizando a linguagem de programação Python (versão 3.5) em conjunto
com as bibliotecas OpenCV (Open Source Computer Vision Library - versão 4.0) e Numpy.
Os três primeiros algoritmos apresentaram resultado dentro do esperado pela teoria, porém o
ultimo programa, que tem como objetivo projetar o mapa de disparidade entre duas imagens
gerou resultado mediano. Os resultados estão apresentados e os códigos podem ser encontrados
na pasta compartilhada \Isabelle_Diniz_Orlandi_11056613\pratica04.

Palavras-Chave: Processamento de Imagens, Python, OpenCV, Calibração, Câme-


ras, Correção, Distorção

2
2. METODOLOGIA

As seções abaixo apresentam as metodologias utilizadas na elaboração de quatro


programas de visão computacional que que tratam de operações de calibração de câmera,
remoção de distorções, projeção de linhas epipolares num sistema de câmeras e geração
de mapas de disparidade para obtenção da informação de profundidade em uma cena. Os
programas foram desenvolvidos na linguagem de programação Python (versão 3.5) em conjunto
com as bibliotecas OpenCV (versão 4.0) e Numpy. Os resultados das operações realizadas
estão apresentadas no próximo capítulo.

2.1 Calibração de Câmera e Remoção de Distorções


Tendo como objetivo corrigir as distorções radiais e tangenciais causadas por efeitos
físicos e de construção da câmera e da lente sobre uma imagem capturada, foi desenvolvido o
programa lab04_ex01.py.
A distorção radial é caracterizada pela representação de linhas retas de uma de forma
curva na imagem capturada. Esse efeito é resultado da dispersão da luz sobre a lente utilizada
principalmente sobre as regiões de bordas das imagens, pois estão mais distantes do eixo
óptico da câmera. Para modelas os coeficientes de distorção radial considera-se que não há
dispersão sobre o eixo óptico da imagem, e que a distorção cresce simetricamente seguindo o
padrão de uma série de Taylor, modelado por [1]:

xdistorced = x(1 + k1 r2 + k2 r4 + k3 r6 ) (1)


ydistorced = y(1 + k1 r2 + k2 r4 + k3 r6 ) (2)

√ 2
onde r = x + y2 .
As distorções tangenciais resultam da diferença entre o alinhamento do plano da
imagem com a lente utilizada, e seus efeitos são notados como a errada captura da profundidade
de objetos, que podem parecem mais distantes na região em que a lente mais se afasta do
plano da imagem. A distorção tangencial pode ser modelada pelas equações: [1]:

xdistorced =x + [2p1 xy + p2 (r2 + 2x2 )] (3)


ydistorced =y + [p1 (r2 + 2y2 ) + 2p2 xy] (4)

3
O vetor coefDist apresenta os 5 coeficientes necessários para as correções das distorções
em uma imagem:
coefDist = [k1 , k2 , p1 , p2 , k3 ] (5)

Além dos coeficientes de distorção, a calibração da câmera retorna valores dos


parâmetros intrínsecos e extrínsecos do sistema de captura. Os parâmetros intrínsecos estão
relacionados à distância focal (fx e fy ) e centro óptico (cx e cy ) da câmera e são utilizados
para formar a matriz da câmera. [1]:

 
fx 0 cx
Matriz da Câmera =  0 fy cy 
 


0 0 1

Uma vez que os parâmetros intrínsecos foram determinados, eles podem ser utilizados
para qualquer imagem capturada por esta câmera, pois como são parâmetros relacionados a
construção da câmera, eles não se alteram.
Os parâmetros extrínsecos fazem a relação entre a posição e orientação da câmera
com um objeto da cena.
A câmera utilizada para a calibração foi uma câmera USB padrão modelo Logitech
c270. Para realizar a calibração das câmeras, foi utilizado o método descrito por Zhang [2]
onde diversas imagens são tomadas de um objeto que possua padrão facilmente reconhecível
e com cantos específicos, por exemplo um tabuleiro de xadrez [3]. Todas as imagens devem
ser tomadas em um único plano de imagem XY para que a relação de profundidade seja
simplificada e apenas as coordenadas X e Y necessitem ser identificadas. Sabendo quais
pontos de cantos o padrão real apresenta é possível relacioná-los com os contos encontrados
na imagem e computar as distorções que a câmera apresenta.
No programa desenvolvido, para que a calibração das câmeras seja realizada, o
primeiro passo é obter as imagens do padrão do tabuleiro de xadrez. Um loop mostra
continuamente a cena capturada pela câmera enquanto o tabuleiro pode ser posicionado
de forma correta para ser totalmente capturado. Ao apertar a tecla ’s’ um frame é salvo
utilizando a função FilesNames(preName, ext) para nomear o nome do arquivo. Esta função
foi desenvolvida para que a captura de imagens não sobrescrevessem imagens já salvas, portado
realiza uma iteração em seu índice de acordo com o número de arquivos no diretório para
salvar a imagem em um novo arquivo.

4
def FilesNames (preName , ext ):
numFiles = len(os. listdir (’.’)) − 1
val = numFiles /2
newFileNameR = preName + ’R_’ + str(val) + ’.’ + ext
newFileNameL = preName + ’L_’ + str(val) + ’.’ + ext
return [ newFileNameR , newFileNameL , val]

Após tomadas as 15 fotos que serão usadas para a calibração, a função da biblioteca
OpenCV cv.findChessboardCorners() [4] identifica em cada uma das imagens tomadas seus
cantos e os salva em um array. Os cantos salvos passam por uma detecção mais fina através da
função cv.cornerSubPix() [5], que aumenta a precisão dos pontos detectados. Após confimados
os pontos identificados como cantos do tabuleiro a função cv.drawChessboardCorners() [4]
conecta os pontos detectados e desenha sobre a imagem as conexões e os pontos detectados.
Uma por vez, as imagens obtidas com os cantos detectados e destacados são exibidas em uma
janela Linux rapidamente.
A calibração da câmera em si é obtida pela utilização da função cv.calibrateCamera()
[4], que retorna a matriz da câmera (3x3) e o vetor de coeficientes de distorção da imagem.
Para afinar os resultados da matriz e dos coeficientes, os dados são processados pela
função do OpenCV cv.getOptimalNewCameraMatrix() [4] que retorna a matriz da câmera
baseada em um parâmetro de escala livre α. Se α=0 a função retorna a matriz para correção
da distorção com o mínimo de pixels indesejados; se α=1 todos os pixels da imagem distorcida
serão mantidos quando corrigidos, e os pixels adicionais serão preenchidos com valores igual a
zero (pixel preto). No programa a função foi utilizada com o parâmetro α=1.
A correção de uma imagem de acordo com os parâmetros modelados é realizada com
a função cv.undistort() [4]. Esta função utiliza as matrizes e coeficientes de distorção para
corrigir as distorções radiais e tangenciais, e é responsável por preencher com zeros (pixels
pretos) as bordas da imagem para adequação do formato retangular.
O resultado da correção das distorções é apresentado em uma janela, que compara
uma das imagens originais tiradas do tabuleiro de xadrez com a correspondente imagem
corrigida.

2.2 Projeção de Sistemas de Coordenadas em Imagens


Com o objetivo de estimar o sistema de coordenadas de um objeto em uma cena e
verificar sua orientação com relação a câmera foi desenvolvido o programa lab04_ex02.py.

5
Utilizando os dados da matriz de caracterização da câmera salvos pelos programa
anterior e assumindo que um conjunto de fotos de um mesmo objeto estão sendo tiradas
em um plano XY fixado, pode-se encontrar um sistema de coordenadas correspondente à
orientação do objeto com relação à câmera.
Foram utilizadas as mesma imagens do tabuleiro de xadrez para terem seus cantos
identificados pela função cv.findChessboardCorners(). A informação de rotação e orientação do
objeto são obtidas através da função do OpenCV cv.solvePnP() [4] que relaciona o objeto entre
os planos 2D-3D. A função cv.projectPoints() é utilizada para projetar pontos 3D no plano
da imagem dados os parâmetros instrínsecos e extrínsecos da câmera. Para desenhar sobre a
imagem os pontos projetados pela função citada, foi utilizada a subfunção draw_Coord(), que
está apresentada abaixo:

def draw_Coord (img , corners , imgpts ):


imgpts = np.int32( imgpts ). reshape(−1,2)
img = cv. drawContours (img , [ imgpts [:4]],−1,(0,255,0),−3)
for i,j in zip( range (4), range (4 ,8)):
img = cv.line(img , tuple ( imgpts [i]), ...
... tuple ( imgpts [j]) ,(255) ,3)
img = cv. drawContours (img , [ imgpts [4:]],−1,(0,0,255),3)
return img

O programa exibe em uma janela Linux as imagens do tabuleiro de xadrez com um


cubo renderizado sobre o tabuleiro, representando sua orientação e rotação com relação à
câmera.

2.3 Projeção de Linhas Epipolares em Imagens Obtidas num Sis-


tema de Duas Câmeras
Através de um sistema de captura de imagens com geometria epipolar é possível
extrair informações de profundidade de objetos na cena. Com duas câmeras posicionadas
de forma a seus eixos ópticos se cruzarem. A Figura 1 apresenta um esquema de geometria
epipolar:
Uma imagem obtida com a câmera esquerda não é capaz de indicar qual a profundidade
do objeto capturado pois todas os pontos da linha OX se projetam sobre o mesmo ponto no
plano da imagem. Logo, a profundidade pode ser extraída pela relação com uma imagem

6
Figura 1: Plano epipolar definido pelo objeto observado X e os centros ópticos das duas
câmeras. Extraído de [6].

capturada de outro ângulo de vista já que para a câmera da direta diferentes profundidades
do objeto em X sobre o eixo óptico da câmera esquerda representam pontos distintos em
seu próprio plano de imagem. O plano XOO’ é chamado de plano epipolar e os pontos e
são chamados epipólos, representando a intersecção entre os centros ópticos e os planos de
imagem das câmeras.
No programa para encontrar a melhor correspondência entre os pontos iguais captu-
rados nas duas imagens foi utilizada a função cv.xfeatures2d.SIFT_create(). Em seguida é
calculada a matriz fundamental.
As linhas epipolares encontradas em uma imagem são desenhadas sobre a outra
imagem, e para realizar o desenho, foi utilizada a subfunção :

def drawlines (img1 ,img2 ,lines ,pts1 ,pts2 ):


r,c = img1.shape
img1 = cv. cvtColor (img1 ,cv. COLOR_GRAY2BGR )
img2 = cv. cvtColor (img2 ,cv. COLOR_GRAY2BGR )
for r,pt1 ,pt2 in zip(lines ,pts1 ,pts2 ):
color = tuple (np. random . randint (0 ,255 ,3). tolist ())
x0 ,y0 = map(int , [0, −r[2]/r[1] ])
x1 ,y1 = map(int , [c, −(r[2]+r [0]∗ c)/r[1] ])
img1 = cv.line(img1 , (x0 ,y0), (x1 ,y1), color ,1)
img1 = cv. circle (img1 ,tuple (pt1),5,color ,−1)
img2 = cv. circle (img2 ,tuple (pt2),5,color ,−1)
return img1 ,img2

7
O resultado das linhas epipolares sobre as imagens das câmeras esquerda e diretita
são mostrados em uma janela, utilizando a bilbioteca Matplotlib.

2.4 Mapa de Disparidade


Para geração de um mapa de disparidade entre duas imagens obtidas a partir de um
sistema de visão estéreo, foi desenvolvido o programa lab04_ex04.py.
Para obter a profundidade de um objeto através de duas imagens tiradas de câmeras
afastadas horizontalmente e tendo seus eixos ópticos paralelos, pode-se modelar o sistema
descrito como na Figura 7:

Figura 2: Esquema de triangularização atraves da visão estéreo. Extraído de [7].

Através de equivalências de triângulos encontra-se a relação 6:

Bf
disparity = x − x 0 = (6)
Z

onde x e x 0 indicam respectivamente a distância entre os pontos da imagem corres-


pondente ao objeto na cena 3D e o centro da câmera; B é a distância entre as duas câmeras e
f a distância focal da câmera. Com esses dados é possível computar a profundidade de todos
os pixels em uma imagem.
O código para geração do mapa de profundidade carrega as duas imagens obti-
das no programa lab04_ex03.py e computa o mapa de disparidade utilizando a função
cv.StereoBM_create() e compute().

8
O programa exibe em uma janela uma das imagens originais capturadas da cena e o
mapa de disparidade para comparação.

9
3. RESULTADOS

3.1 Calibração de Câmera e Remoção de Distorções


O primeiro programa desenvolvido lab04_ex01.py realiza a calibração da câmera
após salvar em disco 15 imagens de um tabuleiro de xadrez posicionado na cena em diferentes
posições, porém, em determinada distância do plano da imagem. Para a obtenção das imagens
uma janela Linux fica continuamente mostrando a cena capturada pela câmera, e quando o
tabuleiro está na posição desejada ao apertar a tecla ’s’ o frame é salvo. Estão apresentadas
na Figura 3 exemplos das fotos tomadas para a calibração da câmera:

Figura 3: Imagens obtidas do tabuleiro de xadrez para calibração da câmera.

Após a obtenção das imagens, é realizada a detecção dos cantos de cada uma das
imagens tomadas. Em uma janela Linux são apresentadas em sequência as imagens com os
cantos identificados, e para passar pela sequência de imagens basta apertar a tecla ’q’. A
Figura 4 apresenta um exemplo de uma janela apresentando os cantos identificados:

10
Figura 4: Janela exibindo os cantos detectados no tabuleiro de xadrez.

Com os cantos de todas as imagens identificados, a calibração é concluída com a


correção de uma imagem capturada a fim de remover as distorções detectadas pela calibração.
Para exibir o resultado da correção, uma janela apresenta lado a lado uma das imagens do
tabuleiro capturadas e sua correspondente já corrigida. A Figura 5 apresenta o resultado da
operação:

Figura 5: Comparação entre uma imagem capturada original e sua correspondente com
remoção de distorções.

11
3.2 Projeção de Sistemas de Coordenadas em Imagens
O segundo programa lab04_ex02.py tem como objetivo projetar na imagem dos
padrões de tabuleiro de xadrez sistemas de coordenadas ou cubos que representem a posição
e orientação do objeto com relação ao plano da câmera. Este programa utiliza os dados
gravados em memória da matriz da câmera e coeficientes de distorção para utilizar em suas
próprias operações.
O resultado da projeção de cubos sobre os tabuleiros de xadrez para representar sua
posição e orientação no espaço esá apresentado na Figura 6:

Figura 6: Resultado da projeção de cubos sobre os tabuleiros de xadrez para representar


sua orientação.

3.3 Projeção de Linhas Epipolares em Imagens Obtidas num Sis-


tema de Duas Câmeras
O terceiro programa lab04_ex03.py quando executado inicia a exibição das capturas
de duas câmeras dispostas de forma a cruzarem seus eixos ópticos em um plano. Quando a
tecla ’s’ é pressionada um par de imagens são salvas sob os nomes frameL e frameR. O par
de exemplo de imagens capturadas para estão apresentados na Figura 7:
Após as operações necessárias para obtenção das projeções de linhas epipolares entre
as imagens, obtida pela relação entre pontos presentes nas duas imagens, o programa exibe a
imagem com as linhas desenhadas. Para as imagens mostradas na Figura 7 as linhas epipolares
identificadas estão apresentadas na Figura 8

12
Figura 7: Imagens capturadas pelo lado esquerdo e direito em um sistema de captura estéreo.

Figura 8: Projeção das linhas epipolares do sistema de câmeras de acordo com pontos
identificados nas imagens.

3.4 Mapa de Disparidade


O último programa lab04_ex04.py tem como objetivo gerar o mapa de disparidade
entre duas imagens obtidas por um sistema de capturas estéreo. As imagens escolhidas
foram as obtidas pelo sistema analisado no programa anterior e apresentadas na Figura 7. O
resultado para o mapa de disparidade entre elas está apresentado na Figura 9.
O mapa de disparidade apresentado possui bastante ruído e não sinaliza de forma
clara a profundidade dos objetos envolvidos na cena.
Isso acontece pois a função de disparidade utilizada está preparada para computar o
mapa de disparidade de imagem que estão associadas a um mesmo plano de imagem, estando
seus eixos ópticos completamente paralelos. Nas imagens utilizadas as câmeras estavam
posicionadas de forma a terem seus eixos ópticos cruzados e não foram realizadas operações
de transformações sobre elas antes da geração do mapa de profundidade.

13
Figura 9: Imagem da câmera da direita e correspondente mapa de disparidade da cena
capturada.

Para a correta obtenção do mapa de disparidade deste par de imagens, ambas deveriam
passar pelo processo de transformação geométrica ditado pelos coeficientes das matrizes que
relacionam os sistemas de coordenadas das câmeras, para que elas apresentassem suas imagens
em um planos de imagem paralelos. Ou, as câmeras deveriam estar dispostas com seus
eixos ópticos aproximadamente paralelos, para que apenas pequenas correções e distorções
necessitassem ser removidas.

14
4. CONCLUSÕES

Ao longo da disciplina de Visão Computacional e dos relatórios de laboratórios


desenvolvidos durante o período, foram abordadas diversas vezes a importância da qualidade
do pré-processamento de imagens para a extração da correta informação desejada de uma
cena. Foram tratados método que atuam sobre diversos aspectos para extração de elementos
que prejudicam na interpretação da imagem de forma computacional, como remoção de ruídos,
suavização da imagem, ajuste de mapas de cor, entre outras operações. Ainda não estavam
sendo levados em conta as distorções presentes em uma imagem geradas pela construção da
câmera e efeitos físicos presentes da captura de uma cena real.
Por mais que modelos teóricos sejam reproduzidos na vida real com extrema precisão e
detalhes, sempre haverão fatores dissipativos e de interferência que gerarão pequenas distorções
em uma imagem capturada quando comparada com a cena real. Para que um sistema preciso
de visão computacional extraia informações - como profundidade dos objetos - de uma cena é
necessária que essas distorções sejam corrigidas e incorporadas a imagem a ser processada.
Em geral, os programas apresentados neste relatório funcionaram como esperado.
O programa lab04_ex04.py pode ser melhorado através da correção das imagens para
um mesmo plano de imagem, para posterior geração do mapa de disparidade. O programa
lab04_ex02.py que projeta no tabuleiro de xadrez cubos relacionados a sua posição e
orientação no espaço apresenta uma ferramenta muito interessante e que pode ser adaptada
para ser utilizada de diversas maneiras dentro da visão computacional. A possibilidade de
criar marcadores de padrões sobre sistemas cartesianos para projetar sobre eles um desenho
de interesse pode ser utilizada até na indústria de entretenimento, como por exemplo, em um
jogo de cartas interativo, onde os personagem das cartas são identificados e projetados sobre
as cartas em uma imagem da cena.
No contexto da robótica, a interpretação de uma cena quanto à profundidade do
ambiente e dos objetos que nela aparecem é base de muitas aplicações. Para que um braço
robótico, ou robô móvel ou um robô humanoide possam interagir com o ambiente de forma
segura e equilibrada é necessário que possam detectar profundidades e distâncias entre objetos.
Os estudos desenvolvidos durante a disciplina apresentaram os primeiros passos a serem dados
para um processo que envolve a captura de imagens para extração de informações. Calibração
do sistema de câmeras, eliminação de ruídos, filtragem, correção de cor, aplicação de limiares,

15
detecção de bordas e segmentação de objetos são a base para o início de qualquer projeto de
visão computacional e a partir do resultado dessas operações são iniciadas as classificações e
tomadas de decisões de uma aplicação.

16
BIBLIOGRAFIA

[1] OpenCV. (2018, Jul.) Camera calibration. [Online]. Available: https://docs.opencv.org/3.


4.2/dc/dbb/tutorial_py_calibration.html Citado 2 vezes nas páginas 3 e 4.

[2] Z. Zhang, “A flexible new technique for camera calibration,” IEEE Transactions on Pattern
Analysis and Machine Intelligence, vol. 22, no. 11, pp. 1330–1334, Nov 2000. Citado na
página 4.

[3] K. Dawson-Howe, A Practical Introduction to Computer Vision with OpenCV, Enhanced


Edition. Wiley, 2014. [Online]. Available: https://books.google.com.br/books?id=
PmKJCwAAQBAJ Citado na página 4.

[4] OpenCV. (2017, Oct.) Camera calibration and 3d reconstruction. [On-


line]. Available: https://docs.opencv.org/3.3.1/d9/d0c/group__calib3d.html#
ga93efa9b0aa890de240ca32b11253dd4a Citado 2 vezes nas páginas 5 e 6.

[5] ——. (2015) Feature detection. [Online]. Available: https://docs.opencv.org/3.1.0/dd/


d1a/group__imgproc__feature.html Citado na página 5.

[6] ——. (2018, Jul.) Epipolar geometry. Citado na página 7.

[7] ——. (2018, Jul.) Depth map from stereo images. Citado na página 8.

17

Você também pode gostar