Diferenças
Aqui você vê as diferenças entre duas revisões dessa página.
| c:processamento_de_imagens [2023/08/01 16:12] – criada maziero | c:processamento_de_imagens [2023/08/01 16:23] (atual) – edição externa 127.0.0.1 | ||
|---|---|---|---|
| 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 | ||
| + | |||
| + | 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 | ||
| + | </ | ||
| + | |||
| + | <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:// | ||
| + | </ | ||
| + | |||
| + | Alguns exemplos de imagens no formato PGM para usar no projeto: | ||
| + | |||
| + | * {{imagens.tar.gz|Imagens selecionadas}} | ||
| + | * [[http:// | ||
| + | |||
| + | ===== 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 simples ==== | ||
| + | |||
| + | 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 livre ==== | ||
| + | |||
| + | O filtro de rotação gira uma imagem em um ângulo θ (>0) no sentido **horário**, | ||
| + | |||
| + | 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 '' | ||
| + | |||
| + | 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:// | ||
| + | |||
| + | 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? | ||
| + | {{lena-threshold-50.png? | ||
| + | {{lena-threshold-75.png? | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ==== Filtro de redução de ruído pela média ==== | ||
| + | |||
| + | O filtro da média é usado para para " | ||
| + | |||
| + | 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. | ||
| + | </ | ||
| + | |||
| + | 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:// | ||
| + | |||
| + | {{ mascaras.png? | ||
| + | |||
| + | Requisitos: | ||
| + | |||
| + | * O tamanho da máscara é um inteiro positivo ímpar, que pode ser informado na linha de comando (opção '' | ||
| + | * 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 '' | ||
| + | |||
| + | 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 LBP (Local Binary Patterns) ==== | ||
| + | |||
| + | LBP (// | ||
| + | |||
| + | Para o cálculo do LBP de um pixel, usa-se uma **máscara** com valores 2< | ||
| + | |||
| + | {{ lbp.png |Cálculo de LBP}} | ||
| + | |||
| + | Considere o pixel central com valor 6 e seus oito vizinhos na imagem (a). O valor do pixel central é utilizado como limiar e todos os pixels com valor de intensidade maior ou igual a ele recebem 1, caso contrário, 0 (b). Esses valores são então multiplicados pela máscara (c ), resultando então nos valores apresentados em (d). O valor LBP do pixel 6 é dado pela soma desses valores, ou seja LPB = 1+8+32+128 = 169. Note que essa codificação garante valores LBP entre 0 e 255. | ||
| + | |||
| + | Forma de chamada: | ||
| + | |||
| + | pgmlbp -i input -o output | ||
| + | |||
| + | Exemplo de entrada e de saída: | ||
| + | |||
| + | {{lena-original.png|}} → | ||
| + | {{lena-lbp.png|}} | ||
| + | |||
| + | {{lbp-in.png|LBP input}} → | ||
| + | {{lbp-out.png|LBP output}} | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ==== Outros filtros (ideias) ==== | ||
| + | |||
| + | * mudança de escala | ||
| + | * detecção de bordas | ||
| + | * melhoria de nitidez | ||
| + | * melhoria de contraste | ||
| + | * ... | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Atividade ===== | ||
| + | |||
| + | * Implementar os filtros acima definidos como arquivos e comandos separados. Exemplo: o filtro de negativo deve ser implementado em um arquivo '' | ||
| + | * 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/ | ||
| + | * 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, | ||
| + | * 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 '' | ||
| + | * Ao menos os alvos '' | ||
| + | * CFLAGS = '' | ||
| + | * Compilar e ligar separadamente (gerar arquivos '' | ||
| + | * O que deve ser entregue ao professor: | ||
| + | * arquivos '' | ||
| + | * arquivo '' | ||
| + | * Por favor, não envie as imagens de teste! m( | ||
| + | |||
| + | ==== Uso de arquivos ==== | ||
| + | |||
| + | * A opção '' | ||
| + | * A opção '' | ||
| + | * Todas as mensagens de erro devem ser enviadas para a saída de erro (// | ||
| + | |||
| + | Essas opções podem ser usadas em qualquer combinação, | ||
| + | |||
| + | < | ||
| + | // entrada e saída em arquivos | ||
| + | pgmmediana -i input.pgm -o output.pgm | ||
| + | pgmmediana -o output.pgm -i input.pgm | ||
| + | |||
| + | // entrada em arquivo, saída em stdout, vice-versa ou ambos | ||
| + | pgmmediana -i input.pgm > output.pgm | ||
| + | pgmmediana -o output.pgm < input.pgm | ||
| + | pgmmediana < input.pgm > output.pgm | ||
| + | |||
| + | // as opções podem estar em qualquer ordem | ||
| + | pgmmediana -m 5 -i input.pgm -o output.pgm | ||
| + | pgmmediana -i input.pgm -m 5 -o output.pgm | ||
| + | pgmmediana -o output.pgm -i input.pgm -m 5 | ||
| + | </ | ||
| + | |||
| + | ==== Estrutura do código-fonte ==== | ||
| + | |||
| + | O código-fonte deve ser estruturado em arquivos '' | ||
| + | |||
| + | {{ estrutura.png? | ||