• Nenhum resultado encontrado

ProcImaROriginal

N/A
N/A
Protected

Academic year: 2021

Share "ProcImaROriginal"

Copied!
46
0
0

Texto

(1)

Alejandro C. Frery, Talita Perciano

Abstract

These notes are introductory to both R and to image processing. R is a FLOSS (Free-Libre Open Source Software) platform and a high-level matrix-oriented programming language and, therefore, it is well suited for implementing many basic operations required for image processing.

Resumo

Este texto apresenta algumas noções básicas de processamento digital de imagens empregando R. R é uma plataforma FLOSS (Free-Libre Open Source Software) e uma linguagem de programação de alto nível orientada a processamento matricial e, com isso, apta a lidar de forma natural com muitas operações básicas e transformações de imagens.

1.1. Introdução: imagens e R

Neste seção veremos alguns comandos básicos da plataforma R, bem como as definições e a notação que iremos empregar no restante do texto. No seção 1.2 apresentaremos as principais definições e notações a serem em-pregadas no resto do texto. No seção 1.3 comentamos as características mais salientes dos principais formatos pictóricos de imagens, e mostramos como li-dar com eles (ler e gravar) em R. O seção 1.4 apresenta algumas das principais transformações locais, com ênfase nas operações de melhoria de contraste. O seção 1.5, que conclui estas notas, apresenta os conceitos básicos das filtra-gens linear (convolução no domínio do espaço e da frequência) e não linear (fitros da mediana e Nagao-Matsuyama).

1.1.1. Processamento de Imagens

O campo de processamento digital de imagens refere-se a processar ima-gens digitais por meio de um computador. Uma imagem pode ser definida

como uma função bidimensional, f(x, y), ondexeysão coordenadas

espaci-ais, e a amplitude de f em qualquer par de coordenadas(x, y)é chamada de

intensidade ou nível de cinza da imagem naquele ponto. Quandox,y, e os

valores de intensidade de f são todos finitos, quantidades discretas,

chama-mos a imagem de imagem digital. Note que uma imagem digital é composta de um número finito de elementos, onde cada um possui uma posição particular e um valor escalar ou vetorial. As imagens coloridas frequentemente possuem

(2)

valores vetoriales de dimensão3, enquanto as imagens em tons de cinza re-querem apenas um escalar em cada posição. O termo mais amplamente usado na área para denominar estes elementos é pixel. No seção 1.2 serão vistas, mais formalmente, as definições e notações envolvidas.

O processamento digital de imagens é um campo de estudo bastante vasto e, na verdade, não há um acordo geral entre autores e pesquisadores sobre onde este campo termina e outras áreas relacionadas, como análise de ima-gens e visão computacional, começam. Porém, um paradigma bastante utili-zado é considerar três níveis de processos computadoriutili-zados: processamento de baixo, médio e alto nível. Os primeiros envolvem operações primitivas como preprocessamento para reduzir ruído e melhoramento de contraste, onde o foco está nos valores e operações sobre os mesmos. Processos de nível mé-dio envolvem tarefas como segmentação (particionar uma imagem em regiões ou objetos), descrição destes objetos para reduzí-los a uma forma adequada para o processamento pelo computador, e classificação de objetos individuais; neste nível já há um certo grau de preocupação com a semântica das informa-ções contidas na imagem. Por fim, processos de alto nível envolvem buscar o significado de conjuntos de objetos reconhecidos e realizar funções congnitivas frequentemente associadas à visão natural.

Historicamente, uma das primeiras aplicações de imagens digitais foi na indústria de jornais, quando figuras foram, pela primeira vez, enviadas por um cabo submarino entre Londres e Nova Iorque. A introdução deste tipo de cabo, no início dos anos 20, reduziu o tempo necessário para transportar uma ima-gem através do Atlântico de mais de uma semana para menos de três horas. Equipamentos especializados de impressão codificavam as imagens para a transmissão e reconstruíam as mesmas no fim da recepção. Os primeiros ca-bos eram capazes de codificar imagens em cinco níveis de cinza distintos. Esta capacidade foi aumentada para 15 níveis em 1929.

A história do processamento digital de imagens está intimamente relacio-nada à história do desenvolvimento do computador digital. De fato, os primei-ros computadores podeprimei-rosos o suficiente para carregar tarefas significativas de processamento de imagens surgiram no início dos anos 60. Desde então, começaram a surgir tarefas consideradas realmente de processamento digital de imagens:

Em 1964, no JPL – Jet Propulsion Laboratory, Califórnia, imagens da

lua foram processadas por um computador para corrigir diversos tipos de distorções.

• No início dos anos 70, técnicas de processamento digital de imagens

começaram a ser usadas em imageamento médico e na astronomia. A invenção da Tomografia Computadorizada pode ser citada como um dos eventos mais importantes na aplicação de processamento de imagens do diagnóstico médico.

Desde esta época até os dias atuais o campo de processamento de ima-gens cresceu vigorosamente. Além de aplicações na medicina e no programa

(3)

espacial, técnicas de processamento de imagens são atualmente usadas em um vasto campo de aplicações como na biologia, geografia, arqueologia, fí-sica e temas relacionados, medicina nuclear, defesa, entre outros. Além disso, existe uma outra grande área de aplicação de técnicas de processamento di-gital de imagens que é solucionar problemas relacionados à percepção pelo computador. Problemas como reconhecimento automático de caracteres, vi-são de máquina industrial para inspeção de produtos, processamento de im-pressões digitais e processamento de imagens de satélite são alguns exemplos de aplicações nesta área. Consulte [Gonzalez and Woods 2007] para leitura adicional.

Neste curso serão apresentadas algumas das operações mais comuns uti-lizadas para o processamento digital de imagens e como estas operações são feitas usando a plataforma R.

1.1.2. A plataforma R

A plataforma R é Free/Libre and Open Source Software (FLOSS). Seu código-fonte está disponível para qualquer pessoa e pode ser alterado para adequá-lo a necessidades específicas, sem ter que pagar. Portanto, FLOSS é de fato gratuito, mas usar este termo somente para designar softwares sem custo é contar a metade da história.

O software gratuito (freeware), por si só, é um software que pode ser usado sem precisar pagar. Porém, não necessariamente se tem acesso ao seu código-fonte e, portanto, nem sempre pode ser alterado ou simplesmente estudado, e frequentemente só pode ser usado da forma como ele foi disponi-bilizado.

R é uma linguagem e um ambiente para computação estatística e para pre-paração de gráficos de alta qualidade. É um projeto GNU similar à linguagem e ambiente S-PLUS [Chambers 2008] e, ainda que haja diferenças significativas entre eles, grande parte do código desenvolvido para um funciona no outro.

R oferece uma grande variedade de técnicas estatísticas (modelos linea-res e não-linealinea-res, testes estatísticos clássicos, modelos de séries temporais, classificação e agrupamento, entre outros) e gráficas, e é altamente extensível. R é uma coleção integrada de facilidades de software para manipulação de dados, realização de cálculos e preparação de gráficos, que inclui

• tratamento efetivo de dados e facilidades de armazenamento;

• operadores para cálculos em matrizes multidimensionais;

• ferramentas de diversos níveis de sofisticação para análises de dados; • facilidades gráficas para análise de dados;

• uma linguagem de programação bem definida, simples e eficaz que

in-clui expressões condicionais, laços, funções recursivas definidas pelo usuário e recursos de entrada e saída.

Antes de começar a usar R, recordemos que estão disponíveis emhttp:

(4)

exe-cutáveis já compilados para diversos sistemas operacionais. Nesse sítio encon-tram-se também disponíveis textos e tutoriais. A versão que utilizaremos para o desenvolvimento destas notas é a 2.8.1 para Linux, disponibilizada em de-zembro de 2008.

Em Ubuntu e outros derivados de Debian, basta dar o seguinte comando para instalar a plataforma:

$ sudo apt-get install r-base

A instalação de bibliotecas deve ser feita como super-usuário. Para entrar no R em Linux, digite “R” na linha de comando

$ R

Para pedir ajuda, já dentro de R, digite:



> ?data

> help . s t a r t ( )

 

Se desejarmos indicar o navegador a ser utilizado (que deverá ter capa-cidade para processar Java), por exemplo Mozilla, poderemos fazê-lo da se-guinte forma:  > help . s t a r t ( browser= " m o z i l l a " )   Para sair do R:  > q ( )   1.1.2.1. Primeiros passos

R pode ser usado como uma calculadora de grande capacidade. Vamos à seguinte sessão  1 $ R 2 > 2 3 [1] 2 4 > 2+2 5 [1] 4 6 > sqrt(2) 7 [1] 1.414214 8 > exp(sqrt(2)) 9 [1] 4.11325 10 > sin(exp(sqrt(2))) 11 [1] -0.8258217

(5)

12 > sinh(exp(sqrt(2))) 13 [1] 30.56439

14 > sinh(exp(sqrt(2 - 1i*2))) 15 [1] -20.96102-6.575177i 16 > q()

17 Save workspace image? [y/n/c]: n

 

Iniciamos uma sessão (em Linux) chamando, a partir de qualquer caminho, o sistema R (linha 1). Entre as linhas 1 e 2, teremos uma saída com informa-ções da versão do R, sua data de lançamento e outros dados (aqui omitidos). A linha 2 passa ao R uma entrada constante e R a imprime (linha 3); a saída de

dados numéricos é precedida pelo indicador da linha, neste caso[1], já que

R supõe que pode haver mais de uma linha de dados; este tipo de marcador pode ser alterado. Na linha 4 pedimos ao R que calcule2+ 2, e o resultado é impresso na linha 5. Nas linhas 6, 8, 10 e 12 solicitamos a realização de outros cálculos, e seus respectivos resultados são exibidos nas linhas 7, 9, 11 e 13.

R trabalha com números complexos; a unidade complexa√−1é denotada na

entrada por1i, e as linhas 14 e 15 mostram uma operação com complexos e

seu resultado, respectivamente. Ao terminar uma sessão (linha 16) R nos per-guntará se desejamos guardar as variáveis e funções definidas (linha 17) para uso futuro; se assim o fizermos, salvaremos também os comandos que foram emitidos na sessão. Se desejamos exportar os comandos para um arquivo de

texto, podemos fazê-lo comsavehistory(file = "arquivo.txt"), para

depois recuperá-los comloadhistory(file = "arquivo.txt").

Para ter uma idéia da capacidade gráfica do R podemos usar os seguintes comandos, que ativarão as demonstrações incluídas na distribuição básica:

 1 > demo("graphics") 2 > demo("image") 3 > demo("persp") 4 > demo("recursion")  

A linha 1 ativa a demonstração de algumas capacidades gráficas do R, in-cluindo o uso de cores. A linha 2 ativa a demonstração dos recursos de uso de imagens para visualização de dados multidimensionais. A linha 3 mostra alguns recursos do R para visualização de funções multidimensionais em pers-pectiva. A linha 4 mostra como R implementa um método adaptativo para cal-cular integrais numéricas.

1.1.2.2. Bibliotecas

O sistema R utiliza diversas bibliotecas de funções e conjuntos de dados

adicionais, que são carregadas com a auxílio da funçãolibrary(), tal como

(6)



1 > library(cluster)

 

Essa função carrega bibliotecas já instaladas localmente. O comando



1 > install.packages()

 

abre interfaces para instalar novas bibliotecas; mais sobre esse assunto na página 9 deste texto.

No sitehttp://cran.r-project.orgestão disponíveis as bibliotecas

oficiais, que cobrem uma ampla gama de aplicações.

1.1.2.3. Leitura e Importação de Dados

Com a instalação completa do R ficam disponíveis vários conjuntos de da-dos, e para lê-los basta utilizar a funçãodata():



1 > data(iris)

 

Dados podem ser importados no sistema a partir de várias fontes, como

ar-quivos ASCII (extensãotxtoucsv), bancos de dados e planilhas. Dois tipos

de importação bastante utilizados são as de arquivos de tipotxtecsv. Para

importar arquivos ASCII, R oferece duas funções interessantes:read.table()

eread.csv(ver exemplo a seguir).



1 > read.table("dados.txt")

2 > read.csv("dados.csv", sep=";")

 

Para ver as variáveis que estão na memória:

 1 > ls() 2 > iris

3 > summary(iris)

4 Sepal.Length Sepal.Width Petal.Length Petal.Width 5 Min. :4.300 Min. :2.000 Min. :1.000 Min. :0.100 6 1st Qu.:5.100 1st Qu.:2.800 1st Qu.:1.600 1st Qu.:0.300 7 Median :5.800 Median :3.000 Median :4.350 Median :1.300 8 Mean :5.843 Mean :3.057 Mean :3.758 Mean :1.199 9 3rd Qu.:6.400 3rd Qu.:3.300 3rd Qu.:5.100 3rd Qu.:1.800 10 Max. :7.900 Max. :4.400 Max. :6.900 Max. :2.500 11 Species

12 setosa :50 13 versicolor:50 14 virginica :50

 

Na listagem acima vemos a saída da funçãols(), que é o conjunto de

(7)

de conjuntos de dados; no nosso caso, a saída é um conjunto de estatísticas de resumo (valores mínimo e máximo, primeiro, segundo e terceiro quartis, e média) de cada variável.

1.1.2.4. Amostras Univariadas

A plataforma R oferece diversas funções para o cálculo de estatísticas des-critivas, como a média, a mediana, estatísticas de ordem, medidas de disper-são, assimetria e curtose. Para ilustrar o uso destas funções será utilizado o

conjunto de dadosiris, disponível no R. Este conjunto de dados consiste em

151 linhas com seis colunas cada uma. A primeira linha, de tipo texto, des-creve o conteúdo de cada coluna. As cinco primeiras colunas correspondem a medidas realizadas sobre flores, e a última, que é de tipo texto, categoriza em uma de três espécies cada flor medida. As duas primeiras linhas (numéricas) e todas as colunas do conjunto de dados podem ser visualizadas da seguinte forma:



1 > iris[1:2,]

2 Sepal.Length Sepal.Width Petal.Length Petal.Width Species

3 1 5.1 3.5 1.4 0.2 setosa

4 2 4.9 3.0 1.4 0.2 setosa

 

A primeira coluna está rotuladaSepal.Length; para ver os valores basta

emitir o seguinte comando:

 1 > iris$Sepal.Length 2 [1] 5.1 4.9 4.7 4.6 5.0 5.4 4.6 5.0 4.4 4.9 5.4 4.8 3 [13] 4.8 4.3 5.8 5.7 5.4 5.1 5.7 5.1 5.4 5.1 4.6 5.1 4 [25] 4.8 5.0 5.0 5.2 5.2 4.7 4.8 5.4 5.2 5.5 4.9 5.0 5 [37] 5.5 4.9 4.4 5.1 5.0 4.5 4.4 5.0 5.1 4.8 5.1 4.6 6 [49] 5.3 5.0 7.0 6.4 6.9 5.5 6.5 5.7 6.3 4.9 6.6 5.2 7 [61] 5.0 5.9 6.0 6.1 5.6 6.7 5.6 5.8 6.2 5.6 5.9 6.1 8 [73] 6.3 6.1 6.4 6.6 6.8 6.7 6.0 5.7 5.5 5.5 5.8 6.0 9 [85] 5.4 6.0 6.7 6.3 5.6 5.5 5.5 6.1 5.8 5.0 5.6 5.7 10 [97] 5.7 6.2 5.1 5.7 6.3 5.8 7.1 6.3 6.5 7.6 4.9 7.3 11 [109] 6.7 7.2 6.5 6.4 6.8 5.7 5.8 6.4 6.5 7.7 7.7 6.0 12 [121] 6.9 5.6 7.7 6.3 6.7 7.2 6.2 6.1 6.4 7.2 7.4 7.9 13 [133] 6.4 6.3 6.1 7.7 6.3 6.4 6.0 6.9 6.7 6.9 5.8 6.8 14 [145] 6.7 6.7 6.3 6.5 6.2 5.9  

Se queremos ter acesso às variáveis diretamente, sem necessidade de fazer referência ao conjunto de dados (iris), podemos colocar as variáveis na lista de objetos definidos com o comando



1 > attach(iris)

(8)

Para calcular a média amostral da variávelSepal.Lengthbasta fazer



1 > mean(Sepal.Length) 2 [1] 5.843333

 

A mediana amostral é obtida com



1 > median(Sepal.Length) 2 [1] 5.8

 

Para calcular os quartis fazemos



1 > quantile(Sepal.Length) 2 0% 25% 50% 75% 100% 3 4.3 5.1 5.8 6.4 7.9

 

A funçãoquantile()admite como argumento opcional um vetor de

valo-res no intervalo[0, 1], retornando os percentis da amostra nesses pontos. Se, por exemplo, queremos calcular os decis deveríamos entrar com o comando

quantile(iris$Sepal.Length, v), ondevé o vetor que contém os va-lores(i/10)1≤i≤9. Podemos fazê-lo manualmente, ou utilizar uma função do R

para gerar este vetor auxiliar.



1 > quantile(Sepal.Length, seq(.1,.9,.1)) 2 10% 20% 30% 40% 50% 60% 70% 80% 90% 3 4.80 5.00 5.27 5.60 5.80 6.10 6.30 6.52 6.90

 

Já que usaremos este vetor várias vezes, é conveniente guardá-lo em uma variável de nome mais curto e manejável com o comando



1 > l_s <- Sepal.Length

 

As últimas versões do R admitem “=” como comando de atribuição, em vez

do mais exótico (porém mais utilizado, até agora) “<-”.

R também oferece funções para calcular medidas de dispersão como vari-ância (var), desvio padrão (sd, por standard deviation) e mediana do desvio absoluto (mad, por median absolute deviation), tal como é mostrado a seguir.

 1 > var(l_s) 2 [1] 0.6856935 3 > sd(l_s) 4 [1] 0.8280661 5 > mad(l_s) 6 [1] 1.03782  

(9)

 1 > max(l_s) 2 [1] 7.9 3 > min(l_s) 4 [1] 4.3 5 > length(l_s) 6 [1] 150  

Para calcular estatísticas de ordem superior, como assimetria e curtose,

é necessário carregar o pacotee1071, que provê as funçõesskewness()e

kurtosis().  1 > install.packages("e1071") 2 > library(e1071) 3 > skewness(l_s) 4 [1] 0.3086407 5 > kurtosis(l_s) 6 [1] -0.6058125  

A linha 1 é necessária para baixar uma biblioteca que não está disponível lo-calmente. R usará a conexão a Internet para obtê-la. Se o comando é dado para uma biblioteca já instalada, R verificará se há uma versão mais atual e, se houver, a instalará.

R permite construir gráficos com facilidade. Por exemplo, para construir um

boxploté necessário apenas emitir o comando



1 > boxplot(iris[,-5], horizontal=TRUE, notch=TRUE, 2 main="Exemplo de Boxplot")

 

Ao informar como entradairis[,-5]estamos pedindo para considerar todas

as linhas e para omitir a quinta coluna, que não é de valores mas sim de rótulos. O resultado deste comando é mostrado na Figura 1.1.

De fato, para gerar o arquivo que armazena o gráfico mostrado na Fi-gura 1.1 é necessário ativar o dispositivo de saída, fazer o gráfico e desativar o dispositivo. A sequência de instruções é



1 > postscript("box_plot")

2 > boxplot(iris[,-5], horizontal=TRUE, notch=TRUE, 3 main="Exemplo de Boxplot")

4 > dev.off()

 

Embora seja possível fazer uma simples captura da janela, este procedimento irá gerar um conjunto de dados matriciais. Procedendo tal como explicado acima, o gráfico será armazenado em formato vetorial e, com isso, a sua qua-lidade visual estará garantida seja qual for a ampliação a que for submetido.

(10)

Sepal.Length Sepal.Width Petal.Length Petal.Width 0 2 4 6 8 Exemplo de Boxplot

Figura 1.1. Exemplo de Boxplot.

Outro gráfico importante é o histograma, que pode ser construído com o seguinte comando:



1 > library(MASS)

2 > hist.scott(Sepal.Length, prob=TRUE, main="Histograma", 3 xlab="Comprimento da Sepala", ylab="Proporcoes")

 

e seu resultado pode ser visto na Figura 1.2. O histograma será definido com cuidado na equação (1) (página 19). R oferece uma grande variedade de parâ-metros para controlar o aspecto com que os histogramas em particular, e todos os gráficos em geral, são produzidos e exibidos. Para produzir este histograma

utilizamos uma função otimizada,hist.scott, disponível no pacoteMASS.

Uma forma entre gráfica e alfanumérica é o diagrama de galhos e folhas (stem-and-leaf plot):



1 > stem(Petal.Length)

2 The decimal point is at the | 3

4 1 | 012233333334444444444444 5 1 | 55555555555556666666777799

(11)

Histograma Comprimento da Sépala Proporções 4 5 6 7 8 0.0 0.1 0.2 0.3 0.4

Figura 1.2. Histograma dos comprimentos de sépalas.

7 2 | 8 3 | 033 9 3 | 55678999 10 4 | 000001112222334444 11 4 | 5555555566677777888899999 12 5 | 000011111111223344 13 5 | 55566666677788899 14 6 | 0011134 15 6 | 6779   1.1.2.5. Amostras Multivariadas

R trata com facilidade dados multivariados, isto é, onde para cada indiví-duo temos um vetor de observações. A notação que utilizaremos para deno-tar um conjunto de nvetores k-dimensionais éyyy= (yyy1, . . . , yyyn), com yyyi∈R

k.

Quandok= 3temos a forma natural de armazenar informações de cor, mas

há sensores capazes de captar centenas de componentes. O sensor AVIRIS, por exemplo, registra as centas em cerca de duzentas-e-cinquenta componen-tes [Curran and Dungan 1990].

(12)

Este tipo de dados aparece naturalmente em estudos onde se mede mais de um atributo para cada indivíduo como, por exemplo, em antropometria onde se registram o peso, a estatura, a idade e diversas medidas corporais de cada pessoa. Este tipo de análise está recebendo atualmente muita atenção, já que é um passo importante na cadeia de operações conhecida como KDD –

Kno-wledge Discovery in Databases. Em particular, os dadosiristêm dimensão quatro (k= 4); vistos em conjunto, sua dimensão é cento-e-cinquenta (n= 150), mas agrupados em três categorias de cinquenta observações cada.

Para obter uma visão geral de um conjunto de dados deste tipo podemos emitir o seguinte comando



1 > summary(iris)

2 Sepal.Length Sepal.Width Petal.Length 3 Min. :4.300 Min. :2.000 Min. :1.000 4 1st Qu.:5.100 1st Qu.:2.800 1st Qu.:1.600 5 Median :5.800 Median :3.000 Median :4.350 6 Mean :5.843 Mean :3.057 Mean :3.758 7 3rd Qu.:6.400 3rd Qu.:3.300 3rd Qu.:5.100 8 Max. :7.900 Max. :4.400 Max. :6.900

9 Petal.Width Species 10 Min. :0.100 setosa :50 11 1st Qu.:0.300 versicolor:50 12 Median :1.300 virginica :50 13 Mean :1.199 14 3rd Qu.:1.800 15 Max. :2.500  

O comandosummaryfornece resumos de cada uma das variáveis, mas não

informa nada a respeito da relação entre elas.

A matriz de covariância descreve relações entre variáveis, assim como sua variância:



1 > var(iris[1:150, 1:4])

2 Sepal.Length Sepal.Width Petal.Length 3 Sepal.Length 0.68569351 -0.04243400 1.2743154 4 Sepal.Width -0.04243400 0.18997942 -0.3296564 5 Petal.Length 1.27431544 -0.32965638 3.1162779 6 Petal.Width 0.51627069 -0.12163937 1.2956094 7 Petal.Width 8 Sepal.Length 0.5162707 9 Sepal.Width -0.1216394 10 Petal.Length 1.2956094 11 Petal.Width 0.5810063  

(13)

rótulos. Analogamente, é possível obter a matriz de correlações:



1 > cor(iris[1:150, 1:4])

2 Sepal.Length Sepal.Width Petal.Length 3 Sepal.Length 1.0000000 -0.1175698 0.8717538 4 Sepal.Width -0.1175698 1.0000000 -0.4284401 5 Petal.Length 0.8717538 -0.4284401 1.0000000 6 Petal.Width 0.8179411 -0.3661259 0.9628654 7 Petal.Width 8 Sepal.Length 0.8179411 9 Sepal.Width -0.3661259 10 Petal.Length 0.9628654 11 Petal.Width 1.0000000  

Um gráfico muito interessante para se ver simultaneamente o comporta-mento de todos os pares de variáveis de um conjunto multivariado é o diagrama de pares, que é obtido com



1 > pairs(iris[,-5], main="Conjunto Iris", pch=21, 2 bg=c("red","green3","blue")[unclass(Species)])

 

e é mostrado na Figura 1.3. A funçãounclasstransforma classes em atributos

numéricos, que por sua vez são utilizados como índices para as cores.

A funçãostars()também é muito utilizada:



1 > stars(iris, full=TRUE, draw.segments=TRUE, 2 key.loc=c(27,1))

 

O resultado é mostrado na Figura 1.4.

As variações possíveis para estes gráficos são, também, muitas. Uma das mais importantes consiste no uso de de “fatores”. Em R, um “fator” é uma va-riável categórica que indica a pertinência de uma observação a uma classe. No exemplo dos dados de flores, podemos atribuir a cada vetor de tamanho

4de valores (largura e comprimento da sépala, largura e comprimento da

pé-tala) a variável categórica “espécie”. Essa representação irá facilitar muito a visualização e a análise dos dados, tal como ilustrado no código que segue.

O seguinte exemplo requer o uso da bibliotecalattice, uma das mais

poderosas ferramentas de visualização e análise de de dados multivariados em R [Murrell 2006, Sarkar 2008].



1 > library(lattice)

2 > splom(~iris[,1:4] | Species, data = iris, pscales = 0, 3 + varnames = c("Sepal\nLength", "Sepal\nWidth",

4 + "Petal\nLength, "Petal\nWidth"))

(14)

Sepal.Length 2.0 2.5 3.0 3.5 4.0 0.5 1.0 1.5 2.0 2.5 4.5 5.5 6.5 7.5 2.0 2.5 3.0 3.5 4.0 Sepal.Width Petal.Length 1 2 3 4 5 6 7 4.5 5.0 5.5 6.0 6.5 7.0 7.5 8.0 0.5 1.0 1.5 2.0 2.5 1 2 3 4 5 6 7 Petal.Width Conjunto Iris

Figura 1.3. Diagrama de pares para os dados iris.

No código acima, a linha 1 carrega a bibliotecalattice. A linha 2 esti-pula a criação de um gráfico de acordo com uma fórmula: as quatro primeiras colunas do conjunto iris, onde estão os valores, em função do fator espécie.

O trechopscales = 0desta linha elimina o uso de marcas numéricas nos

eixos para facilitar a visualização mais qualitativa do que quantitativa das rela-ções entre as variáveis. As linhas 3 e 4 apenas especificam a forma em qual os rótulos das variáveis serão mostrados.

Na figura 1.5 podemos notar como as variáveis que descrevem medidas de pétalas variam de forma diferente em função da espécie: quando se trata de Virginica, ambas adotam valores relativamente grandes, quando é Setosa os valores são pequenos, e quando a espécie é Versicolor observa-se uma variação intermediária. Essa, bem como muitas outras relações interessantes, são evidenciadas pelo fato da figura 1.5 exibir os dados de forma sincronizada, isto é, fazendo coincidir os eixos de cada uma das três caixas que o compõem. Uma biblioteca mínima a respeito de R é formada pelos seguintes livros: [Chambers 2008, Chambers et al. 1983, Crawley 2005, Crawley 2007, Dalgaard 2002, Davison and Hinkley 1997, Everitt and Hothorn 2006, Maindonald and Braun 2003, Murrell 2006, Paradis 2005, Sarkar 2008, Spector 2008, Venables and Ripley 2000, Venables and Ripley 2002, Venables and Smith 2001, Verzani 2004]. Em parti-cular, o texto de [Velho et al. 2008] apresenta uma abordagem similar à destas

(15)

Sepal.Length Sepal.Width

Petal.Length Petal.Width Species

Figura 1.4. Diagrama de estrelas a partir do conjunto de dados iris.

notas e todos os exemplos dos Capítulos 3 e 10 foram implementados em R. Três recursos na Web são essenciais:

• O sítio oficial de R:http://www.r-project.org

• A lista de discussão R-help (em Inglês): https://stat.ethz.ch/

mailman/listinfo/r-help

• A lista de discussão RSTAT (em Português):http://br.groups.yahoo.

com/group/R_STAT

1.2. Imagens: definições e notação

O conjunto dos números reais será denotadoR, o dos números complexos

C, o dos números inteirosZe o dos números naturais (incluindo o zero)N. O

número de elementos do conjuntoAserá denotado#A. O indicador do conjunto

Aserá denotado como1A, isto é,

1A(x) =



1 se x∈ A

0 se x∈ A./

(16)

processa-Figura 1.5. Diagrama de pontos por classe dos dados iris.

mento de imagens, são os livros de [Mascarenhas and Velasco 1989], o de [Jain 1989], o de [Banon 2000] e o já mencionado [Velho et al. 2008].

Uma imagem, no contexto destas notas, sempre será uma função definida sobre uma grade finita euclidiana regular bidimensional sobre um subconjunto dos vetores reaisp-dimensionais, isto é, o conjuntoS= [0, m −1]×[0,n−1] ⊂Z

2

denotará o suporte das imagens; note que[0, m − 1] ⊂N0, ondeN0 denota o conjunto dos naturais incluindo o zero e[0, n−1] ⊂N0são intervalos de inteiros,

logo,Sé uma região conexa. Uma imagem é um objeto da forma f : S→ K,

ondeKR

p ou aindaK

C

p. Dependendo da plataforma computacional

empregada, m≥ 1 e n≥ 1 denotarão, respectivamente, o número de linhas

(17)

bidimensionais pelas linhas na primeira variável e pelas colunas na segunda (diferentemente de, por exemplo, as plataformas IDL e ENVI), diremos que a

imagem fpossuimlinhas encolunas.

Desta forma ficam excluídas desta discussão as imagens tomográficas, por serem elas funções definidas sobre grades tridimensionais, bem como os mo-delos de imagens de certas máquinas morfológicas, por eles empregarem gra-des exagonais. Também não iremos considerar o tempo, isto é, vídeo.

No que segue descreveremos dois elementos importantes ao se tratar de imagens: a estrutura espacial, caracterizada pelo conceito de “vizinhança”, e o conjunto dos valores possíveis em cada posição da imagem, isto é, o seu contradomínio.

1.2.1. Vizinhanças

Algumas das mais importantes operações com imagens dependem não

apenas do valor observado na coordenada s∈ S, mas também dos valores

observados em uma região próxima dessa coordenada. Torna-se, portanto, importante definir com precisão o conceito de “proximidade”.

Dada a natureza discreta do suporte S, há várias maneiras de definir a

vizinhança da posiçãos∈ S, que será denotada∂s e que, por definição, não

inclui a própria coordenadas. Um caso extremo é o da vizinhança vazia, isto é,∂s= /0; no outro extremo, cada coordenada pode ter como vizinhos todos os

outros pontos, ou seja,∂s= S \ {s}.

É comum ouvir dizer “usaremos os quatro vizinhos mais próximos”; isso é intuitivo mas, não resolve corretamente a definição de vizinhança em bordas e esquinas da imagem. Para tomar conta de todas as situações possíveis podemos usar o conceito de distância, por exemplo

s= {t ∈ S \ {s} : d(s,t) ≤ k},

onded(s,t)é alguma distância entre as coordenadass,t ∈ S. As distâncias mais frequentes são a de Manhattan (ouL1), a euclidiana (ouL2) e a de Kolmogorov

(ouL) dadas, respectivamente, por

d1(s,t) = |s1−t1| + |s2−t2|,

d2(s,t) =

q

(s1−t1)2+ (s2−t2)2, e

d(s,t) = max{|s1−t1|,|s2−t2|}.

Na relações acima denotamoss= (s1, s2)et= (t1,t2).

1.2.2. Contradomínios

Tal como comentado no início do seção 1.2, uma imagem é uma função

que a cada coordenada do suportes∈ Satribui um valor emR

pou ainda em

C

p, comp≥ 1inteiro. DenotaremosKo contradomínio da imagem f. A forma

em que os valores do contradomínio são efetivamente armazenados em um computador digital é denominada “quantização”.

(18)

O contradomínio mais simples é o binário, onde temos K= {0,1}. A vi-sualização de uma imagem binária pode ser feita de diversas maneiras, por

exemplo atribuindo a cada valor0a cor preta e a cada valor 1a cor branca.

Fica assim claro que a visualização de uma imagem está apenas associada ao seu contradomínio, mas não está necessariamente determinada por ele.

Um outro contradomínio frequentemente encontrado nas aplicações é o formado pelos primeiros256inteiros, começando no0, isto é,K= {0,1,...,255}. Esse é conhecido como “formato byte”.

Ainda nos contradomínios unidimensionais, é frequente encontrar inteiros com e sem sinal, inteiros longos (com e sem sinal), palavras em ponto flutuante e em precisão estendida.

Quando se trata de contradomínios multidimensionais, o mais frequente

é que sejam usadaspcópias do mesmo contradomínio unidimensional para

definir o espaço de valores da imagem, isto é, teremos imagens binárias p

-dimensionais, imagens bytep-dimensionais e assim por diante. Cada uma das

dimensões irá medir, tipicamente, diferentes propriedades da cena, isto é, do mundo real. Um exemplo disso é o das imagens de sensoriamento remoto obtidas pelos sensores do Satélite Sino-Brasileiro de Recursos Terrestres –

CBERS (verhttp://www.cbers.inpe.br). A sua câmera imageadora de

alta resolução – CCD produz imagens nas seguintes bandas espectrais:

• 0, 51− 0,73µm (pancromática) • 0, 45− 0,52µm (azul)

• 0, 52− 0,59µm (verde) • 0, 63− 0,69µm (vermelho)

• 0, 77− 0,89µm (infravermelho próximo).

Cada uma dessas bandas é registrada com quantização de8bits, isto é, em

formato byte.

Imagens com contradomínio complexo são bem mais específicas. Elas aparecem quando o mecanismo de imageamento registra não apenas a in-tensidade do sinal mas também a fase relativa do mesmo. Exemplos de apli-cações onde aparecem imagens complexas são as imagens de elastografia [Silva et al. 2006] (com valores emC) e as de polarimetria por radar de aber-tura sintética [Frery et al. 2007] (com valores emC

p). A quantização mais

fre-quente para as imagens em formato complexo é a de precisão simples tanto para a parte real quanto para a parte imaginária de cada banda.

Uma ferramenta importante para fazer uma descrição sucinta dos valores adotados por uma imagem é o histograma. Este objeto é uma contagem dos valores observados em certos intervalos determinados pelo usuário.

Seja f : S→ K ⊂Ruma imagem eI= {I0, I1, . . . , Iq}uma partição finita do contradomínio em intervalos, isto é, os elementos deI satisfazem:

1. cadaIié um intervalo (não necessariamente não degenerado),

(19)

3. a união deles é exatamente o contradomínio:S0≤i≤qIi= K.

De posse de uma partiçãoI do contradomínio, o histograma da imagem

f é definido como o vetor deq+ 1componentes naturais, onde a componente

ié o número de elementos emSonde a imagem adota um valor na partiçãoIi,

isto é, o histograma da imagemfem relação à partiçãoI é a funçãoHI( f ) =

(H0, H1, . . . , Hq)onde

Hi= #{s ∈ S : f (s) ∈ Ii}. (1)

Freqüentemente empregaremos o histograma de proporções da imagem fem

relação à partiçãoI, que é definido comohI( f ) = HI( f )/#S = (h0, h1, . . . , hq),

isto é, é o histograma de f em relação à partiçãoI com cada componente

dividida pelo número de elementos deS.

1.3. Formatos de imagens e leitura de dados

Há duas grandes classes de informações visuais que podem ser armaze-nadas em um computador digital: as imagens vetoriais e as matriciais. As primeiras são formadas pela descrição, em alguma linguagem conveniente, dos elementos geométricos que compõem a imagem. Elas são a forma ideal para mostrar, em qualquer escala que for necessária, informações que podem ser descritas pela junção de formas geométricas relativamente simples; são exemplos desse tipo de informação as figuras 1.1 (segmentos, circunferências e texto), 1.2 (segmentos e texto), e 1.3 (segmentos, circunferências, cores e texto). O segundo tipo de informações visuais que podemos armazenar é o das imagens matriciais. Nestas últimas, o elemento básico é um valor associ-ado a uma posição. As imagens matriciais são o objeto destas notas e serão detalhadas no que segue deste seção.

No contexto de imagens digitais, um formato de imagem é uma forma pa-drão de organizar e armazenar dados de imagem. O formato define como os dados são arranjados e o tipo de compressão –se existir algum– que é usado. De maneira informal, formatos de imagens, também chamados de “gráficos raster” ou “arquivos bitmap” (mapa de bits), contêm uma represen-tação de um gráfico armazenada como pixels a uma resolução fixa. Um exem-plo é uma imagem fotográfica digital ou imagem escaneada. Alguns dos for-matos de imagens mais comuns são GIF, JPEG, PNG, TIFF e BMP. O livro de [Murray and Ryper 1994] continua sendo uma referência excelente tanto pela sua abrangência quanto pela profundidade com que disseca os principais formatos gráficos.

Os formatos de imagens podem ser divididos em duas classes: binário e vários tons. Uma imagem binária possui apenas duas tonalidades, enquanto que uma imagem em vários tons possui toda a gama de tons de cinza entre o branco e o preto. A tabela 1.1 mostra alguns formatos de imagens conhecidos dividos nestas duas classes.

Dentre as diversas maneiras de descrever cores (ver [Velho et al. 2008]), faremos referência apenas ao espaço RGB. Cada cor no espaço RGB é des-crita em uma base aditiva formada pelas cores primárias vermelho (R – Red ),

(20)

Binário Tom contínuo

CCITT Grupo 3 JPEG

CCITT Grupo 4 JPEG-LS

JBIG (ou JBIG1) JPEG-2000

JBIG2 BMP

TIFF GIF

PDF PNG TIFF

Tabela 1.1. Formatos de imagens

verde (G – Green) e azul (B – Blue).

Os formatos descritos a seguir são conhecidos genericamente como “for-matos pictóricos”, por estarem intimamente relacionados ao armazenamento e à distribuição de fotografias.

1.3.1. TIFF

O TIFF (Tagged Image File Format) é um formato flexível que normalmente salva 8 bits ou 16 bits por cor (vermelho, verde, azul) para um total de 24 bits e 48 bits, respectivamente, usando TIFF ou TIF como extensão. Este formato su-porta uma variedade de padrões de compressão de imagens, incluindo JPEG, JPEG-LS e JPEG-2000. Nenhum leitor simples lê todo tipo de arquivo TIFF, e por causa disso é frequentemente referenciado como uma família de formatos mais do que um único formato. Os dados em arquivos TIFF podem estar com-primidos com perdas e sem perdas (alguns oferecem compressão sem perda relativamente de boa qualidade para imagens binárias). Algumas câmeras di-gitais podem salvar no formato TIFF, usando o algoritmo de compressão LZW (Lempel-Ziv-Welch, ver [Nelson 1989]) para armazenamento sem perdas. O formato de imagem TIFF não é amplamente suportado por navegadores Web, porém ainda é amplamente aceito como um padrão de arquivo para fotografia no comércio de impressão. Por fim, este formato suporta espaços de cores es-pecíficos para certos dispositivos de impressão, com o CMYK definido por um conjunto particular de tintas para impressão: os pigmentos cian (C), magenta (M), amarelo (Y – Yellow ) e preto (K – blacK ) que formam um espaço de cores subtrativas.

1.3.2. JPEG

Arquivos JPEG (Joint Photographic Experts Group) armazenam dados (na maioria dos casos) em um formato com perdas. Praticamente todas as câme-ras digitais podem salvar imagem no formato JPEG, que suporta 8 bits por cor para um total de 24 bits, produzindo arquivos relativamente pequenos. Quando não é muito grande, a compressão não denigre visivelmente a

(21)

qua-lidade da imagem, mas arquivos JPEG podem sofrem de degradações percep-tíveis quando editados e salvos repetidamente. Imagens fotográficas podem ser melhor armazenadas em um formato sem perdas diferente do JPEG se as mesmas tiverem que ser re-editadas futuramente, ou se pequenos artefa-tos forem inaceitáveis na imagem. O formato JPEG também é usado como o algoritmo de compressão de imagem em muitos arquivos PDF.

1.3.3. PNG

O formato de imagem PNG (Portable Network Graphics) foi criado como o sucessor livre e em código aberto do GIF. Este formato suporta truecolor (16 milhões de cores) enquanto que o GIF suporta apenas 256 cores. O arquivo PNG destaca-se quando a imagem possui grandes áreas uniformemente colo-ridas. O formato PNG sem perdas é mais apropriado para edição de figuras e os formatos com perdas, como o JPEG, são melhores para distribuição final de imagens fotográficas, pois arquivos JPEG são menores do que arquivos PNG. Muitos navegadores Web antigos não suportam o formato PNG, porém todos os navegadores atuais suportam as variantes mais comuns do formato PNG, incluindo transparência em 8 bits.

1.3.4. BMP

O formato de imagem BMP (Windows Bitmap) suporta arquivos gráficos dentro do sistema operacional Microsoft Windows. Tipicamente, os dados de arquivos BMP não são comprimidos e, portanto, ocupam muito espaço. A grande vantagem deste formato é sua simplicidade e grande aceitação.

1.3.5. Leitura de formatos pictóricos no R

R possui algumas funções úteis para a leitura e o gravação dos quatro for-matos de imagens discutidos anteriormente. O trecho de código abaixo apre-senta o uso de funções para leitura.

 1 > # Leitura 2 > imagem <- read.jpeg("imagem.jpg") 3 > plot.imagematrix(imagem) 4 > library(SoPhy) 5 > imagem <- read.picture("imagem.tiff") 6 > plotRGB(imagem) 7 > library(pixmap) 8 9 > # Funcao read.image

10 read.image <- function(file, imdir="/usr/X11R6/bin/",...){ 11 if(!require(pixmap))

12 stop("library pixmap required and not found\n") 13 newfile <- tempfile()

14 cmd <- paste(sep="",imdir,"convert ", ... ," ",file, 15 + " pnm:",newfile)

(22)

16

17 retval <- system(cmd) 18 if(retval != 0) {

19 errmsg <- paste("system command",cmd, 20 + "failed with error code",retval,"\n") 21 stop(errmsg) 22 } 23 p1 <- read.pnm(newfile) 24 unlink(newfile) 25 p1 26 } 27 28 > imagem <- read.image("imagem.bmp")

29 > imagem <- getChannels(imagem, colors = "all") 30 > imagem <- imagemmatrix(imagem,type="rgb") 31 > plot(imagem)

32 > imagem <- read.image("imagem.png")

33 > imagem <- getChannels(imagem, colors = "all") 34 > imagem <- imagemmatrix(imagem,type="rgb") 35 > plot(imagem)

 

No código acima, a linha 2 mostra como ler uma imagem no formato JPEG. Para leitura de imagens no formato TIFF é necessário o uso da biblioteca

SoPhy que fornece a funçãoread.picture, como mostrado nas linhas 4 e 5. O R não fornece uma forma direta para ler imagens nos formatos BMP e PNG, porém pode ser usada uma função disponível no programa

ImageMa-gick (http://www.imagemagick.org) chamadaread.image, juntamente

com a bibliotecapixmap. Esta função está presente no código acima a partir

da linha 9. Na linha 11 a função verifica a existência do pacotepixmap. Na

linha 13 é criado o nome de um arquivo temporário. O comandopasteusado

na linha 14 cria, através de concatenações de strings um comando para ser executado pelo sistema. Este comando é usado para converter para pnm a imagem passada como parâmetro pela chamada da função. Na linha 17 o

co-mandosystemfaz uma chamada para o sistema executar o comando contido

na strig cmd. Após a conversão da imagem, o comandoread.pnmé usado

para ler a imagem, como visto na linha 23. Por fim, na linha 24 é usado o

comandounlinkpara apagar o arquivo temporário criado anteriormente. As

linhas de 28 até 35 mostram como usar a funçãoread.imagepara ler

ima-gens nos dois formatos.

O trecho de código abaixo apresenta o uso de funções para gravação.



1 > # Gravacao

2 > png(filename = "imagem.png", width = 480, height = 480) 3 > plot(imagem)

(23)

5 6 > jpeg(filename="imagem.jpg",width=480,height=480, 7 + quality=80) 8 > plot(imagem) 9 > dev.off() 10 11 > imagem 12 size: 458 x 372 13 type: rgb 14 > imagem <- array(imagem,dim=c(458,372,3)) 15 > imagem <- imagem*255 16 > write.picture(imagem,"imagem.tiff") 17 18 > bitmap("imagem.bmp",’bmp256’) 19 > plot(imagem) 20 > dev.off()  

No código acima as linhas 2, 7, 16 e 18 mostram como salvar imagens

nos formatos PNG, JPEG, TIFF e BMP, respectivamente. O comando png

recebe como parâmetros o nome da imagem, a altura e a largura da imagem. O

comandojpegtambém recebe como parâmetros o nome da imagem, a altura

e a largura da mesma, bem como a qualidade desejada para a gravação da

imagem. Para o comandobitmapbasta fornecer o nome da imagem e o tipo

(outros tipos aceitos podem ser vistos através do comandohelp(bitmap).

1.4. Operações pontuais

As operações mais simples que podem ser realizadas sobre uma ima-gem são as conhecidas como operações pontuais. Estas operações estão definidas de forma tal que cada valor na imagem de saída depende apenas do valor correspondente na imagem de entrada, isto é, são caracterizadas para imagens f, g : S → Kpor operadoresΨ= (Ψs)s∈Sda formag( f )onde

g(s) = (Ψs( f (s)))s∈S. Em outras palavras, o valor da nova imagem na

coorde-nadas, denotadog(s)dependerá apenas do valor da imagem de entrada na

mesma coordenada (f(s)) e do operador definido para ela (Ψs).

O operador pontual mais simples que podemos definir é a identidade, isto é,Ψs( f (s)) = f (s)para todos∈ S; com issog(s) = f (s)para todos∈ S.

As operações pontuais tal como definidas acima são muito gerais, permi-tindo mudar a regra de transformação conforme muda a coordenada, isto é, é possível definir operadoresΨ= (Ψs)s∈Stais queΨs( f (s)) 6=Ψt( f (t))ses6= t

mesmo se f(s) = f (t). Embora esta generalidade seja desejável, na grande

maioria das situações práticas é suficiente trabalhar com a mesma operação

em cada coordenada, isto é, fazendoΨstpara todas as coordenadas. Se

este for o caso a operação pontual ficará definida pelo operadorΨsem neces-sidade de especificá-lo para cada elementos∈ S. Este tipo de transformações

(24)

é conhecido como invariante por translação.

As transformações pontuais podem, em geral, ser especificadas através de tabelas de visualização, conhecidas como LUTs (Look-Up Tables), especial-mente quando o contradomínio das imagens é finito. No que segue será dada especial ênfase às imagens no formato byte, isto é, às imagens f, g : S → K = [0, 255] ⊂N. Para este tipo de imagem qualquer tansformação pontual invari-ante por translação pode ser especificada (e convenientemente implementada)

por uma LUT de255entradas ou, mais economicamente, por um vetor de255

entradas onde cada uma é um valor emK. Com efeito, a transformação Ψ

ficará especificada pelo vetor(v(0), . . . , v (255))fazendov(i) =Ψ(i)e a transfor-mação será aplicada fazendog(s) = v( f (s))para cada coordenada. A não ser que seja especificada outra coisa, quando se trata de uma imagem colorida, a operação é aplicada em cada uma das três bandas.

1.4.1. Negativo digital

Neste contexto, a transformação identidade é, então, especificada pelo ve-torv(i) = i, enquantov(i) = 255 − iespecifica o negativo digital. O código que segue calcula o negativo de uma imagem.

 1 > library(rimage) 2 > load("imagem.Rdata") 3 > imagem 4 size: 458 x 372 5 type: rgb 6 > negativo <- 1 - imagem 7 > plot.imagematrix(negativo)  

No código acima a linha 1 carrega a bibliotecarimagee a linha 2 lê uma

matriz com os valores de uma imagem no R. Esta imagem será usada daqui em diante para ilustrar as operações apresentadas nestas notas. Na linha 6 é realizada a transformação de negativo digital da imagem para todas as bandas; note que ao invés de subtrair o valor de255ele é subtraído de1, isso se deve à conversão interna que a plataforma faz dos valores, padronizando-os para o intervalo[0, 1].

Utiliza-se a funçãoplot.imagemmatrixpara visualizar a imagem

trans-formada. A Figura 1.6 mostra a imagem original (“Moreno Bom”, acrílico sobre

tela, 2008, de Enilson Costahttp://enilson.costa.googlepages.com;

direitos cedidos pelo autor) e seu negativo digital.

Às vezes é conveniente definir transformações pontuaisΨsupondo as

ima-gens com contradomínio real. A versão discreta desta transformação consiste

em truncar e arredondar os valores transformados, isto é, em fazer g(s) =

⌊min{max{0,Ψ( f (s)},255} + 1/2⌋, onde ⌊x⌋ = max{t ∈Z: t≤ x}denota o arre-dondamento para abaixo do valorx∈R.

(25)

(a) Imagem original (b) Negativo digital

Figura 1.6. Ilustração da transformação de negativo digital.

1.4.2. Mudança de brilho e de constraste

Para quaisquer números reaisα eβ as operações pontuais “mudança de

escala porα” e “acréscimo do valorβ” são definidas, respectivamente, como

Sα( f ) =αf eTβ( f ) = f +β, sendo a primeira o produto de escalares em cada coordenada e a segunda a soma de escalares em cada coordenada. A trans-formaçãoΨserá dita “transformação linear” se Ψ(αf+β) =αΨ( f ) +β para

todos reaisα eβ e toda imagem f. As transformações lineares podem ser

vi-sualizadas como retas no espaço( f (s), g(s)). A transformação será dita

“trans-formação linear por partes” se existe uma partição de K tal que para cada

elemento da partição a transformação é linear. Um exemplo de transformação linear por partes para imagens reais ég(s) =| f (s)|. O código a seguir mostra

como realizar as operações de mudança de escala porαe acréscimo do valor

β.



1 > alpha <- 0.3 2 > beta <- 0.5

3 > imagem1 <- imagem*alpha 4 > imagem2 <- imagem + beta 5 > imagem3 <- imagem*alpha + beta 6 > plot.imagematrix(imagem1) 7 > plot.imagematrix(imagem2) 8 > plot.imagematrix(imagem3)

(26)

No código acima as linhas 1 e 2 definem os valores deαeβ. As linhas 3, 4 e 5 realizam, respectivamente, as transformações de escala, de acréscimo de valor e as duas operações simultaneamente. A Figura 1.7 mostra o resultado das operações de mudança de escala e acréscimo de valor.

Como pode ser observado na figura, estas operações redundam em mu-danças de brilho e contraste em uma imagem, sendo que a determinação de

αe deβ fica por conta do usuário, e nem sempre é fácil achar um par de

va-lores capaz de produzir um resultado próximo do ideal. Para isso é necessário definir alguma métrica que guie a procura desses valores como, por exemplo, variância (que é uma medida de contraste) ou entropia (que é uma medida de informação.

1.4.3. Equalização do histograma

Uma operação pontual para melhoria do contraste que não depende de especificações do usuário, e que faz parte do repertório básico de transforma-ções de imagens, é a equalização do histograma. Intuitivamente, uma imagem com uma boa gradação de tons de cinza deverá ter aproximadamente a mesma quantidade de posições com cada valor possível deK. No outro extremo, tería-mos uma imagem com um único valor, isto é, sem nenhuma informação visual. Essa imagem com boa gradação de tons de cinza teria, em princípio, um histo-grama aproximadamente uniforme. . . e histohisto-gramas uniformes são típicos de eventos oriundos de variáveis aleatórias com distribuição uniforme.

Precisaremos de um par de definições e de um resultado importante de probabilidade para justificar o funcionamento da técnica de equalização do his-tograma.

Definição 1.4.1 (Distribuição uniforme em(0, 1)) A variável aleatória X se-gue a distribuição uniforme no intervalo(0, 1)se a sua função de distribuição acumulada é F(t) =    0 set≤ 0, t se0< t < 1, 1 set≥ 1. (2)

A distribuição uniforme é central em probabilidade e em estatística compu-tacional. Ela é a base dos algoritmos para geração de ocorrências de va-riáveis aleatórias com qualquer tipo de distribuição [Bustos and Frery 1992, Frery and Cribari-Neto 2005, Vieira et al. 2008], e pode ser generalizada para outros suportes distintos do intervalo(0, 1), inclusive para conjuntos discretos finitos.

Teorema 1.4.1 (Inversão) Seja a variável aleatória contínuaY, cuja distribui-ção é caracterizada pela fundistribui-ção de distribuidistribui-ção acumuladaFY. A variável

alea-tóriaU= FY(Y )possui distribuição uniforme em(0, 1).

Este teorema, cuja prova pode ser vista em [Bustos and Frery 1992], fornece o suporte teórico para a transformação que estamos procurando.

(27)

Com efeito, se o que queremos é uma imagem com um histograma o mais uniforme possível, podemos modelar os valores observados como sendo even-tos, isto é, ocorrências da variável aleatóriaY. Já que não conhecemosFY, a

função de distribuição acumulada que caracteriza a distribuição deY, podemos estimá-la. Para tanto, podemos lançar mão da função empírica.

Definição 1.4.2 (Função empírica) Sejamx1, . . . , xnocorrências das variáveis

aleatóriasX1, . . . , Xntodas com a mesma distribuição caracterizada pela função

de distribuição acumuladaF. A função empírica, dada por

b F(t) =1

n#{i : xi≤ t},

é um estimador deF.

As propriedades da função empírica bem como a sua relação com inferência robusta podem ser vistas no já clássico livro de [Huber 1981].

A definição 1.4.2 fornece meios para estimarF, que segundo o teorema 1.4.1 é a transformação que precisamos para obter a distribuição que desejamos e que foi estipulada na definição 1.4.1. Temos todos os ingredientes para resolver o nosso problema:

1. Calcular a função empírica da imagemf= (x1, . . . , xn), isto é, obterFb( f ).

2. Obter a imagem com o histograma equalizadog : S→ [0,1]aplicando

pontualmenteFba f, isto é,g(s) = bF( f (s)).

Em se tratando de imagens coloridas, esta transformação pode ser aplicada

banda a banda independentemente. Pelo fato deFbser apenas um estimador

deF, e pela natureza discreta dos dados, dificilmente a imagem transformadag

terá um histograma perfeitamente distribuído; de qualquer maneira, o resultado de aplicar esta transformação costuma ser notável.

O código abaixo mostra como realizar a operação de equalização no R.

 1 > library(rimage) 2 > banda1 <- imagematrix(imagem[,,1],noclipping=T) 3 > banda2 <- imagematrix(imagem[,,2],noclipping=T) 4 > banda3 <- imagematrix(imagem[,,3],noclipping=T) 5 > banda1_equalizada <- equalize(banda1) 6 > banda2_equalizada <- equalize(banda2) 7 > banda3_equalizada <- equalize(banda3) 8 > imagem_equalizada <- array(dim=dim(imagem)) 9 > imagem_equalizada[,,1] <- banda1_equalizada 10 > imagem_equalizada[,,2] <- banda2_equalizada 11 > imagem_equalizada[,,3] <- banda3_equalizada 12 > imagem_equalizada <- imagematrix(imagem_equalizada) 13 > library(MASS) 14 > par(mfrow=c(2,2))

(28)

15 > plot.imagematrix(imagem) 16 > hist.scott(imagem,main="",xlab="Intensidades", 17 + ylab="Densidade") 18 > plot.imagematrix(imagem_equalizada) 19 > hist.scott(imagem_equalizada,main="",xlab="Intensidades" 20 + ,ylab="Densidade")  

A biblioteca rimage fornece a função equalize que equaliza o

histo-grama de uma imagem. Neste caso a equalização é feita em cada uma das bandas da imagem (ver linhas 5 a 7) e depois é feita a composição das bandas

equalizadas para formar a imagem final (ver linhas 8 a 12). O comandopar

usado na linha 14 divide a janela gráfica do R em quatro regiões (duas lihas e duas colunas). Na primeira região é apresentada a imagem original (linha 15), na segunda o histograma desta imagem (linha 16), na terceira (linha 18) e na quarta (linha 19) a imagem equalizada e seu histograma respectivamente. No

comandohist.scottsão usados os parâmetrosxlabeylabque

especi-ficam os rótulos para os eixos x e y do gráfico respectivamente. A Figura 1.8 apresenta o resultado do código acima. Nela percebemos uma característica desta operação: as cores são alteradas (posto que a transformação é aplicada em cada banda, independentemente das outras) e eventuais ruídos são ampli-ficados.

A operação de binarização, também conhecida como limiarização em rela-ção ao valora, é uma operação linear por partes definida comog(s) =1

[a,∞)( f (s)).

Esta operação pode ser generalizada parakvalores comk−1limiares. Quando

aplicada a imagens coloridas, ela é conhecida como “posterização”. O código a seguir mostra como realizar a operação de binarização no R.

 1 > banda1 <- imagematrix(imagem[,,1],type="grey") 2 > limiar <- 0.5 3 > ind1 <- which(banda1<limiar) 4 > ind2 <- which(banda1>=limiar) 5 > binaria <- banda1 6 > binaria[ind1] <- 0 7 > binaria[ind2] <- 1 8 > plot.imagematrix(binaria)  

No código acima a linha 1 extrai uma das bandas da imagem colorida ori-ginal e a linha 2 define o limiar que será aplicado a imagem. Em seguida, as linhas 3 e 4 buscam os pixels na imagem que possuem valores menores do que o limiar e maiores ou iguais ao mesmo, respectivamente. As linhas 6 e 7 aplicam o limiar a imagem. A Figura 1.9 mostra o resultado da binarização.

De forma semelhante podemos fazer uma posterização na imagem co-lorida. Observe o código em R que segue.



(29)

2 > limiar2 <- 0.6

3 > ind1 <- which(imagem<limiar1)

4 > ind2 <- which(imagem>=limiar1 && imagem<limiar2) 5 > ind3 <- which(imagem>=limiar2) 6 > posterizada <- imagem 7 > posterizada[ind1] <- 0 8 > posterizada[ind2] <- 0.45 9 > posterizada[ind3] <- 1 10 > plot.imagematrix(posterizada)  

A Figura 1.10 apresenta o resultado da posterização feita usando o código acima.

Lembramos que nos exemplos acima os limiares estão no intervalo [0, 1]

por causa da padronização interna que a biblioteca faz nos dados.

1.5. Filtragem linear e não linear

Diferentemente das operações pontuais, as operações de filtragem são

lo-cais, isto é, se gé o resultado de filtrar f, então o valor g(s) irá depender

tanto de f(s)quanto dos valores adotados por f na vizinhança des, isto é

g(s) =ϒ( f (s), f (t) : t ∈s). Evidentemente, as operações pontuais são opera-ções locais definidas sobre a vizinhança vazia. As operaopera-ções de filtragem, em geral, são mais poderosas do que as operações pontuais.

Existem inúmeras classificações para as operações de filtragem ou, mais simplesmente, para os filtros de imagens. Dentre as mais importantes podem ser mencionadas as seguintes:

• Filtragem linear (para todos∈ Sos operadoresϒs satisfazemϒs(α1f+

α2g) =α1ϒs( f ) +α2ϒs(g)para todo par de escalaresα1,α2e todo par de

imagens f, g) vs. filtragem não linear.

• Filtragem por mudança de domínio, quando se emprega uma

represen-tação da imagem diferente da original como, por exemplo, no domínio de Fourier, Wavelet etc. (ver, por exemplo, [Jain 1989]).

• Filtragem estatística, quando o substrato teórico para construir o filtro

decorre das propriedades estocásticas dos dados observados.

1.5.1. Filtros lineares

Uma propriedade interessante dos filtros lineares invariantes por translação é que os mesmos ficam unicamente definidos por uma “máscara”. A másca-ra de ladoℓ(ímpar) que define todo filtro linear invariante por translação é o conjunto de valores reaismmm= (mi j)com−(ℓ − 1)/2 ≤ i, j ≤ (ℓ − 1)/2tal que

g(x, y) =

i, j

f(x + i, y + j)mi j, (3)

para toda coordenada(x, y) na grade que esteja convenientemente distante

(30)

sua aplicação é denotada porg= f ∗ mmm[Gomes and Velho 1994]. Embora a máscara tenha sido definida com suporte quadrado, qualquer tipo de suporte pode ser acomodado em um quadrado suficientemente grande preenchendo com zeros onde corresponder.

A filtragem por convolução é muito usada na prática devido à sua conexão com a filtragem no domínio de Fourier e pelo custo computacional relativa-mente baixo que ela demanda, já que estas operações consistem em realizar médias ponderadas dos dados de entrada (no domínio da imagem) ou, equiva-lentemente, produtos ponto a ponto no domínio de Fourier.

Sempre que desejável e possível, será utilizada uma notação compacta omitindo a coordenada, isto é, se a imagemgé o resultado da operação pontual ϒsobre cada valor f(s), então ao invés de escreverg= (g(s))s∈S= (ϒ( f (s)))s∈S será escritog( f ).

1.5.1.1. Filtro gaussiano

O filtro gaussiano é um filtro linear que é normalmente usado para suavizar imagens, removendo detalhes e ruído. Este filtro é bastante similar ao filtro da média neste sentido, porém usa uma máscara diferente que representa o formato de uma distribuição gaussiana. A densidade que caracteriza a distri-buição gaussiana bidimensional de média nula possui a forma:

G(x, y) = 1 2πσ2exp n −x 2+ y2 2σ2 o , (4) comσ> 0e(x, y) ∈R 2.

Para construir uma máscara de convolução para este filtro, basta produzir uma aproximação discreta para a função gaussiana. Uma máscara gaussiana bidimensional é definida pelo seu tamanho e desvio padrão. No código em

R abaixo, são construídas três máscaras gaussianas de tamanho11× 11

va-riando o valor deσ. Estas máscaras são aplicadas a uma imagem à qual foi

adicionado ruído gaussiano e, para tanto, faremos uso da bibliotecabiOps. A partir da linha 1 definimos as funções que auxiliam na construção das

máscaras gaussianas: meshgrid (que define os valores da grade sobre a

qual a máscara é montada), egaussian_mask(que efetivamente calcula os

valores da máscara, começando na linha 7). As linhas 16 e 17 padronizam a matriz de convolução de tal forma que a soma dos seus elementos seja unitária. Isto é feito para manter constante o brilho médio da imagem após a filtragem.

 1 > meshgrid <- function(x,y){ 2 ignore.arg2 <- function(x,y) {x} 3 list(x=t(outer(x,y,FUN=ignore.arg2)),y=outer(y,x, 4 + FUN=ignore.arg2)) 5 } 6

(31)

7 > gaussian_mask <- function(tamanho,sigma){ 8 tam <- (tamanho-1)/2 9 std <- sigma 10 mesh <- meshgrid(-tam:tam,-tam:tam) 11 x <- mesh$x 12 y <- mesh$y 13 arg <- -(x*x + y*y)/(2*std*std) 14 h <- exp(arg) 15 sumh <- sum(h) 16 if (sumh != 0) 17 h <- h/sumh 18 }  

A listagem a seguir calcula três matrizes de convolução gaussiana de

tama-nho5× 5com diferentes valores do parâmetroσ. As máscaras assim criadas

são mostradas nas equações (5), (6) e (7).

 1 > mascara1 = gaussian_mask(5, 1) 2 > mascara2 = gaussian_mask(5, 2) 3 > mascara10 = gaussian_mask(5, 10)   m1 =       0.003 0.013 0.022 0.013 0.003 0.013 0.060 0.098 0.060 0.013 0.022 0.098 0.162 0.098 0.022 0.013 0.060 0.098 0.060 0.013 0.003 0.013 0.022 0.013 0.003       , (5) m2 =       0.023 0.034 0.038 0.034 0.023 0.034 0.049 0.056 0.049 0.034 0.038 0.056 0.063 0.056 0.038 0.034 0.049 0.056 0.049 0.034 0.023 0.034 0.038 0.034 0.023       , (6) m10 =       0.039 0.040 0.040 0.040 0.039 0.040 0.040 0.041 0.040 0.040 0.040 0.041 0.041 0.041 0.040 0.040 0.040 0.041 0.040 0.040 0.039 0.040 0.040 0.040 0.039       . (7)

Nas equações (5), (6) e (7) constatamos que quanto maior o valor do

espa-lhamento,σ, menor será a diferença entre os valores nas máscaras. A razão

entre os valores máximo e mínimo na máscara comσ= 1é0.162/0.003 ≈ 55,

enquanto que na máscara comσ = 10é 0.041/0.039 ≈ 1. Assim sendo, na

(32)

pixel periférico, enquanto na segunda máscara todos os pixels terão aproxima-damente a mesma influência no resultado final aumentando, assim, o efeito do borramento. Esse efeito fica manifesto nos exemplos a seguir.

A filtragem por convolução pode ser feita utilizando a funçãoimgConvolve

do pacotebiOps, tal como mostrado a seguir.



1 > sertanejo = readJpeg("sertanejo.jpg")

2 > sertanejo_gauss = imgGaussianNoise(sertanejo, 0, 1000) 3 > filtrada1 = imgConvolve(sertanejo_gauss, mascara1) 4 > filtrada10 = imgConvolve(sertanejo_gauss, mascara10)

 

A linha 2 acima soma eventos de variáveis aleatórias gaussianas de média

nula e variância1000a cada valor de cada banda em cada coordenada da

ima-gem original (mostrada na Figura 1.11(a)). O resultado dessa contaminação é mostrado na Figura 1.11(b) A linha 3 e a seguinte calculam as imagens filtradas

por convolução com as máscaras definidas acima comσ= 1e comσ= 10.

A Figura 1.11 apresenta o resultado da filtragem usando duas das três más-caras produzidas pelo código. Nessa imagem percebemos que a convolução por uma máscara gaussiana reduz efetivamente o ruído, mas quanto mais in-tensa essa redução maior será o borramento introduzido na imagem.

1.5.1.2. Filtro laplaciano

O filtro laplaciano é um filtro passa-altas caracterizado por uma máscara

de tamanhoℓ × ℓque aproxima no domínio discreto a operação de derivação.

O valor central da máscara costuma ser positivo e cercado de valores nega-tivos nas direções norte-sul e leste-oeste e, geralmente, a soma dos pesos é zero. Com a aplicação deste filtro há um aumento de contraste na imagem filtrada, o que introduz, muitas vezes, bordas artificiais que podem confundir o observador. A Figura 1.12 mostra um exemplo de aplicação do filtro laplaciano.

NoReste filtro é implementado pela funçãolaplaciancomo mostrado

no código abaixo.  1 > library(rimage) 2 > imagem 3 size: 458 x 372 4 type: rgb 5 > plot.imagematrix(imagem) 6 > laplaciano <- normalize(laplacian(imagem)) 7 > plot.imagematrix(laplaciano)  

O filtro laplaciano, por ser um filtro que possue a propriedade de detectar bordas, pode ser utilizado para ajudar na segmentação de imagens baseada

(33)

em bordas, que busca separar áreas homogêneas (segmentos) pela identifica-ção das fronteiras entre elas.

1.5.2. Filtros não lineares

Esta família de filtros é maior do que a dos filtros lineares. No que segue veremos apenas dois membros dela: a mediana (que é um caso simples de filtro morfológico) e o filtro de Nagao-Matsuyama, que é um caso particular de filtro adaptativo. Para mais sobre morfologia matemática recomendamos os textos [Banon 2000, Banon and Barrera 1994].

1.5.2.1. Filtro da mediana

Alguns filtros, como o da média por exemplo, possuem limitações ao re-mover ruídos em uma imagem visto que os mesmos não preservam bordas e detalhes finos da imagem. Para contornar este problema, uma técnica al-ternativa é o filtro da mediana, que é um filtro não convolucional e não linear cujo efeito é similar ao dos filtros passa-baixas. Este filtro calcula o novo nível de cinza como o mediano daqueles observados no domínio da máscara. A mediana de uma máscarammmde ladoℓé dada por

med(mmm) = 

m(ℓ2+1)/2:ℓ2, seℓ2for ímpar;

(m2/2:ℓ2+ m2/2+1:ℓ2)/2, caso contrário,

ondemmm= (m1:2, . . . , m2:2)é o vetormmmordenado de menor para maior.

Com a aplicação deste filtro é possível eliminar, através de uma computa-ção simples e rápida, informações indesejáveis que corrompem a qualidade da imagem e, ao mesmo tempo, preservar as bordas na imagem. Devido a essa habilidade, o filtro da mediana é freqüentemente escolhido para suavizar ima-gens que apresentam ruídos conhecidos como “sal-e-pimenta”. O efeito visual do ruído “sal-e-pimenta”, ou Speckle, proporciona uma textura granulosa que pode dificultar a interpretação das imagens [Sinha and Hong 1990].

Uma desvantagem deste filtro é a de ser menos eficiente do que o da mé-dia para combater o ruído gaussiano aditivo (sinal de ruído com distribuição gaussiana).

NoR, o pacotebiOpsfornece a funçãoimgBlockMedianFilterque

im-plementa este filtro tendo como parâmetros a imagem a ser filtrada e o tama-nho da máscara a ser utilizada. O código abaixo mostra como usar esta função para filtrar a imagem que estamos utilizando com ruído “sal-e-pimenta”.

 1 > library(biOps) 2 > imagem_ruido <- imgSaltPepperNoise(imagem,10) 3 > imagem_ruido 4 size: 458 x 372 5 type: rgb 6 > plot.imagematrix(imagem_ruido)

Referências

Documentos relacionados

Ao contrário da opinião popular, a carne suína, além de não ser perigosa para a saúde, pode ser considerada uma aliada do homem no controle de uma série de enfermidades e, além

A produção de grãos de arroz irrigado com o efluente da carcinicultura foi semelhante à obtida pela irrigação com água de rio, quando foi utilizada na adubação a dose de

Os cupons fiscais somente poderão ser cadastrados uma única vez, não sendo possível concorrer mais de uma vez com a mesma compra; a tentativa de imputar o

Objeto: Autorizar a Interessada, inscrita no CNPJ/MF sob o nº 31.428.952/0001-34, a implantar e explorar a UFV Raios do Parnaíba I, CEG UFV.RS.PI.043203- 2.01, sob o regime de

Pode configurar as opções de áudio do seu computador no painel de controle de som ou no ícone de configuração de som Realtek HD na barra de tarefas ou no painel de controle.. O

uma forma eficiente de realizar a interseção entre duas esferas e duas cascas esféricas no R 3 , desejamos investigar o efeito de acrescentarmos mais uma casca esférica extra

Após, consegui contrato pelo estado e fui trabalhar em São Vendelino, em um grupo escolar com um quinto ano, tendo 36 alunos, sendo que dois alunos eram mais

Consulte a Secção 11 para obter informações pormenorizadas sobre sintomas e efeitos na saúde.. Classificação conforme Regulamentação (EC) 1272/2008 [CLP/GHS] SECÇÃO