Deixe-me começar este tutorial tirando alguns jargões teóricos do seu caminho. quando falamos sobre melhoria de imagemisso basicamente significa que queremos uma nova versão da imagem que seja mais adequada do que a original.
Por exemplo, quando você digitaliza um documento, a imagem de saída pode ter uma qualidade inferior à imagem de entrada original. Portanto, precisamos de uma maneira de melhorar a qualidade das imagens de saída para que elas possam ser visualmente mais expressivas para o visualizador, e é aí que entra o aprimoramento da imagem. Quando aprimoramos uma imagem, o que estamos fazendo é aguçar os recursos da imagem, como contraste e bordas.
É importante observar que o realce da imagem não aumenta o conteúdo de informação da imagem, mas sim aumenta a faixa dinâmica dos recursos escolhidos, acabando por aumentar a qualidade da imagem. Portanto, aqui realmente não sabemos como seria a imagem de saída, mas deveríamos ser capazes de dizer (subjetivamente) se houve alguma melhoria ou não, como observar mais detalhes na imagem de saída, por exemplo.
O aprimoramento de imagem é geralmente usado como uma etapa de pré-processamento nas etapas fundamentais envolvidas no processamento de imagem digital (ou seja, segmentação, representação). Existem muitas técnicas para aprimoramento de imagens, mas abordarei duas técnicas neste tutorial: imagem inversa e transformação da lei de potência. Vamos dar uma olhada em como podemos implementá-los em Python. Então vamos começar!
Imagem Inversa
Como você deve ter adivinhado pelo título desta seção (que também pode ser referido como negação de imagem), o inverso da imagem visa transformar as intensidades escuras na imagem de entrada em intensidades brilhantes na imagem de saída e as intensidades brilhantes na imagem de entrada em intensidades escuras na imagem de saída. Em outras palavras, as áreas escuras ficam mais claras e as áreas claras ficam mais escuras.
Diz isso I(i,j)
refere-se ao valor de intensidade do pixel localizado em (i,j)
. Para esclarecer um pouco aqui, os valores de intensidade na imagem em tons de cinza caem no intervalo [0,255]
e (i,j)
refere-se aos valores de linha e coluna, respectivamente. Quando aplicamos o operador inverso de imagem em uma imagem em tons de cinza, o pixel de saída O(i,j)
valor será:
Hoje em dia, a maioria das nossas imagens são imagens coloridas. Essas imagens contêm três canais, vermelho, verdee azulreferido como RGB
imagens. Neste caso, ao contrário da fórmula acima, precisamos subtrair a intensidade de cada canal de 255. Portanto, a imagem de saída terá os seguintes valores em pixel (i,j)
:
1 |
O_R(i,j) = 255 - R(i,j) |
2 |
O_G(i,j) = 255 - G(i,j) |
3 |
O-B)i,j) = 255 - B(i,j) |
Após esta introdução, vamos ver como podemos implementar o operador inverso de imagem em Python. Gostaria de mencionar que, para simplificar, executarei o operador em uma imagem em tons de cinza. Mas darei algumas ideias sobre como aplicar o operador em uma imagem colorida e deixarei o programa completo para você como exercício.
A primeira coisa que você precisa fazer para uma imagem colorida é extrair o valor de intensidade de cada canal de pixel (ou seja, RGB). Para esse propósito, você pode usar a Python Imaging Library (PIL). Vá em frente e baixe uma amostra de imagem de babuíno em baboon.png. O tamanho da imagem é 500x500
. Digamos que você queira extrair os valores de intensidade de vermelho, verde e azul localizados no local do pixel (325, 432)
. Isso pode ser feito da seguinte forma:
1 |
from PIL import Image |
2 |
|
3 |
im = Image.open('baboon.png') |
4 |
print(im.getpixel((325,432))) |
Com base na documentação, qual o método getpixel()
faz é:
Retorna o valor do pixel em uma determinada posição.
Depois de executar o script acima, você notará que obtém apenas o seguinte resultado: 138
! Mas onde estão os valores de intensidade dos três canais (RGB)? O problema parece estar com o mode
da imagem que está sendo lida. Verifique o modo executando a seguinte instrução:
Você obterá a saída P
, significando que a imagem foi lida em um modo de paleta. Uma coisa que você pode fazer é converter a imagem para o modo RGB antes de retornar os valores de intensidade dos diferentes canais. Para fazer isso, você pode usar o convert()
método, como segue:
1 |
rgb_im = im.convert('RGB') |
Nesse caso, você obteria o seguinte valor retornado: (180, 168, 178)
. Isso significa que os valores de intensidade para os canais vermelho, verde e azul são 180, 168 e 178, respectivamente.
Para juntar tudo o que descrevemos até agora, o script Python que retornaria os valores RGB de uma imagem é o seguinte:
1 |
from PIL import Image |
2 |
|
3 |
im = Image.open('baboon.png') |
4 |
rgb_im = im.convert('RGB') |
5 |
print(rgb_im.getpixel((325,432))) |
Resta um ponto antes de você avançar para o operador inverso da imagem. O exemplo acima mostra como recuperar o valor RGB de 1 pixel apenas, mas ao executar o operador inverso, você precisa fazer isso em todos os pixels.
Para imprimir todos os valores de intensidade para os diferentes canais de cada pixel, você pode fazer o seguinte:
1 |
from PIL import Image |
2 |
|
3 |
im = Image.open('baboon.png') |
4 |
rgb_im = im.convert('RGB') |
5 |
width, height = im.size |
6 |
|
7 |
for w in range(width): |
8 |
for h in range(height): |
9 |
print(rgb_im.getpixel((w,h))) |
Neste ponto, deixarei como exercício para você descobrir como aplicar o operador inverso de imagem em todos os canais de imagem colorida (isto é, RGB) de cada pixel.
Vamos dar uma olhada em um exemplo que aplica o operador inverso de imagem em uma imagem em tons de cinza. Vá em frente e baixe boat.png, que servirá como nossa imagem de teste nesta seção. Isto é o que parece:
Vou usar a biblioteca numpy para esta tarefa. O script Python para aplicar o operador inverso de imagem na imagem acima deve ter a seguinte aparência:
1 |
import cv2 |
2 |
import numpy as np |
3 |
from PIL import Image |
4 |
img = Image.open('boat.png') |
5 |
array_img = np.array(img) |
6 |
image_invert = np.invert(array_img) |
7 |
cv2.imwrite('new_boat.jpg', image_invert) |
Numpy é um pacote python usado em computação científica com Python. OpenCV-Python é uma biblioteca projetada para resolver problemas de visão computacional. O OpenCV-Python vem com o numpy, então não há necessidade de instalar o numpy se você instalar o OpenCV-Python primeiro. Primeiro abrimos a imagem com Pillow e depois a convertemos em um array numpy.
Então usamos o i do numpynvert()
função para inverter a imagem e salvar a nova imagem invertida. o invert()
função converterá branco em preto e vice-versa.
Abaixo está a imagem original à esquerda e a imagem recém-invertida à direita.
Observe que algumas características da imagem ficaram mais nítidas após a aplicação do operador. Veja, por exemplo, as nuvens e o farol na imagem à direita.
Transformação da Lei de Potência
Este operador, também chamado correção de gama, é outro operador que podemos usar para aprimorar uma imagem. Vejamos a equação do operador. no pixel (i,j)
o operador tem a seguinte aparência:
I(i,j)
é o valor de intensidade no local da imagem (i,j)
; e k
e gamma
são constantes positivas. Não entrarei em detalhes matemáticos aqui, mas acredito que você pode encontrar explicações completas sobre esse tópico em livros de processamento de imagem. No entanto, é importante observar que, na maioria dos casos, k=1
, portanto, alteraremos principalmente o valor de gamma. Assim, a equação acima pode ser reduzida a:
vou usar o OpenCV
e NumPy
bibliotecas aqui. Você pode verificar meu tutorial Apresentando o NumPy caso precise aprender mais sobre a biblioteca. Nossa imagem de teste será novamente boat.tiff (vá em frente e faça o download).
O script Python para executar o operador Power Law Transformation tem a seguinte aparência:
1 |
import cv2 |
2 |
import numpy as np |
3 |
|
4 |
im = cv2.imread('boat.tiff') |
5 |
im = im/255.0 |
6 |
im_power_law_transformation = cv2.pow(im,0.6) |
7 |
cv2.imshow('Original Image',im) |
8 |
cv2.imshow('Power Law Transformation',im_power_law_transformation) |
9 |
cv2.waitKey(0) |
Observe que o valor gama que escolhemos é 0.6
. A figura abaixo mostra a imagem original e o resultado da aplicação do operador de transformação da lei de potência nessa imagem (a imagem da esquerda mostra a imagem original e a imagem da direita mostra o resultado após a aplicação do operador de transformação da lei de potência).
O resultado acima foi quando gamma = 0.6
. Vamos ver o que acontece quando aumentamos gama para 1.5
por exemplo:
Observe que conforme aumentamos o valor de gama, a imagem fica mais escura e vice-versa.
Alguém pode estar se perguntando qual poderia ser a utilidade da transformação da lei de potência. De fato, os diferentes dispositivos usados para aquisição, impressão e exibição de imagens respondem de acordo com o operador de transformação da lei de potência. Isso se deve ao fato de que o cérebro humano usa correção gama para processar uma imagem. Por exemplo, a correção gama é considerada importante quando queremos que uma imagem seja exibida corretamente (o melhor contraste da imagem é exibido em todas as imagens) em um monitor de computador ou telas de televisão.
Conclusão
Neste tutorial, você aprendeu como aprimorar imagens usando Python. Você viu como destacar recursos usando o operador inverso da imagem e como a transformação da lei de potência é considerada um operador crucial para exibir imagens corretamente em monitores de computador e telas de televisão.