Ferramentas do usuário

Ferramentas do site


prog2:processamento_de_imagens

Diferenças

Aqui você vê as diferenças entre duas revisões dessa página.

Link para esta página de comparações

Ambos lados da revisão anterior Revisão anterior
prog2:processamento_de_imagens [2019/04/09 13:48]
maziero
prog2:processamento_de_imagens [2019/05/13 18:47] (atual)
maziero [Atividade]
Linha 1: Linha 1:
 +====== Processamento de Imagens ======
 +
 +O processamento digital de imagens usa intensivamente vetores e matrizes. Uma imagem é geralmente representada como uma matriz de pixels, onde cada pixel é descrito por um ou mais valores inteiros que indicam seus níveis de cor ou de luminosidade. Por isso, processar imagens é uma ótima forma de exercitar o uso de matrizes.
 +
 +===== O formato PGM =====
 +
 +Para facilitar a leitura e escrita dos arquivos de imagem, neste projeto será adotado o formato de imagem ​ [[https://​en.wikipedia.org/​wiki/​Netpbm_format|Portable Gray Map]] (PGM), um formato de imagem em **níveis de cinza** bem simples e fácil de ler/​escrever. Boa parte dos programas de tratamento de imagens reconhece o formato PGM.
 +
 +Eis um exemplo de imagem no formato PGM:
 +
 +<code pgm feep.pgm>​
 +P2
 +# this is a PGM image
 +24 7
 +15
 +0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
 +0  3  3  3  3  0  0  7  7  7  7  0  0 11 11 11 11  0  0 15 15 15 15  0
 +0  3  0  0  0  0  0  7  0  0  0  0  0 11  0  0  0  0  0 15  0  0 15  0
 +0  3  3  3  0  0  0  7  7  7  0  0  0 11 11 11  0  0  0 15 15 15 15  0
 +0  3  0  0  0  0  0  7  0  0  0  0  0 11  0  0  0  0  0 15  0  0  0  0
 +0  3  0  0  0  0  0  7  7  7  7  0  0 11 11 11 11  0  0 15  0  0  0  0
 +0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
 +</​code>​
 +
 +<note important>​
 +Existem duas variantes do formato PGM: //PGM plain// (P2) e //PGM raw// (P5); **ambas** devem ser lidas pelos filtros implementados neste projeto. Mais detalhes sobre essas variantes podem ser obtidas [[http://​netpbm.sourceforge.net/​doc/​pgm.html|nesta página]].
 +</​note>​
 +
 +Alguns exemplos de imagens no formato PGM para usar no projeto:
 +
 +  * {{imagens.tar.gz|Imagens selecionadas}}
 +  * [[http://​people.sc.fsu.edu/​~jburkardt/​data/​pgma/​pgma.html|Muitos outros exemplos]]
 +
 +===== Filtros de imagem =====
 +
 +Este projeto visa construir filtros simples para imagens digitais em níveis de cinza, no formato PGM (P2 e P5) com pixels de 8 bits (1 byte).
 +
 +==== Filtro negativo ====
 +
 +O filtro negativo consiste em converter cada pixel da imagem em seu complemento. Sendo //max// o valor máximo para um pixel na imagem, o complemento de um pixel com valor //v// seria //max-v//.
 +
 +Forma de chamada:
 +
 +  pgmnega -i input -o output
 +
 +Exemplo de entrada e de saída:
 +
 +{{lena-original.png|}}
 +{{lena-negative.png|}}
 +
 +/*
 +
 +==== Filtro de rotação ====
 +
 +O filtro de rotação gira uma imagem em 90° no sentido horário. ​
 +
 +Forma de chamada:
 +
 +  pgmrotacao -i input -o output
 +
 +Exemplo de entrada e de saída:
 +
 +{{lena-original.png|}}
 +{{lena-rotate.png|}}
 +
 +*/
 +
 +==== Filtro de rotação ====
 +
 +O filtro de rotação gira uma imagem em um ângulo θ (>0) no sentido **horário**,​ em relação ao seu centro (vide [[https://​en.wikipedia.org/​wiki/​Rotation_matrix#​In_two_dimensions|rotação de imagens 2D]]).
 +
 +Requisitos:
 +
 +  * O tamanho da imagem de saída deve ser ajustado para **não cortar os cantos** da imagem.
 +  * Os espaços vazios gerados pela rotação devem ser **preenchidas com a cor branca**.
 +  * O ângulo de rotação é informado pela opção ''​-a'';​ se não for informado, por default θ = 90º.
 +
 +Forma de chamada:
 +
 +  pgmrotacao -a N -i input -o output
 +
 +Exemplo de entrada e de saída para θ = 30º:
 +
 +{{lena-original.png|}}
 +{{lena-rotate-30.png|}}
 +
 +/*
 +==== Filtro de limiar ====
 +
 +O filtro de limiar ([[https://​en.wikipedia.org/​wiki/​Thresholding_%28image_processing%29|threshold filter]]) converte uma imagem em tons de cinza em um imagem em preto-e-branco (2 cores). A forma mais simples de fazer isso é comparar o valor de cada pixel com um limiar pré-definido:​ se o valor do pixel for igual ou superior ao limiar, ele vira branco (//​v=max//​),​ caso contrário ele vira preto (//​v=0//​). ​
 +
 +Forma de chamada:
 +
 +  pgmlimiar -l N -i input -o output
 +
 +onde //N// é um limiar real entre 0.0 (0% do valor máximo) e 1.0 (100% do valor máximo). Caso o limiar não esteja definido, assume-se que seja 50%.
 +
 +Exemplo de entrada e de saídas com limiar de 50% e 75%:
 +
 +{{lena-original.png?​200|}}
 +{{lena-threshold-50.png?​200|}}
 +{{lena-threshold-75.png?​200|}}
 +
 +*/
 +
 +/*
 +==== Filtro de redução de ruído pela média ====
 +
 +O filtro da média é usado para para "​limpar"​ uma imagem, ou seja, reduzir o seu nível de ruído. O algoritmo é básico bem simples: para cada pixel, seu valor deve ser substituído pela média de todos os 9 pixels vizinhos (incluindo ele mesmo).
 +
 +Deve ser tomado cuidado especial ao tratar os pixels nas primeiras e últimas linhas ou colunas, pois eles não têm todos os vizinhos. Nesses casos, devem ser considerados no cálculo somente os vizinhos existentes.
 +
 +<note important>​
 +A imagem processada deve ser armazenada em uma segunda matriz, para que não se misturem valores novos e velhos no cálculo dos pixels.
 +</​note>​
 +
 +Forma de chamada:
 +
 +  pgmmedia -i input -o output
 +
 +Exemplo de entrada e de saída:
 +
 +{{ballons-original.png|}}
 +{{ballons-average.png|}}
 +
 +*/
 +
 +==== Filtro da mediana ====
 +
 +O [[https://​en.wikipedia.org/​wiki/​Median_filter|filtro da mediana]] reduz o nível de ruído de uma imagem sem prejudicar muito sua nitidez. Este filtro consiste basicamente em substituir o valor de um pixel pelo valor da [[https://​pt.wikipedia.org/​wiki/​Mediana_%28estat%C3%ADstica%29|mediana]] de seus pixels vizinhos. O número de vizinhos a considerar é definido por uma **máscara**,​ ou seja, a matriz de vizinhos que circunda o pixel a tratar (incluindo ele mesmo):
 +
 +{{ :​prog2:​mascaras.png?​300 |Máscaras de filtragem}}
 +
 +Requisitos:
 +
 +  * O tamanho da máscara é um inteiro positivo ímpar, que pode ser informado na linha de comando (opção ''​-m''​);​ caso não seja informado, o valor default é 3, para uma máscara de 3x3 pixels.
 +  * Os pixels nas bordas da imagem não têm todos os vizinhos e portanto não devem ser filtrados.
 +  * Para ordenar os valores dos pixels deve ser usada a função ''​qsort''​ da biblioteca C (''​man qsort''​).
 +
 +Forma de chamada:
 +
 +  pgmmediana -m N -i input -o output
 +
 +Exemplo de entrada e de saída:
 +
 +{{ballons-original.png|Imagem original}} ​ {{ballons-median.png|Imagem filtrada}}
 +
 +/* filtro de detecção de bordas */
 +
 +/* filtro de melhoria de nitidez */
 +
 +===== Atividade =====
 +
 +  * Implementar os filtros acima definidos como arquivos e comandos separados. Exemplo: o filtro de negativo deve ser implementado em um arquivo ''​pgmnega.c''​ que gera um executável ''​pgmnega''​. **Respeite os nomes dos executáveis** indicados nas descrições acima!
 +  * Os filtros devem aceitar como entrada imagens no formato PGM (P2 e P5, //plain// e //raw//) e devem gerar como saída imagens no mesmo formato da entrada.
 +  * O formato PGM permite definir imagens com pixels de 8 ou 16 bits. Para este trabalho, considere somente imagens com pixels de 8 bits (todas as imagens fornecidas como exemplo têm pixels de 8 bits).
 +  * As rotinas comuns (leitura/​escrita de arquivos, tratamento da linha de comando, etc) devem ser implementadas em arquivos separados, cujos cabeçalhos são incluídos nos arquivos de implementação dos filtros.
 +  * Sempre que possível, as informações da imagem necessárias às funções devem ser transferidas como parâmetros (por valor ou por referência,​ dependendo da situação). Minimizar o uso de variáveis globais.
 +  * Use alocação dinâmica de memória para as imagens, para poder processar as imagens maiores. Só aloque a memória após encontrar o tamanho da imagem.
 +  * Construir um ''​Makefile''​ para o projeto:
 +    * Ao menos os alvos ''​all''​ (default), ''​clean''​ e ''​purge''​.
 +    * CFLAGS = ''​-Wall''​
 +    * Compilar e ligar separadamente (gerar arquivos ''​.o''​ intermediários)
 +  * O que deve ser entregue ao professor:
 +    * arquivos ''​.c''​ e ''​.h''​
 +    * arquivo ''​Makefile''​
 +    * **não enviar** as imagens de teste m(
 +
 +==== Uso de arquivos ====
 +
 +  * A opção ''​-i''​ indica o nome do arquivo de entrada; se não for informado, deve-se usar a entrada padrão (//​stdin//​).
 +  * A opção ''​-o''​ indica o nome do arquivo de saída; se não for informado, deve-se usar a saída padrão (//​stdout//​).
 +  * Todas as mensagens de erro devem ser enviadas para a saída de erro (//​stderr//​).
 +
 +Essas opções podem ser usadas em qualquer combinação,​ ou seja:
 +
 +<​code>​
 +// entrada e saída em arquivos
 +pgmmediana -i inputfile.pgm -o outputfile.pgm
 +pgmmediana -o outputfile.pgm -i inputfile.pgm
 +
 +// entrada em arquivo, saída em stdout, vice-versa ou ambos
 +pgmmediana -i inputfile.pgm > outputfile.pgm
 +pgmmediana -o outputfile.pgm < inputfile.pgm
 +pgmmediana < inputfile.pgm > outputfile.pgm
 +
 +// as opções podem estar em qualquer ordem
 +pgmmediana -m 5 -i inputfile.pgm -o outputfile.pgm
 +pgmmediana -i inputfile.pgm -m 5 -o outputfile.pgm
 +pgmmediana -o outputfile.pgm -i inputfile.pgm -m 5
 +</​code>​
 +
 +==== Estrutura do código-fonte ====
 +
 +O código-fonte deve ser estruturado em arquivos ''​.c''​ e ''​.h''​ que agrupem as diversas funcionalidades. A figura abaixo traz uma uma **sugestão de estrutura** para o código-fonte (as setas correspondem a ''​include''​s):​
 +
 +{{estrutura.png?​700 |}}
  
prog2/processamento_de_imagens.txt · Última modificação: 2019/05/13 18:47 por maziero