Transformações afins com Python
A biblioteca OpenCV, também implementada em Python, contém uma gama de algoritmos relacionados à visão computacional. Dentre eles estão as transformações afins. Neste tutorial aprenderemos a utilizar essas transformações para recuperação de imagens “distorcidas”.
Os códigos nesse tutorial são imagens, não sendo possível copiá-los. Mas se quiser fazer isso, eu disponibilizei os códigos gratuitamente no meu Github, basta acessar o projeto clicando aqui.
Preparando seu computador
É preciso ter o software Anaconda Python 3.7 instalado. Se não tiver, basta fazer o download do instalador nesse link. A instalação é bem simples bastando clicar “Next” várias vezes.
Depois, basta procurar por “Anaconda Navigator” e, após abrí-lo, clicar em “Jupyter Notebook”. Como na imagem abaixo:
Ao clicar em “Jupyter notebook” a interface deste programa se abrirá no seu navegador de internet padrão. Daí então é só clicar em “New” e escolher Python 3, como mostra a figura abaixo:
Abrirá uma nova aba no seu navegador de internet, como na figura a seguir. Daí, basta digitar os código e apertar o botão “run”, indicado pelo quadrado vermelho na imagem. Neste exemplo, pedimos para o computador imprimir o texto (string) “Hello, world!”
Pronto, acabamos de executar nosso primeiro programa em Python utilizando o software Jupyter notebook!
Instalando o OpenCV
No Anaconda há uma variedade de bibliotecas instaladas, no entanto a biblioteca OpenCV não é uma delas e precisa ser instalada. Para instalar basta executar o código a seguir no seu Jupyter notebook:
Uma vez instalada você não precisa mais executar o código acima. Vejamos agora algumas funções legais da biblioteca OpenCV!
Lendo e mostrando uma imagem
A primeira imagem desse tutorial, chamada de Quadro Inacabado e retirada do site Pixabay, será usada em todo esse projeto. Para isso salvaremos a imagem com nome quadro.jpg na mesma pasta onde encontra-se o nosso projeto. Estamos prontos para começar a programar!
Primeiramente devemos importar as bibliotecas que utilizaremos:
Podemos ler o arquivo onde está a imagem e mostrar esta no Jupyter notebook:
Podemos notar que a imagem está diferente. Isso porque o OpenCV lê a imagem no sistema BGR. Mas podemos consertar isso com o código a seguir:
Podemos então mostrar a imagem novamente no Jupyter notebook:
É possível visualizar a figura numa janela separada criada pelo próprio OpenCV com o código a seguir:
Para fechar a janela, aperte a tecla 0 (zero).
Como funcionam as transformações afins?
As transformações afins são ilustradas pela seguinte relação:
Fazendo M = [ A B ], podemos representar as equações acima da seguinte forma:
Geometricamente, estamos transformando os pontos do plano cartesiano. Dependendo das matrizes A e B, essas transformações podem ser translações e/ou rotações.
Vejamos alguns exemplos na prática. Considere os vértices de um quadrado de lados medindo 2 unidades e centrado na origem.
Definiremos agora 3 transformações afins através de suas matrizes:
A transformação M1 estica o quadrado original na direção do eixo y dobrando sua área e, também, translada o quadrilátero em 5 unidades nessa mesma direção.
A transformação M2 estica o quadrado original na direção do eixo x dobrando seu área e, também, translada o quadrilátero em 5 unidades nessa mesma direção.
Por fim, a transformação M3 não altera a área do quadrado original, mas rotaciona este num ângulo de 45º e translada o mesmo 5 unidades na direção de x e 5 unidades na direção de y.
Considerando M = [A B], seguindo as notações já apresentadas neste post, observe que a área do quadrado é alterada det(A) vezes. Isso não é uma coincidência e um bom exercício de álgebra linear e geometria analítica é demonstrar este fato.
Para aplicar as transformações e obter novas coordenadas, basta multiplicar as matrizes M1, M2 e M3 pela matriz formada pelos vértices do quadrado original:
Para visualizar, num gráfico, o que aconteceu geometricamente com os vértices do quadrado original, executamos o código a seguir:
O resultado é o seguinte:
Transformações afim em imagens
Transformações afins podem ser utilizadas para alterar imagens. Uma imagem JPG pode ser representada num sistema cartesiano como na figura a seguir:
Os índices (posições das linhas e colunas) das entradas da matriz de cor da imagem são as coordenadas nesse sistema. Por exemplo, o pixel que está mais superior e mais a esquerda está na linha 0 e coluna 0 da matriz de cores da imagem. Estes mesmos índices [0 0] são as coordenadas que representam este pixel no plano cartesiano. O pixel mais inferior e mais a direita está na linha 424 e coluna 639 da matriz de cores da imagem. Logo, suas coordenadas no eixo cartesiano são [424 639]. É importante observar que começamos a contar linhas e colunas do zero, não do um como usual.
Para saber mais sobre imagens como matrizes recomendo este post.
Caso queiramos aplicar uma rotação de 45º na imagem acima, utilizamos o código a seguir:
O resultado é o seguinte:
Identificando pontos na imagem
Agora que sabemos recuperar imagens que foram transformadas (esticadas, rotacionadas e transladadas), para sermos precisos devemos determinar qual a matriz M correta a ser aplicada.
Para isso basta conhecer 3 pontos linearmente independentes, pois estes 3, como possuem 2 coordenadas cada, determinarão 6 equações nas variáveis a00, a01, a10, a11, b00 e b10 num sistema possível e determinado!!!
Mas como pegamos pontos numa imagem? Basta executar o código abaixo:
Ao clicar na imagem do quadro nos cantos superior esquerdo, inferior esquerdo e inferior direito, obtemos a seguinte saída:
Repetindo o processo com a imagem que rotacionamos anteriormente:
Obtemos:
Recuperando a imagem original
Agora podemos resolver o sistema e descobrir a transformação que alterou a imagem.
Felizmente o OpenCV também tem uma função para fazer isso automaticamente. No entanto é necessário passar 4 pontos da imagem como referência:
Observe que a matriz não é exata e sim aproximada, pois depende da precisão com que clicamos na borda do quadro contido na imagem!
Sumário
Aprendemos com este tutorial:
- Ler imagens com OpenCV
- Mudar sistema de cores da imagem com OpenCV
- Exibir a imagem com Matplotlib
- Exibir a imagem com OpenCV
- Testar transformações com Numpy
- Exibir as transformações com Matplotlib
- Testar transformações com OpenCV
- Identificar pontos na imagem com OpenCV
- Descobrir quais transformações afins foram aplicadas numa imagem transformada
Desafio!!!
Clicando aqui você baixa a imagem a seguir:
Sua missão é gerar a imagem abaixo utilizando a imagem acima:
Espero que tenham gostado e até a próxima!!!