Transformações afins com Python

Leandro Cruvinel
7 min readSep 16, 2019

--

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”.

Fonte: Pixabay

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:

https://docs.opencv.org

Fazendo M = [ A B ], podemos representar as equações acima da seguinte forma:

https://docs.opencv.org

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:

Pixabay

Sua missão é gerar a imagem abaixo utilizando a imagem acima:

Espero que tenham gostado e até a próxima!!!

--

--

Leandro Cruvinel
Leandro Cruvinel

Written by Leandro Cruvinel

Math Professor | Data Scientist | Web developer

Responses (1)