Deep Learning para Super Resolução de Imagens
Super resolução refere-se ao processo de upscaling (aumento) de imagens com melhoria de seus detalhes. Com a biblioteca Python OpenCV, isso é feito com o auxílio de modelos pré-treinados de redes neurais do tipo deep learning (aprendizado profundo).
Aumento de imagens é uma necessidade comum dos nossos tempos. Porém, nem sempre os procedimentos tradicionais de aumento geram bons resultados. Ao aumentar as dimensões de uma imagem, os píxeis extras precisam ser interpolados de alguma forma. Técnicas clássicas para aumentar imagens usam métodos como interpolação cúbica e interpolação linear. Mas essas técnicas não dão bons resultados, pois elas não contextualizam o ambiente ao redor de cada píxel durante a expansão de tamanho. Felizmente, modelos de deep learning podem ser usados para expansão de imagens com melhora de resolução. Esse processo é chamado de super resolução.
A super resolução com a biblioteca Python OpenCV aproveita modelos de aprendizado profundo para obter resultados impressionantes. OpenCV também oferece métodos tradicionais de interpolação para dimensionamento de imagens. Porém, sua super resolução com deep learning é uma alternativa mais poderosa.
Upscaling com Super Resolução
OpenCV fornece modelos de redes neurais do tipo deep learning pré-treinados projetados especificamente para tarefas de super resolução. Esses modelos são treinados em grandes conjuntos de dados de pares de imagens de baixa e alta resolução. Durante a super resolução, a imagem de baixa resolução é alimentada no modelo pré-treinado. O modelo usa seu conhecimento adquirido em seu treinamento para reconstruir uma imagem de maior resolução. A imagem melhora na resolução de seus detalhes e também é aumentada em tamanho (upscaling). Dependendo do modelo usado, ela pode ser aumentada em 2, 3, 4 e até 8 vezes.
Super resolução com OpenCV em Python
Para usar super resolução de imagens com OpenCV, precisa instalar o módulo opencv-contrib-python preferencialmente em ambiente virtual:
pip install opencv-contrib-python
Para quem já tem o OpenCV instalado, mas sem o opencv-contrib-python, a melhor opção é instalar o módulo em um ambiente virtual para evitar problemas com dependências. Ele já vem com uma versão do OpenCV embutida.
Modelos de Deep Learning para Super Resolução
Além do módulo de deep learning do OpenCV, é preciso baixar pelo menos um dos modelos pré-treinados de super resolução para poder usá-la. Existem vários modelos disponíveis que podem ser usados com o módulo de deep learning do OpenCV. Cada modelo aumenta a imagem com uma magnitude específica (2 vezes, 3 vezes, 4 vezes ou 8 vezes dependendo do modelo). Portanto, dependendo do aumento que você deseja, será preciso baixar o modelo correto. Entre os modelos disponíveis estão:
EDSR: este é o modelo com melhor desempenho. No entanto, ele também é o maior modelo e, portanto, tem inferências mais lentas. Ele pode ser baixado aqui (3x) e aqui (4x).
ESPCN: modelo pequeno, com inferências rápidas. Ele pode fazer upscaling de vídeos em tempo real (dependendo do tamanho dos frames). Ele pode ser baixado aqui (2x), aqui (3x) e aqui (4x).
FSRCNN: também é um modelo pequeno com inferências rápidas e precisas. Você pode baixá-lo aqui (2x).
LapSRN: um modelo de tamanho médio que pode aumentar imagens em até 8 vezes. Você pode baixá-lo aqui (2x), aqui (4x) e aqui (8x).
No geral, as inferências desses modelos não demoram muito. Porém, fatores como tamanho da imagem e a magnitude de aumento podem tornar o processo bem lento.
Upscaling Tradicional em Código
Para ilustrar como usar os modelos de super resolução com OpenCV, faremos uma comparação entre os resultados obtidos com eles e com um método tradicional de aumento de imagem (interpolação cubica). Veja o código abaixo, ele faz aumento de imagens com interpolação cubica tradicional:
import cv2 # importa OpenCV
img = cv2.imread('SUA_IMAGEM_AQUI') # carrega sua imagem (.png, .jpg, etc)
# interpolação cubica tradicional
scale_up_x = 4 # define taxa de aumento para largura
scale_up_y = 4 # define taxa de aumento para altura
scaled_f_up_cubic = cv2.resize(img, None, fx= scale_up_x, fy= scale_up_y, interpolation= cv2.INTER_CUBIC) # realiza upscaling com interpolação cubica tradicional
cv2.imwrite("O_NOME_DE_SUA_NOVA_IMAGEM_AQUI.png", scaled_f_up_cubic) # salva a nova imagem
Nesse código, estamos realizando um aumento de quatro vezes em uma imagem com uma técnica tradicional de interpolação.
Super Resolução em Código com EDSR
Para usar super resolução com deep learning, o código pode ser escrito assim:
from cv2 import dnn_superres
img = cv2.imread('SUA_IMAGEM_AQUI') # carrega sua imagem (.png .jpeg, .jpg, etc)
sr = dnn_superres.DnnSuperResImpl_create() # cria objeto para super resolução
path = "EDSR_x4.pb" # define o modelo de deep learning, o modelo precisa estar na mesma pasta que seu código ou você precisa inserir a path correta
sr.readModel(path) # carrega modelo no objeto para super resolução
sr.setModel("edsr",4) # define o modelo no objeto para super resolução e especifica o tamanho do aumento que deve ser feito (4 vezes no exemplo)
result = sr.upsample(img) # aplica modelo na imagem
cv2.imwrite("NOME_DA_SUA_NOVA_IMAGEM.png", result) # salva nova imagem
Neste exemplo, o modelo de super resolução usado foi o EDSR com aumento de 4 vezes. Para usar outros modelos, o código é exatamente igual, mas precisa mudar o modelo especificado (linhas 6 e 8 acima) e o número do aumento (linha 8 acima). Veja alguns exemplos abaixo comparando interpolação tradicional com EDSR. Estamos mostrando apenas uma parte das imagens aumentadas por que os arquivos são muito grandes.
Super Resolução em Código com LapSRN
Mais um exemplo de como usar super resolução, agora para um aumento de 8 vezes no tamanho original da imagem. Para realizar esse aumento, o modelo que precisa ser usado é o LapSRN (LapSRN_8x). Um exemplo de como utilizá-lo em código é mostrado abaixo. O código é equivalente ao mostrado anteriormente para o EDSR.
# para super resolução
from cv2 import dnn_superres
img = cv2.imread('SUA_IMAGEM_AQUI') # carrega sua imagem (.png .jpeg, .jpg, etc)
sr = dnn_superres.DnnSuperResImpl_create() # cria objeto para super resolução
path = "LapSRN_x8.pb" # define o modelo de deep learning
sr.readModel(path) # carrega o modelo
sr.setModel("lapsrn",8) # define o modelo no objeto para super resolução e especifica o tamanho do aumento que deve ser feito (8 vezes)
result = sr.upsample(img) # aplica modelo na imagem
cv2.imwrite("NOME_DA_SUA_NOVA_IMAGEM.png", result) # salva nova imagem
E aqui está um exemplo de resultado obtido com esse modelo em comparação com interpolação tradicional. As imagens são mostradas apenas parcialmente porque os arquivos são muito grandes para internet.