Manipulação de Imagens com Python e OpenCV - Parte 1

Nesta série, dividida em 2 partes, iremos construir uma aplicação completa para aplicar filtros em uma imagem. Na primeira parte iremos utilizar as técnicas de manipulação para desenvolver os filtros que serão aplicados às imagens, tudo isso utilizando Python e OpenCV.

Manipulação de Imagens com Python e OpenCV - Parte 1
python-opencv

Nesta série, dividida em 2 partes, iremos construir uma aplicação completa onde será possível fazer o upload de uma imagem e aplicar diferentes filtros de uma maneira fácil e rápida.

Na primeira parte iremos utilizar as técnicas de manipulação para desenvolver os filtros que serão aplicados às imagens, tudo isso utilizando Python e OpenCV.

Atualização: na parte 2 construiremos uma aplicação utilizando o Streamlit onde o usuário poderá realizar o upload de uma imagem e selecionar o filtro que deseja aplicar.

OpenCV

O OpenCV é uma biblioteca open-source de visão computacional, multiplataforma e otimizada para aplicações em tempo real.

Com o OpenCV é possível desde criar imagens do zero até realizar diferentes tipos de manipulações em imagens existentes - redimensionar, escurecer, borrar, aumentar a nitidez, dar efeitos de movimento, aplicar máscaras, etc. - de uma maneira simples e rápida.

Em nossos exemplos utilizamos o Google Colab que já vem com o OpenCV instalado. No entanto, para conseguir realizar os exemplos utilizando seu editor de preferência, será necessário primeiro instalar o opencv-python.

pip install opencv-python

E importar a biblioteca

import cv2

Aplicando filtros

Em visão computacional, é muito comum precisarmos aplicar filtros a imagens, seja para reduzir ruídos ou para evidenciar alguma característica específica.

Para atingirmos esse efeito utilizamos uma operação chamada de convolução. A convolução consiste em "passar" uma matriz (filtro) através dos pixels de uma imagem. Como resultado dessa operação, teremos uma nova imagem com o efeito desejado (embaçar, deixar mais nítida etc.).

Nesse artigo iremos focar, nas transformações de efeito nas imagens, tais como manipular o brilho - deixando a imagem mais clara ou escura -, aplicar um efeito de embaçado (blurring), melhorar a nitidez (sharpening).

Alterando brilho

A primeira transformação, e a mais simples, que iremos realizar será aumentar/diminuir o brilho de uma imagem. Para isso iremos criar um "filtro" com as mesmas dimensões da imagem alvo.

# utilizando o ones do numpy para criar o filtro
filter_1 = np.ones(reduced_image.shape, dtype=np.uint8) * 110

Nosso filter_1 nada mais é que uma matriz com o mesmo tamanho da imagem composta de valores numéricos = 110. Como o filtro tem o mesmo tamanho da imagem, podemos aumentar o brilho somando os valores do filtro a cada pixel da imagem.

# clarear
sum = cv2.add(reduced_image, filter_1)

# exibir a imagem
# no python
#cv2.imshow(sum)

# no google colab.
cv2_imshow(sum)

Conseguimos o efeito contrário se realizarmos a operação de subtração

# escurecer
sub = cv2.subtract(reduced_image, filter_1)

# exibir a imagem
# no python
#cv2.imshow(sub)

# no google colab.
cv2_imshow(sub)
Resultado do processamento das imagens

Embaçando (Blur)

O segundo filtro (kernel) que utilizaremos como exemplo é o blur e suas variações - gaussian blur e motion blur - esse filtro utiliza as operações de convolução ao aplicar uma matriz sobre a imagem.

# criando o kernel
kernel_blur = np.ones((3, 3), np.float32) / 9

# aplicando o filtro
blurred = cv2.filter2D(reduced_image, -1, kernel_blur)

# mostranto a imagem com filtro
# no python
#cv2.imshow(blurred)

# no google colab
cv2_imshow(blurred)

Nesse exemplo, criamos uma matriz 3x3 com valores 1/3 e aplicamos sobre a imagem utilizando o comando filter2D do OpenCV. Quanto menores forem os valores mais borrada a imagem ficará.

Por ser um filtro amplamente utilizado, o OpenCV já possui um método para aplicar o filtro Gaussian Blur de maneira bem simples:

# utilizando o GaussianBlur, que já é implementado no OpenCV
gaussian_blurred = cv2.GaussianBlur(reduced_image, (5, 5), 0)

# visualizando a imagem
# no python
# cv2.imshow(gaussian_blurred)

# no colab
cv2_imshow(gaussian_blurred)

Para aplicar o Motion Blur iremos, primeiro criar uma matriz 15x15 preenchida com zeros, em seguida iremos preencher com o valor 1 todas as colunas da sétima linha dessa matriz, por fim dividimos todos os valores por 15 e aplicamos sobre nossa imagem:

# implementando o filtro
kernel_motion_blur = np.zeros((15,15))
kernel_motion_blur[7, :] = np.ones(15)
kernel_motion_blur = kernel_motion_blur / 15

# aplicando o filtro
motion_blurred = cv2.filter2D(reduced_image, -1, kernel_motion_blur)

# plotando a imagem
# no python
#cv2.imshow(motion_blurred)

# no colab
cv2_imshow(motion_blurred)

Os resultados podem ser vistos na imagem abaixo:

Comparativo de "blurs"

Sharpening (afiando a imagem)

O objetivo do filtro de sharpening é melhorar a nitidez da imagem, normalmente esse filtro é usando quando se quer destacar os limites (edges) da imagem. Existem diversas maneiras de realizar esse filtro, o mais comum é utilizar uma matriz 3x3 com um centro positivo 9 e os demais pontos com valor -1.

Utilizamos novamente o comando filter2D para aplicar nosso filtro sobre a imagem.

# criando o filtro de sharpening
kernel_sharpening_1 = np.array([[-1, -1, -1],
                                [-1, 9, -1],
                                [-1, -1, -1]])

# implementando o filtro
sharpened = cv2.filter2D(reduced_image, -1, kernel_sharpening_1)

# mostrando a imagem
# no python
# cv2.imshow(sharpened)

# no colab
cv2_imshow(sharpened)

Podemos ver o resultado na imagem abaixo:

Filtro sharpening

Conclusão

Chegamos ao fim da parte 1 dessa série. Nos concentramos nos principais conceitos e comandos básicos do OpenCV, que servirão de base para o desenvolvimento da nossa aplicação utilizando o Streamlit.

Por ser uma introdução, os filtros aqui demonstrados não são os únicos nem os melhores para todos os casos possíveis, apesar de serem os mais utilizados para a maioria dos problemas simples.

Podemos encontrar diversos outros filtros na literatura que serão mais indicados para casos específicos.

Mais detalhes sobre as implementações dos filtros e outras funções do OpenCV podem ser vistas aqui.