Code Monkey home page Code Monkey logo

inpainting's Introduction

Inpainting

Introdução

Inpainting é o processo de reconstrução digital de partes perdidas ou deterioradas de imagens e vídeos, também conhecida como interpolação de imagens e vídeos. Refere-se à aplicação de algoritmos sofisticados para substituir partes perdidas ou corrompidas da imagem (principalmente pequenas regiões ou para remover pequenos defeitos).

Nesse projeto estudamos e implementamos técnicas de inpainting para a remoção automática de rabiscos inseridos artificialmente em imagens. Para realizarmos a detecção automática da região que devemos fazer inpainting usamos do fato de que os rabiscos são feitos com cores contrastantes que ocorrem com alta frequência nas imagens.

Aplicamos os métodos utilizados para a remoção de objetos em imagens também. Para isso é necessário desenhar em cima do objeto a ser removido com um pincel duro com uma cor contrastante como, por exemplo, o vermelho (255, 0, 0).

Conjunto de imagens

Parte do conjunto de imagens utilizado é apresentado abaixo. Todas as imagens utilizadas estão no formato Bitmap (.bmp) e estão organizadas na pasta images/.

Imagens Originais

As imagens abaixo estão em sua forma original.

dogo2 horse_car forbes momo_fino
Cachorro (retirada da internet) Texto em foto (retirada de um artigo) Forbes Professor Moacir

Imagens Deterioradas

As imagens abaixo foram rabiscadas artificialmente. A única imagem que não inserimos rabiscos foi a segunda imagem, que foi retirada de um artigo.

dogo2 horse_car forbes momo_fino
Cachorro (retirada da internet) Texto em foto (retirada de um artigo) Forbes Professor Moacir

Algoritmos de extração da máscara

O primeiro passo para realizar inpainting é definir a região deteriorada. Para isso implementamos dois métodos simples para extrair a máscara automaticamente. Para essa etapa do trabalho queremos realizar inpainting em cores específicas, ou seja, assumimos como sendo parte da região deteriorada todos os pixels que possuem certas cortes determinadas pelos métodos descritos a seguir.

O primeiro passo de ambos os métodos é calcular o número de ocorrências de cada tripla de cor RGB. Optamos por ignorar cores muito próximas do branco absoluto (255, 255, 255) pois alguns dos experimentos foram feitos com imagens com excesso de luz. Ignoramos então as cores que possuem valor maior ou igual a 250 nos três canais.

Vale notar que os métodos podem ser melhorados para que a máscara obtida represente não só algumas cores pré-determinadas pelos métodos, mas que represente também a "penumbra" que muitas ferramentas de edição inserem nas bordas dos traços. Para isso podemos extrair a máscara usando os métodos abaixo e depois preencher todos os pixels não preenchidos adjacentes a um ou mais pixels preenchidos que possuem um tom parecido, utilizando uma certa medida de distância. Para esse projeto tentamos usar uma medida de distância usando os canais H e S do espaço de cores HSV, mas, como não obtivemos muita precisão, optamos por usar apenas riscos "duros" no projeto para focar na parte principal: o Inpainting.

momo momo
Foto deteriorada Máscara extraída

Most Frequent

Nesse método assumimos que apenas uma cor deve ser removida: a mais frequente. Esse método funciona muito bem quando existe rabiscos de apenas uma cor.

Minimum Frequency

Nesse método definimos um threshold e assumimos que todas as cores que ocorrem mais vezes do que esse threshold fazem parte da região de inpainting. Para essa etapa definimos o threshold como sendo 1% dos pixels da imagem, ou seja, se alguma cor ocorrer em mais do que 1% da imagem, ela é considerada "rabisco". Esse método não funciona tão bem quando existe rabiscos de apenas uma cor, mas é um método necessário para remover rabiscos de diferentes cores.

Red

Nesse método a máscara será composta por todos os pixels vermelhos (255, 0, 0). Esse método é importante para melhorar a precisão da extração da máscara para a aplicação extra do projeto de remover objetos indesejados. Para isso basta o usuário pintar de vermelho (255, 0, 0) os objetos que deseja remover da imagem.

Algoritmos de Inpainting

Gerchberg Papoulis

O algoritmo Gerchberg-Papoulis é um algoritmo de inpaiting por difusão que funciona por meio de cortes nas frequencias obtidas pela Transformada Discreta de Fourier (DFT), zerando parte das frequências das imagens.

Considerando uma Máscara M que possui valor 0 nos locais em que a imagem é conhecida e 255 nas regiões deterioradas, o algoritmo com T iterações é aplicado da seguinte maneira:

  1. g_0 = Imagem inicial
  2. Obtenção da DFT de M.
  3. Para cada iteração k = 1, ..., T
    • G_k = DFT de g_{k-1}
    • Filtra G_k zerando coeficientes das frequências relativos a:
      • G_k >= 0.9 * max(M)
      • G_k <= 0.01 * max(G_k)
    • Convolução de G_k com um filtro de média k x k.
    • g_k = IDFT de G_k
    • Normalização de G_k entre 0 e 255.
    • Inserção dos pixels de gk somente na região referente a máscara.
      • g_k = (1 - M/255) * g_0 + (M/255) * g_k

Ao final do processo é obtida a imagem G_k restaurada.

Abaixo estão alguns dos resultados do algoritmo.

dogo2 horse_car forbes momo_fino
Cachorro (retirada da internet) Texto em foto (retirada de um artigo) Forbes Professor Moacir

Inpainting por exemplos

Os algoritmos de Inpainting por exemplos utilizados consistem em substituir cada pixel deteriorado Pd por um pixel não deteriorado P cuja janela KxK centrada em P maximiza uma certa medida de similaridade em relação a janela KxK centrada em Pd.

O K é definido automaticamente levando em consideração a "grossura" do rabisco da seguinte forma: Para cada pixel deteriorado Pd calcula-se sua distância de Manhattan para o pixel não-deteriorado mais próximo usando uma Multi-Source Breadth-First Search. Ao recuperar o máximo de todos esses valores, multiplica-lo por 2 e somar 3, obtemos um valor para K grande o suficiente para a região deteriorada nunca conter completamente uma janela KxK.

A medida de distância utilizada foi similar ao RMSE, mas calculado apenas entre pixels não-deteriorados. Vale dizer que para todo o projeto assumimos que os pixels fora da imagem são pretos (0, 0, 0).

Brute Force

Nesse algoritmo a busca pelo pixel P é feita em toda a imagem. Seu tempo de execução é altíssimo e, portanto, apenas conseguimos rodar para as imagens dogo1.bmp (100x100), dogo2.bmp (400x400), momo_fino.bmp (280x280) e momo.bmp (280x280).

dogo1 dogo2 momo_fino momo
Cachorro 100x100 reconstruído Cachorro 400x400 reconstruído Moacir com rabiscos finos reconstruído Moacir com rabiscos grossos reconstruído

Local Brute Force

Nesse algoritmo fazemos a suposição de que as janelas mais similares não estão muito longe da região deteriorada, portanto a busca pelo pixel P é feita apenas em uma região 101x101 centrada em Pd. Isso permite que façamos inpainting em imagens maiores em tempo hábil, como a imagem abaixo.

forbes forbes
Forbes 961x1280 deteriorado Forbes 961x1280 reconstruído

Local Dynamic Brute Force

Aprimorando um pouco a ideia do Brute Force Local, percebemos que atribuir a média entre os pixels cuja janela KxK mais se assemelham a janela do pixel Pd reduz o RMSE e resulta, em geral, em restaurações mais suaves. Usamos os 5 mais semelhantes para imagens menores e os 10 mais semelhantes para imagens maiores.

Além disso, ao começarmos a tentar remover rabiscos mais grossos ou objetos maiores observamos que poderíamos usar um valor de K dinâmico, ou seja, um valor de K para cada pixel deteriorado Pd com o objetivo de obter janelas mais representativas e reduzir o tempo de execução. Esse método se mostrou especialmente útil em máscaras mais grossas, ou seja, máscaras que produzem um valor de K elevado nos outros métodos.

A imagem abaixo é um bom exemplo da utilidade do K dinâmico, pois podemos ver que as regiões "deterioradas" são "grossas". Para as bordas dessas regiões o K usado é menor, o que reduz o tempo de execução.

forbes forbes forbes forbes
Forbes-Perfil 934x1280 original Forbes-Perfil 934x1280 "deteriorado" Forbes-Perfil 934x1280 máscara Forbes-Perfil 934x1280 restaurado

Smart Brute Force

Nesse algoritmo rodamos uma Depth-First Search (DFS) a partir de cada componente conexa de pixels deteriorados. Para o primeiro pixel deteriorado Pd de uma componente fazemos a busca pelas 50 janelas KxK mais similares em uma região 101x101 centrada em Pd e guardamos em uma lista de candidatos. Passamos essa lista para os vizinhos de Pd de tal forma que os vizinhos precisem apenas calcular a distância para 50 janelas na maior parte das vezes. Quando a janela mais similar ao pixel atual não for tão similar (sua distância é maior que um threshold que definimos como sendo 5.0 para a maioria das imagens), buscamos uma lista com os 50 melhores candidatos novamente. Por fim atribuímos a cada pixel deteriorado a média dos 5 pixels cujas janelas são as mais similares dentre os candidatos.

A suposição feita para o desenvolvimento desse algoritmo se deve ao fato de que pixels deteriorados vizinhos devem ser similares entre si e, portanto, similares a uma mesma lista de candidatos.

Podemos ver pela imagem horse_car.bmp que usar o pixel cuja janela KxK possui distância mínima não é sempre a melhor escolha. A média entre os 5 melhores candidatos resulta em um inpainting mais suave, removendo parte do ruído produzido pelos outros métodos de força bruta descritos.

|horse_car_deteriorated| horse_car_mask| horse_car_local| horse_car_smart| |------------|------------|------------|------------| | Imagem deteriorada | Máscara | Local Brute Force | Smart Brute Force |

Resultados

Para o problema de remoção de rabiscos a avaliação dos resultados foi feita, além de visualmente, pela raiz do erro quadrático médio (RMSE) calculado apenas nos pixels da região deteriorada e a partir de imagens geradas representando a diferença entre as imagens originais e as imagens restauradas. Quanto ao problema de remoção de objetos indesejados a avaliação se deu apenas visualmente.

Remoção de rabiscos em imagens

Em geral observamos que os melhores resultados vieram do algoritmo Smart Brute Force enquanto os piores resultados vieram do Gerchberg Papoulis, visto que esse gera regiões visivelmente mais borradas (apesar de possuir o tempo de execução mais baixo) principalmente para imagens com vários detalhes como rostos. Podemos ver a diferença dos resultados entre esses dois algoritmos na imagem do Professor Moacir (momo.bmp) de dimensões 280x280:

|momo_inpainted_brute| momo_diff_brute| momo_inpainted_gerchberg| momo_diff_gerchberg| |------------|------------|------------|------------| | Smart Brute Force | Imagem da diferença Smart Brute Force | Gerchberg Papoulis | Imagem da diferença Gerchberg Papoulis |

Comparação do RMSE e do tempo de execução para esses algoritmos:

Algoritmo RMSE Tempo
Smart Brute Force 21.352 01m57s
Gerchberg Papoulis 45.094 00m05s

As tabelas abaixo sumarizam os resultados obtidos na remoção dos rabiscos para cada algoritmo.

Brute Force

Imagem RMSE Tempo
dogo1.bmp (100x100) 08.340 00m07s
dogo2.bmp (400x400) 13.222 32m19s
momo.bmp (280x280) 23.721 30m24s
momo_fino.bmp (280x280) 13.735 06m50s

Local Brute Force

Imagem RMSE Tempo
dogo1.bmp (100x100) 08.340 00m05s
dogo2.bmp (400x400) 12.456 01m50s
momo.bmp (280x280) 23.456 03m23s
momo_fino.bmp (280x280) 14.350 00m47s
horse_car.bmp (438x297) 25.752 10m11s
forbes.bmp (961x1280) 09.140 19m07s

Local Dynamic Brute Force

Imagem RMSE Tempo
dogo1.bmp (100x100) 06.646 00m03s
dogo2.bmp (400x400) 12.014 00m52s
momo.bmp (280x280) 21.288 01m14s
momo_fino.bmp (280x280) 13.644 00m34s
horse_car.bmp (438x297) 23.660 04m38s
forbes.bmp (961x1280) 06.964 07m21s

Smart Brute Force

Imagem RMSE Tempo
dogo1.bmp (100x100) 07.198 00m03s
dogo2.bmp (400x400) 11.384 00m36s
momo.bmp (280x280) 21.102 02m55s
momo_fino.bmp (280x280) 12.567 00m24s
horse_car.bmp (438x297) 20.614 07m48s
forbes.bmp (961x1280) 08.533 06m10s

Gerchberg Papoulis

Imagem RMSE Tempo
dogo1.bmp (100x100) 29.460 00m01s
dogo2.bmp (400x400) 23.039 00m09s
momo.bmp (280x280) 45.094 00m05s
momo_fino.bmp (280x280) 30.238 00m05s
horse_car.bmp (438x297) 43.221 00m09s
forbes.bmp (961x1280) 20.856 01m31s

Em seguida apresentamos alguns dos melhores resultados com comparativos visuais.

Cachorro 100x100 (dogo1.bmp)

O algoritmo Local Dynamic Brute Force obteve o melhor resultado com 6.646 de RMSE e um tempo de execução de 3 segundos.

dogo1_original dogo1_deteriorated dogo1_dynamic dogo1_diff
Original Deteriorada Restaurada Diferença

Cachorro 400x400 (dogo2.bmp)

O algoritmo Smart Brute Force obteve o melhor resultado com 11.384 de RMSE e um tempo de execução de 36 segundos.

dogo2_original dogo2_deteriorated dogo2_smart dogo2_diff
Original Deteriorada Restaurada Diferença

Moacir 280x280 (momo.bmp) - Rabiscos Grossos

O algoritmo Smart Brute Force obteve o melhor resultado com 21.102 de RMSE e um tempo de execução de 2 minutos e 55 segundos.

momo_original momo_deteriorated momo_smart momo_diff
Original Deteriorada Restaurada Diferença

Moacir 280x280 (momo_fino.bmp) - Rabiscos Finos

O algoritmo Smart Brute Force obteve o melhor resultado com 12.567 de RMSE e um tempo de execução 24 segundos.

momo_fino_original momo_fino_deteriorated momo_fino_smart momo_fino_diff
Original Deteriorada Restaurada Diferença

Charrete 438x297 (horse_car.bmp)

O algoritmo Smart Brute Force obteve o melhor resultado com 20.614 de RMSE e um tempo de execução 7 minutos e 48 segundos.

horse_car_original horse_car_deteriorated horse_car_smart horse_car_diff
Original Deteriorada Restaurada Diferença

Forbes 961x1280 (forbes.bmp)

O algoritmo Local Dynamic Brute Force obteve o melhor resultado com 6.964 de RMSE e um tempo de execução 7 minutos e 21 segundos.

forbes_original forbes_deteriorated forbes_dynamic forbes_diff
Original Deteriorada Restaurada Diferença

Remoção de objetos em imagens

Abaixo estão os resultados do uso de Inpainting para a remoção de objetos de imagens. Os tempos de execução para cada algoritmo estão apresentados abaixo:

Local Dynamic Brute Force

Imagem Tempo
forbes_profile.bmp 02m43s
gabi_star.bmp 00m31s
team.bmp 01m42s
mike.bmp 11m47s
praia.bmp 11m53s
zoo.bmp 02m15s

Smart Brute Force

Imagem Tempo
forbes_profile.bmp 01m42s
gabi_star 02m11s
team.bmp 18m40s
mike.bmp 73m06s
praia.bmp 77m31s
zoo.bmp 11m47s

Para cada imagem é apresentada a imagem original a imagem com adição de vermelho (255, 0, 0) por cima da região indesejada e o resultado mais satisfatório obtido por algum dos algoritmos.

Remoção de marcas na pele 934x1280 (forbes_profile.bmp)

|forbes_profile_original| forbes_profile_deteriorated| forbes_profile_inpainted_brute| |------------|------------|------------| | Original | "Deteriorada" | Local Dynamic Brute Force |

Remoção do PI 972x648 (gabi_star.bmp)

|gabi_star_original| gabi_star_deteriorated| gabi_star_smart| |------------|------------|------------| | Original | "Deteriorada" | Smart Brute Force |

Remoção do colar 810x540 (team.bmp)

|team_original| team_deteriorated| team_smart| |------------|------------|------------| | Original | "Deteriorada" | Smart Brute Force |

Remoção da tatuagem no rosto 769x1024 (mike.bmp)

|mike_original| mike_deteriorated| mike_smart| |------------|------------|------------| | Original | "Deteriorada" | Smart Brute Force |

Remoção das bicicletas da praia 1210x1613 (praia.bmp)

|praia_original| praia_deteriorated| praia_smart| |------------|------------|------------| | Original | "Deteriorada" | Smart Brute Force |

Remoção da pessoa em frente ao zoológico 625x394 (zoo.bmp)

|zoo_original| zoo_deteriorated| zoo_smart| |------------|------------|------------| | Original | "Deteriorada" | Smart Brute Force |

Obtivemos ótimos resultados com os algoritmos de Inpainting por exemplos para a remoção de rabiscos e de objetos maiores. Apesar disso percebemos que esses algoritmos não lidam muito bem com contornos e texturas (como podemos reparar pela imagem da praia) como os métodos descritos nesse artigo do Bertalmio.

É notável a importância de algoritmos e códigos eficientes para reduzir o tempo de execução dos métodos de Inpainting por exemplos. Podemos concluir que os resultados foram satisfatórios e que a maioria dos objetivos foram cumpridos, com exceção da extração de máscaras de imagens com rabiscos com cores não "duras".

Instruções para execução do código

O algoritmo de Gerchberg Papoulis foi implementado em Python 3 com Numpy e ImageIO, enquanto os algoritmos de Inpainting por exemplos foram implementados em C++ com OpenCV para obter tempos de execução menores.

A imagem de entrada deve estar na pasta project/images/deteriorated/, a máscara será salva em project/images/masks/ e a imagem de saída na pasta project/images/deteriorated/<inpainting_algorithm>/.

A compilação do código em C++ foi feita utilizando o cmake com o arquivo CMakeLists.txt, então para gerar o Makefile e compilar o executável é preciso executar os comandos dentro da pasta Project:

cmake .
make

A execução do código em C++ é feita pelo comando:

./main <image_in.bmp> <image_out.bmp> <mask_extraction_algorithm> <inpainting_algorithm> (compare)?

É possivel também executar somente a comparação, utilizando o comando:

./main compare <path/original.bmp> <path/inpainted.bmp> <path/mask.bmp>

A execução do código em Python é feita pelo comando:

python3 main.py <image_in.bmp> <image_out.bmp> <mask_extraction_algorithm> (compare)?

O código em Python contém apenas a implementação do algoritmo Gerchberg Papoulis, por isso não é necessário escolher o algoritmo de inpainting.

Os argumentos são:

  • <image_in.bmp> - Nome da imagem de entrada.
  • <image_out.bmp> - Nome da imagem de saída.
  • <mask_extraction_algorithm> - Algoritmo de extração da máscara (most_frequent, minimum_frequency ou red).
  • <inpainting_algorithm> - Algoritmo de inpainting (brute, local, dynamic ou smart).
  • (compare) - Opcional. Realiza a comparação entre a imagem original, se houver, e a imagem restaurada produzindo o RMSE e a imagem da diferença.

Por exemplo, se quisermos executar o Local Brute Force para remover rabiscos de múltiplas cores da imagem dogo2.bmp e obter uma avaliação dos resultados (RMSE e imagem da diferença) basta colocar a imagem na pasta images/deteriorated/ e executar o comando:

./main dogo2.bmp dogo2.bmp minimum_frequency local compare

Após a execução a máscara é salva em images/masks/dogo2.bmp, a imagem restaurada é salva em images/inpainted/Local Brute Force/dogo2.bmp e a imagem da diferença é salva em images/difference/Local Brute Force/dogo2.bmp.

Outro exemplo seria executar o Local Dynamic Brute Force para remover marcas na pele na imagem forbes_profile.bmp. Para isso podemos pintar as marcas de pele com a cor vermelho (255, 0, 0), colocar essa imagem na pasta images/deteriorated/ e executar o comando:

./main forbes_profile.bmp forbes_profile.bmp red dynamic

Após a execução a máscara é salva em images/masks/forbes_profile.bmp e a imagem sem as marcas de pele é salva em images/inpainted/Local Dynamic Brute Force/forbes_profile.bmp.

OBS.: Apesar do cálculo do RMSE e da imagem da diferença não terem significado para a avaliação dos resultados para a aplicação de remoção de objetos ainda é possível fazê-los usando a diretiva compare.

inpainting's People

Contributors

victorxjoey avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.