Matrizes, imagens e Python!
Reconhecimento facial, carros autônomos e diagnósticos automatizados de exames clínicos como tomografia, raio-x e ultra-som. O que tudo isso tem em comum?
Um computador interpretando imagens!
Como isso é possível?
As imagens digitais são formadas por números, esses números podem ser interpretados pelo computador com a ajuda de algumas funções, cálculos e códigos. Vejamos, por exemplo, como seria a imagem do gato Félix formada por 1’s e 0's:
Para visualizar melhor, vamos colorir os 0’s:
Basicamente é isso, as imagens digitais são grandes matrizes com números e, para interpretar essas imagens, como nós humanos, os computadores realizam diversas operações com essas matrizes. Nesse tutorial, aprenderemos a ler, criar e manipular algumas imagens usando Python!
Os códigos estão como imagens. Para versão original e que dá para copiar e colar, pode acessar meu Github clicando aqui!
Começando a utilizar Python
Utilizaremos os notebooks do Google para escrever e executar nossos programas em Python. Para tal, siga as instruções abaixo:
- No seu navegador web digite: https://colab.research.google.com/
- Faça o login com sua conta do gmail (se não estiver logado).
- Clique em “Novo notebook”. Se tudo der certo, você estará vendo uma tela como abaixo:
Agora, faremos nosso primeiro programa em Python!
Seus notebooks ficarão salvos automaticamente no seu Google Drive. Dessa forma, para facilitar nossa busca pelos mesmos, daremos um nome conveniente. Faremos um programa que imprime a mensagem “Hello, world!”. Dessa forma, daremos o nome de hello-world-python.ipynb (veja a seta vermelha).
O próximo passo é escrever o programa. Escreva seu código onde está indicado pela seta verde na figura acima.
Por fim, executaremos nosso programa. Para isso aperte o play, indicado pela seta azul na figura acima.
Se tudo deu certo, aparecerá abaixo do código a mensagem Hello, world! Parabéns, você fez seu primeiro programa em Python.
Estamos prontos para começar!
Imagens RGB
Considere a seguinte imagem:
A imagem acima é composta por 3 camadas, uma vermelha, uma verde e uma azul. Como, em inglês, vermelho é RED, verde é GREEN e azul é BLUE, essa mistura é conhecida como sistema RGB.
Cada camada contém variações de tonalidades de sua respectiva cor. Essas variações são representadas por números inteiros de 0 a 255 com 0 representando ausência da cor e 255 representando a maior intensidade da cor. Quando sobrepostas, as cores RGB, juntamente com suas variações, formam qualquer outra cor que desejarmos. Por exemplo, rgb(255, 255, 0) geram a cor amarela. No site W3Schools existe uma ferramenta pra testarmos essas sobreposições. Se quiser brincar um pouco com as cores, basta clicar aqui!
Voltando à imagem do cogumelo vermelho, ao separarmos as camadas desta, obtemos:
Cada entrada da matriz de cor é chamada de pixel. O preto representa ausência de cor e o branco significa intensidade máxima daquela cor. Tons de cinza representam valores intermediários entre o branco e o preto.
Vejamos outro exemplo para tentar deixar as coisas um pouco mais claras:
As camadas separadas da imagem acima ficam da seguinte forma:
Observe que quanto mais presente é determinada cor de determinada camada na imagem, mais branca ela fica.
Agora que já sabemos que imagens são grandes matrizes sobrepostas, com números variando de 0 a 255 e, que estes números, representam a intensidades de cada cor do sistema RGB, hora de trabalhar com essas imagens utilizando o Python!
Matrizes com Python
Como imagens são matrizes, é necessário primeiro aprendermos como declarar matrizes em Python. Para isso, nada melhor que um exemplo. Considere a matriz A abaixo:
Para declarar a matriz A em Python, basta digitar o código abaixo:
Linhas iniciadas com # são comentários do código. Elas não são consideradas pelo interpretador da linguagem Python. Podemos ainda imprimir a matriz A com a função print:
Para mudar um elemento da matriz A, digamos o elemento 1 que está na linha 2 e coluna 4, basta digitar o seguinte código:
Observe que os índices (2,4) foram decrescidos em uma unidade ficando (1,3). Ao imprimir novamente a matriz A, obtemos:
A biblioteca Numpy oferece uma função já pronta para transpor matrizes. Para transpor, por exemplo, a matriz A, basta executar o código abaixo:
Outra operação interessante que, também, é possível fazer com a biblioteca Numpy é a multiplicação de matriz. Vejamos um exemplo:
Com a biblioteca Numpy é bem fácil declarar matrizes nulas, de 1’s ou identidades. Vejamos:
Acima uma matriz com 2 linhas e 3 colunas com todas as entradas iguais a 1.
Acima uma matriz nula com 2 linhas e 3 colunas.
Acima uma matriz identidade de ordem 3.
Até agora vimos matrizes que possuem linhas e colunas. Queremos também declarar as camadas! Para entender melhor essa loucura, pense num cubo mágico:
Cada camada é uma matriz! Para declarar uma matriz de 1’s com 8 linhas, 9 colunas e 3 camadas, basta digitar o código:
Estamos prontos pra criar imagens em Python!
Criando uma imagem com Python
Criaremos uma matriz 8x9x3. As primeira, segunda e terceira camadas da nossa matriz serão compostas pelas variações de tons das camadas vermelha, azul e verde, respectivamente, da imagem do cogumelo do Mário. Primeiro criaremos as camadas separadamente.
A camada vermelha fica:
A camada verde fica:
E a camada azul fica:
O comando dtype=np.float32 muda o tipo de entrada da matriz. Logo, ao invés de digitarmos números de 0 a 255, podemos digitar números de 0 a 1.
Criaremos uma matriz M nula 8x9x3 e a cada camada de M colocaremos uma das camadas RGB acima:
Para visualizar nossa imagem, utilizaremos a biblioteca Matplotlib.
Pronto! Deve aparecer o cogumelo vermelho do Mário, caso tudo tenha ocorrido bem.
Desafio:
Lendo imagens com Python
Escolha uma imagem da internet. Lembre-se de verificar os direitos de uso da imagem. Para este exemplo, a imagem que será utilizada é a rubik.jpg.
Primeiro, devemos colocar a imagem temporariamente no nosso ambiente de desenvolvimento. Para isso clique no botão indicado na figura abaixo:
Arraste o arquivo de imagem para a aba que se abriu.
Após carregar a imagem, pode fechar a aba de arquivos.
Para transformar esse arquivo de imagem em matriz, utilizaremos a biblioteca PIL. Observemos o código abaixo:
A linha 7, lê a imagem. A linha 10, transforma em matriz com valores de 0 a 1, como a que criamos quando fizemos o cogumelo. As linhas 13, 14, 15 e 16 são para visualizar a imagem. Neste exemplo, o resultado foi o seguinte:
Manipulando imagem com Python
Entendemos o que são imagens digitais, como ler essas imagens e como transformá-las em matriz. Mas nada disso é interessante se não pudermos manipular essas imagens usando propriedades de matrizes!!!
Considere a matriz M obtida ao ler a imagem do cubo mágico. Para alterar um pixel da image, basta escolher linha, coluna e camada, digamos 22, 52 e 2, respectivamente, e atribuir o novo valor, por exemplo, M[21, 51, 1] = 0.5 (lembre que diminuímos um em cada índice). No entanto, nossa imagem é composta por muitos pixels de forma que, trocar apenas um pixel, vai gerar uma resultado quase que imperceptível.
Tentaremos então trocar vários pixels de uma só vez. Para trocar todas as linhas, ou todas as colunas, usamos dois pontos “:” no lugar do respectivo índice. Por exemplo, vamos zerar a camada vermelha e a verde. Obteremos uma imagem bem azulada, uma vez que só os tons de azul ficarão:
Observe que “:” está no lugar do índice que representa linha, bem como no lugar do índice que representa coluna. Logo, estamos considerando todas as linhas e todas as colunas. Obtemos então:
Legal, já sabemos colocar filtros nas nossas fotos!!!
O comando M.shape nos diz qual a dimensão da imagem:
Logo, nossa matriz tem 519 linhas, 544 colunas e 3 camadas.
É possível alterar apenas algumas linhas. Por exemplo, da 100ª à 200ª. Para isso, trocamos o índice da linha por 99:200 (novamente, subtrai-se 1 no índice, no entanto, quando trata-se de intervalo, o último se mantém). O código, então, fica:
Obtemos o seguinte resultado:
A biblioteca Numpy tem várias funções para manipular matriz. Já vimos uma delas: a transposta! Para nosso próximo exemplo, transporemos a imagem do cubo mágico:
O resultado é o seguinte:
Por fim, trocaremos a parte de cima da imagem com a parte debaixo. Para isso executaremos os seguintes passos:
- Carrega a imagem numa matriz M e coloca no formato correto
- Cria uma matriz identidade ID para usarmos as linhas desta
- Criamos uma segunda matriz identidade DID
- Alteramos a matriz DID de acordo com nosso objetivo
- Multiplicamos DID por M para obter uma nova M
- Visualizamos o resultado
Veremos o código:
O resultado é:
Agora devemos nos perguntar: como podemos saber previamente quais operações e matrizes utilizaremos para conseguir alcançar determinado objetivo, por exemplo, trocar a parte de cima da imagem com a parte debaixo?
Bom, a maioria dessas operações e funções é estudada num curso de Álgebra Linear, bem como o que elas fazem. Inclusive, as operações que trocam linhas de matrizes são as mesmas que trocam linhas de sistemas, daqueles que resolvemos no ensino médio. Estudar álgebra linear a fundo fornecerá mais ferramentas para alcançarmos objetivos mais complexos!
Sumário
Para recapitular, vimos:
- O sistema de cor RGB
- Imagens como matrizes de cores
- Criação de matrizes em Python
- Mudança de valores de matrizes
- Transposição de matrizes
- Multiplicação de matrizes
- Criação de imagens em Python
- Leitura de imagens em Python
- Algumas manipulações de imagens em Python
Desafio
Esse desafio não é para ser fácil, mas também não é para ser impossível. Tente transformar a primeira imagem, abaixo e à esquerda, na segunda imagem, abaixo e à direita:
A imagem para esse desafio pode ser baixada aqui!
Todos os conceitos e ferramentas para completar esse desafio estão nesse post. A inversão da terceira com a quarta faixa horizontal na imagem transformada foi proposital.
Divirta-se!