Intro Pi Java

146
 Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 1 /146  Introdução ao Processamento de Imagens Digitais em Java / API JAI Escola de Verão da Unifesp Rafael Santos

Transcript of Intro Pi Java

Page 1: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 1/146

 

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 1 /146

 

Introdução ao Processamento deImagens Digitais em Java / API JAI

Escola de Verão da Unifesp

Rafael Santos

Page 2: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 2/146

 

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 2 /146

Objetivo

●  Apresentar conceitos, técnicas e exemplos básicos de

aplicação de processamento de imagens digitais.● Implementações em Java opcionalmente com a API JAI

(Java Advanced Imaging).● Parte reduzida do livro on-line Java Image Processing

Cookbook (http://www.lac.inpe.br/JIPCookbook/index.jsp).● Código! 

Page 3: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 3/146

 

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 3 /146

 

Introdução

Page 4: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 4/146Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 4 /146

Aplicações de Processamento de Imagens

● Sensoriamento Remoto: –

Geologia (estudo da composição da superfície). –  Agricultura (determinação da cobertura vegetal). – Engenharia Florestal (idem). – Cartografia (mapeamento da superfície). –

Meteorologia.● Medicina e Biologia.●  Astronomia (macro) e Física (micro).● Produção e Controle de Qualidade.● Segurança e Monitoramento.● Documentos, Web, etc.

 

Page 5: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 5/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 5 /146

Imagens Digitais

● Imagem = matriz de pixels.●

Pixel = medida, conjunto de medidas ou índice para tabelade valores.

● Metadados: dados adicionais sobre a imagem.

 

Page 6: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 6/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 6 /146

Imagens e Pixels

34 34 42 42 34 12 42

29 29 49 49 29 30 49

105 105 97 97 105 105 97

12 34 14 34 34 42 34

30 29 48 29 29 49 29

105 105 97 105 105 97 105

34 34 69 36 12 12 42

29 29 76 54 30 30 49

105 105 97 104 105 105 97

34 12 85 113 36 34 34

29 30 103 108 54 29 29

105 105 85 72 104 105 105

34 34 58 100 90 14 34

29 29 53 123 115 48 29

105 105 105 66 78 97 105

12 34 42 90 107 85 42

30 29 49 115 136 103 49

105 105 97 78 58 85 97

34 42 35 85 111 105 42

29 49 41 103 132 119 49

105 97 105 85 60 86 97

 

Page 7: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 7/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 7 /146

Tipos mais comuns

● Câmera Digital –

3264x2448 elementos sensores – Resolução: não se aplica – 3 bandas – Cada pixel é discretizado com

valores entre 0 e 255

● Scanner  –  Array móvel de elementos sensores

 – Resolução: 2400 DPI ou mais – 3 bandas – Discretização variável

 

Page 8: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 8/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 8 /146

Outros Tipos de Imagens Digitais

● Não somos limitados à imagens como as de câmeras e

scanners! – Pixels podem ter mais que três valores associados a eles. – Pixels podem ter valores fora do tradicional intervalo [0, 255]. – Pixels não precisam representar valores inteiros ou positivos!

● Exemplos: – Imagens multispectrais e hiperspectrais. – Imagens de modelos de terreno, médicas (Raio-X), etc.

 

Page 9: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 9/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 9 /146

Outros Tipos de Imagens Digitais

 

Page 10: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 10/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 10 /146

Outros Tipos de Imagens Digitais

 

Page 11: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 11/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 11 /146

Imagens Digitais: Multiespectrais

 

Page 12: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 12/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 12 /146

Imagens Digitais: Hiperespectrais

http://www.cossa.csiro.au/hswww/Overview.htm

 

Page 13: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 13/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 13 /146

 

Processamento de Imagens em Java

 

Page 14: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 14/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 14 /146

Processamento de Imagens em Java

● Preciso saber Java? –

 Ajuda e muito, mas não é imprescindível. – Experiência com C++, C#, outras linguagens pode ajudar.

● Todo o código está no livro on-line

(http://www.lac.inpe.br/JIPCookbook), completo e comentado.

 

Page 15: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 15/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 15 /146

Processamento de Imagens em Java

● Popularidade e flexibilidade de Java.●

Temos APIs para representação, visualização e I/O simplesde imagens como parte do JSE.● Temos a API Java Advanced Imaging para operações muito

mais poderosas, flexíveis e complexas!● E a questão da performance?

 – Melhor do que esperado! – Não estou preocupado com real time. – Mais valor à clareza e simplicidade de código.

 

Page 16: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 16/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 16 /146

Processamento de Imagens em Java: JAI

● Java (Swing) tem classes e operadores básicos.●

Java Advanced Imaging –  API adicional (download separado). – Projeto do java.net – público mas não totalmente aberto.

● Muitos operadores específicos para processamento de

imagens.● Execução postergada e cadeias de operadores.● Representação mais poderosa e flexível de imagens (tiles).●  Alguns operadores acelerados (implementação nativa).● Dúvida: terá apoio da Oracle?

 

Page 17: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 17/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 17 /146

 

Representação de Imagens em Java

 

R t ã d I J

Page 18: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 18/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 18 /146

Representação de Imagens: Java

Formato de representação na memória é diferente deformato de arquivo!

● Existem limitações mútuas.

RenderedImage

ColorModel Raster

SampleModel

DataBuffer

ColorSpace

 

R t ã d I Til dI (JAI)

Page 19: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 19/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 19 /146

Representação de Imagens: TiledImage (JAI)

 

R t ã d I

Page 20: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 20/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 20 /146

Representação de Imagens

RenderedImage

PlanarImage

WritableRenderedImage BufferedImage

RenderedOp

ImageJAI

 TiledImageAPI JAI

 

Page 21: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 21/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 21 /146

 

Criando Imagens em Java

 

Criando Imagens (sem JAI)

Page 22: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 22/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 22 /146

Criando Imagens (sem JAI)

Imagens simples (RGB, puro preto-e-branco, níveis de cinza;

pixels são arrays de bytes).

1.Criamos instância de BufferedImage.

2.Criamos instância de WritableRaster associada à

BufferedImage.

3.Manipulamos os pixels do WritableRaster.

 

Criando Imagens (sem JAI)

Page 23: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 23/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 23 /146

Criando Imagens (sem JAI)

public static void main(String[] args) throws IOException{

  int width = 256;int height = 256;BufferedImage image = new 

BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);WritableRaster raster = image.getRaster();

  int[] cor1 = new int[]{255,0,0};int[] cor2 = new int[]{0,0,255};int cont=0;

  for(int h=0;h<height;h++)  for(int w=0;w<width;w++)

{  if ((((w/32)+(h/32)) % 2) == 0)

raster.setPixel(w,h,cor1);else raster.setPixel(w,h,cor2);}

ImageIO.write(image,"PNG",new File("checkerboard.png"));}

 

Criando Imagens (com JAI)

Page 24: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 24/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 24 /146

Criando Imagens (com JAI)

Imagens simples (RGB, puro preto-e-branco, níveis de cinza) ou

multibandas; pixels podem ser arrays de qualquer tipo nativo.

1.Criamos instância de SampleModel usando

RasterFactory.

2.Criamos um TiledImage com este SampleModel.

3.Criamos um WritableRaster a partir da

TiledImage.

4.Manipulamos os pixels do WritableRaster.

 

Criando Imagens (com JAI)

Page 25: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 25/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 25 /146

Criando Imagens (com JAI)

int width = 640; int height = 640;SampleModel sampleModel =

RasterFactory.createBandedSampleModel(DataBuffer.TYPE_BYTE,

width,height,1);TiledImage tiledImage =

new TiledImage(0,0,width,height,0,0,sampleModel,null);WritableRaster wr = tiledImage.getWritableTile(0,0);for(int h=0;h<height/32;h++)  for(int w=0;w<width/32;w++)

{  int[] fill = new  int[32*32]; // A block of pixels...

Arrays.fill(fill,(int)(Math.random()*256)); wr.setSamples(w*32,h*32,32,32,0,fill);

}JAI.create("filestore",tiledImage,  "jaigl.png","PNG");

 

Criando Imagens (com JAI)

Page 26: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 26/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 26 /146

Criando Imagens (com JAI)

Para imagens com tiles é um pouco mais complicado...

1.Criamos instância de SampleModel usando

RasterFactory.

2.Criamos um TiledImage com este SampleModel.

3.Para cada tile:1.criamos um WritableRaster a partir da

TiledImage.

2. Manipulamos os pixels do WritableRaster.

 

Criando Imagens (com JAI)

Page 27: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 27/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 27 /146

Criando Imagens (com JAI)

int width = 483; int height = 483;int tWidth = 64; int tHeight = 64;SampleModel sampleModel =

RasterFactory.createBandedSampleModel(DataBuffer.TYPE_BYTE,tWidth,tHeight,3);

ColorModel cm = TiledImage.createColorModel(sampleModel);TiledImage tiledImage =

new TiledImage(0,0,width,height,0,0,sampleModel,cm);

// Create the colors.int[] red = new  int[]{255,0,0};int[] green = new  int[]{0,255,0};int[] blue = new  int[]{0,0,255};int[] yellow = new  int[]{255,255,0};int[] black = new  int[]{0,0,0};

 

Criando Imagens (com JAI)

Page 28: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 28/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 28 /146

Criando Imagens (com JAI)

for(int th=tiledImage.getMinTileY();th<=tiledImage.getMaxTileY();th++) for(int tw=tiledImage.getMinTileX();tw<=tiledImage.getMaxTileX();tw++)

{

WritableRaster wr = tiledImage.getWritableTile(tw,th);  for(int ih=0;ih<tHeight;ih++)  for(int iw=0;iw<tWidth;iw++)

{  int w = wr.getMinX()+iw;

int h = wr.getMinY()+ih;if ((w >= 17)&&(w < 17+216)&&(h >= 17)&&(h < 17+216))

wr.setPixel(w,h,red);else if ((w >= 250)&&(w < 250+216)&&(h >= 17)&&(h < 17+216))

 wr.setPixel(w,h,green);else if ((w >= 17)&&(w < 17+216)&&(h >= 250)&&(h < 250+216))

wr.setPixel(w,h,yellow);else if ((w >= 250)&&(w < 250+216)&&(h >= 250)&&(h < 250+216))

wr.setPixel(w,h,blue);

else wr.setPixel(w,h,black);}

}

 

Criando Imagens (com JAI)

Page 29: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 29/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 29 /146

Criando Imagens (com JAI)

TIFFEncodeParam tep = new TIFFEncodeParam();tep.setWriteTiled(true);

tep.setTileSize(tWidth,tHeight);JAI.create("filestore",tiledImage,"rgbtile.tiff","TIFF",tep);

 

Page 30: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 30/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 30 /146

 

 Armazenando e Recuperando Imagens

 

Entrada e Saída

Page 31: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 31/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 31 /146

Entrada e Saída

● Sem JAI (BufferedImage):

● Com JAI (PlanarImage):

public static void main(String[] args) throws IOException

{File f = new File(args[0]);BufferedImage image = ImageIO.read (f);System.out.println("Dimensões: "+

image.getWidth()+"x"+image.getHeight()+" pixels");}

public static void main(String[] args) throws IOException{

PlanarImage image = JAI.create("fileload",args[0]);System.out.println("Dimensões: "+image.getWidth()+"x"+image.getHeight()+" pixels");

}

 

Entrada e Saída

Page 32: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 32/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 32 /146

Entrada e Saída

● Sem JAI (BufferedImage):

● Com JAI (PlanarImage):

public static void main(String[] args) throws IOException  

{  int width = 256;int height = 256;BufferedImage image =new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);

...ImageIO.write(image,"PNG",new File("checkerboard.png"));

}

public static void main(String[] args) throws IOException{...

TiledImage tiledImage =new TiledImage(0,0,width,height,0,0,sampleModel,colorModel);

...JAI.create("filestore",tiledImage,"floatpattern.tif","TIFF");}

 

 

Page 33: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 33/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 33 /146

 Acesso Direto a Pixels

 

Acesso a pixels (sem JAI)

Page 34: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 34/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 34 /146

p ( )

public static void main(String[] args) throws IOException{File f = new File(args[0]);BufferedImage imagem = ImageIO.read (f);Raster raster = imagem.getRaster();

  int[] pixel = new int[3];  int brancos = 0;  for(int h=0;h<imagem.getHeight();h++)  for(int w=0;w<imagem.getWidth();w++)

{raster.getPixel(w,h,pixel);

  if ((pixel[0] == 255) && (pixel[1] == 255) &&(pixel[2] == 255)) brancos++;

}System.out.println(brancos+" pixels brancos");}

Memória!

 

Acesso a pixels (com JAI)

Page 35: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 35/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 35 /146

p ( )

public static void main(String[] args) throws IOException{File f = new File(args[0]);

BufferedImage imagem = ImageIO.read (f);RandomIter iterator =

RandomIterFactory.create(imagem,null);  int[] pixel = new int[3];  int brancos = 0;  for(int h=0;h<imagem.getHeight();h++)

  for(int w=0;w<imagem.getWidth();w++){iterator.getPixel(w,h,pixel);

  if ((pixel[0] == 255) && (pixel[1] == 255) &&(pixel[2] == 255)) brancos++;

}

System.out.println(brancos+" pixels brancos");}

● Existem também RectIter e RookIter.

 

 

Page 36: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 36/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 36 /146

Exibindo Imagens

 

Visualização de Imagens

Page 37: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 37/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 37 /146

● Componentes de interfaces gráficas para mostrar imagens.● Geralmente bem simples, melhorias como interatividade,

processamento, etc. ficam por conta do programador... – … o que é fácil de fazer graças ao mecanismo de herança!

● Conhecimentos de programação de interfaces gráficas em

Java são úteis: só conhecimento de design não adiantam.

 JFrameComponentes de UI

 

Display de Imagens (sem JAI)

Page 38: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 38/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 38 /146

public static void main(String[] args) throws IOException{BufferedImage image = ImageIO.read (new File(args[0]));

JFrame frame = new JFrame("Display Image: "+args[0]);ImageIcon icon = new ImageIcon(image);JLabel imageLabel = new JLabel(icon);frame.getContentPane().add(new JScrollPane(imageLabel));frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(600,300);

frame.setVisible(true);}

● BufferedImage → ImageIcon → JLabel 

(JScrollPane).

 

Display de Imagens (sem JAI)

Page 39: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 39/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 39 /146 

Display de Imagens (com JAI)

Page 40: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 40/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 40 /146

  public static void main(String[] args) throws IOException{BufferedImage image = ImageIO.read (new File(args[0]));

JFrame frame = new JFrame("Display Image: "+args[0]);DisplayJAI display = new DisplayJAI(image);frame.getContentPane().add(new JScrollPane(display));frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(600,300);frame.setVisible(true);

}

● DisplayJAI é mais flexível, permite alguma interação

(não implementada).●

Não é parte da API JAI (!?).

 

 

Page 41: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 41/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 41 /146

Exibindo Imagens(Soluções Específicas)

 

Imagens Sincronizadas

Page 42: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 42/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 42 /146

● Componente que mostra duas imagens sincronizadas: – Modificação no viewport de uma causa modificação no

viewport da outra.● Composição de instâncias de DisplayJAI.

 

Imagens Sincronizadas

Page 43: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 43/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 43 /146

public class DisplayTwoSynchronizedImages extends JPanelimplements AdjustmentListener

{  protected DisplayJAI dj1;  protected DisplayJAI dj2;  protected JScrollPane jsp1;  protected JScrollPane jsp2;

● Exibição de duas instâncias de DisplayJAI de forma

sincronizada.

 

Imagens Sincronizadas

Page 44: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 44/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 44 /146

public DisplayTwoSynchronizedImages(RenderedImage im1,RenderedImage im2)

{

  super();  // Cria componente com duas imagens com JScrollPanessetLayout(new GridLayout(1,2));

  dj1 = new DisplayJAI(im1);dj2 = new DisplayJAI(im2);jsp1 = new JScrollPane(dj1);jsp2 = new JScrollPane(dj2);

add(jsp1);add(jsp2);

  // Registra listeners para os scroll bars do JScrollPanes  jsp1.getHorizontalScrollBar().addAdjustmentListener(this);  jsp1.getVerticalScrollBar().addAdjustmentListener(this);  jsp2.getHorizontalScrollBar().addAdjustmentListener(this);  jsp2.getVerticalScrollBar().addAdjustmentListener(this);

}

 

Imagens Sincronizadas

Page 45: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 45/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 45 /146

public void adjustmentValueChanged(AdjustmentEvent e){

  if (e.getSource() == jsp1.getHorizontalScrollBar())

  jsp2.getHorizontalScrollBar().setValue(e.getValue());  if (e.getSource() == jsp1.getVerticalScrollBar())  jsp2.getVerticalScrollBar().setValue(e.getValue());  if (e.getSource() == jsp2.getHorizontalScrollBar())  jsp1.getHorizontalScrollBar().setValue(e.getValue());  if (e.getSource() == jsp2.getVerticalScrollBar())  jsp1.getVerticalScrollBar().setValue(e.getValue());

}

}

 

Imagens Sincronizadas: Exemplo

Page 46: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 46/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 46 /146

public class Borda{

  public static void main(String[] args)

{PlanarImage imagem = JAI.create("fileload", args[0]);

  float[] kernelMatrix = { -1, -2, -1,0, 0, 0,1, 2, 1 };

KernelJAI kernel = new KernelJAI(3,3,kernelMatrix);

PlanarImage bordas = JAI.create("convolve",imagem,kernel);JFrame frame = new JFrame("Bordas horizontais");frame.add(new DisplayTwoSynchronizedImages(imagem,bordas));frame.pack();frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);}

}

 

Imagens Sincronizadas: Exemplo

Page 47: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 47/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 47 /146 

Imagens Substitutas

Page 48: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 48/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 48 /146

● Uso de imagens substitutas (surrogate images):● Criamos uma imagem normalizada com pixels entre valores

0-255● Transformamos o tipo da imagem para bytes.● Uma classe que herda de DisplayJAI pode executar 

estes passos.

 

Imagens Substitutas

Page 49: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 49/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 49 /146

public class DisplaySurrogateImage extends DisplayJAI{

  protected PlanarImage surrogateImage;

 protected

 int

 width,height;public DisplaySurrogateImage(PlanarImage image){

  width = image.getWidth();  height = image.getHeight();  // Recuperamos valores extremos da imagem.

ParameterBlock pbMaxMin = new ParameterBlock();

pbMaxMin.addSource(image);PlanarImage extrema = JAI.create("extrema", pbMaxMin);  double[] allMins = (double[])extrema.getProperty("minimum");  double[] allMaxs = (double[])extrema.getProperty("maximum");  double minValue = allMins[0];  double maxValue = allMaxs[0];  for(int v=1;v<allMins.length;v++)

{  if (allMins[v] < minValue) minValue = allMins[v];  if (allMaxs[v] > maxValue) maxValue = allMaxs[v];

}

 

Imagens Substitutas

Page 50: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 50/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 50 /146

  // Reescalamos os níveis de cinza da imagem.  double[] subtract = new double[1]; subtract[0] = minValue;  double[] multiplyBy = new double[1];

multiplyBy[0] = 255./(maxValue-minValue);ParameterBlock pbSub = new ParameterBlock();pbSub.addSource(image);pbSub.add(subtract);

  surrogateImage = (PlanarImage)JAI.create("subtractconst",pbSub);ParameterBlock pbMult = new ParameterBlock();pbMult.addSource(surrogateImage);pbMult.add(multiplyBy);

  surrogateImage = (PlanarImage)JAI.create("multiplyconst",pbMult);  // Convertemos para bytes.

ParameterBlock pbConvert = new ParameterBlock();pbConvert.addSource(surrogateImage);pbConvert.add(DataBuffer.TYPE_BYTE);

  surrogateImage = JAI.create("format", pbConvert);  // Usamos esta imagem para display.

set(surrogateImage);}

 }

 

Imagens Substitutas

Page 51: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 51/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 51 /146

public class DemonstraDisplaySurrogateImage{

  public static void main(String[] args){PlanarImage image = JAI.create("fileload", args[0]);JFrame frame = new JFrame("Mostrando "+args[0]);frame.getContentPane().add(

  new JScrollPane(new DisplaySurrogateImage(image)));frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.pack();

frame.setVisible(true);}}

 

Imagens Substitutas: LUTs

Page 52: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 52/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 52 /146

● Uso de imagens substitutas (surrogate images) com LUTs:● Look-up Tables (LUTs): tabela de cores.

00 00 00 00

00 00 10 00

00 00 21 00

00 11 22 01

0 1131

255 02330 1240

255 25525510 11 22 11 0

00

11

22

32

23

00

00

01

12

12

00 11 32 01 022 12

00 00 21 00 022 01

00 00 10 00 011 00

00 00 00 00 000 00

0

0

0

0

0

12

3

R BGÍndice

 

Imagens Substitutas: LUTspublic void setLUT(short[][] lut)

Page 53: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 53/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 53 /146

public void setLUT(short[][] lut){SampleModel sampleModel = surrogateImage.getSampleModel();SampleModel newSampleModel =

RasterFactory.createBandedSampleModel(DataBuffer.TYPE_BYTE,sampleModel.getWidth(),sampleModel.getHeight(),3);

  byte[] reds = new  byte[256];  byte[] greens = new  byte[256];  byte[] blues = new  byte[256];  for(int i=0;i<256;i++)

{reds[i] = (byte)lut[i][0];

greens[i] = (byte)lut[i][1];blues[i] = (byte)lut[i][2];}

ColorModel colorModel = new IndexColorModel(8,256,reds,greens,blues);ImageLayout layout = new ImageLayout(surrogateImage);layout.setColorModel(colorModel);HashMap<RenderingHints.Key,ImageLayout> map =new HashMap<RenderingHints.Key,ImageLayout>();

map.put(JAI. KEY_IMAGE_LAYOUT,layout);RenderingHints hints = new RenderingHints(map);ParameterBlock pb = new ParameterBlock();pb.addSource(surrogateImage);PlanarImage newSurrogateImage = JAI.create("format",pb,hints);set(newSurrogateImage);}

 

Imagens Substitutas: LUTs/** Th i t d l t */

Page 54: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 54/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 54 /146

  /** The sin lut (rgb order) */  public final static short[][] sin_rgb()

{  short[][] lut = new  short[256][3];  for(short i=0;i<256;i++)

{

lut[i][0] = (short)(127*(1+Math.sin(Math.PI*(i-127)/255)));lut[i][1] = (short)(127*(1+Math.sin(Math.PI*(i )/255)));lut[i][2] = (short)(127*(1+Math.sin(Math.PI*(i+127)/255)));}

  return lut;}

  /** The inverted gray lut */  public final static short[][] invGray()

{  short[][] lut = new  short[256][3];

  for(short i=0;i<256;i++){lut[i][0] = (short)(255-i);lut[i][1] = (short)(255-i);lut[i][2] = (short)(255-i);}

  return lut;

}

 

Imagens Substitutas: LUTs

Page 55: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 55/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 55 /146

 

Desenhando em Imagens

P d bt t t áfi d ff d

Page 56: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 56/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 56 /146

● Podemos obter contextos gráficos de BufferedImages

e PlanarImages.. – .. e usá-los para desenhar sobre a imagem.

●  As imagens são modificadas (na memória) e podem ser 

visualizadas e/ou armazenadas com os gráficos.

 

Desenhando em ImagensBufferedImage baseImage ImageIO read(new File("sjc region png"))

Page 57: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 57/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 57 /146

BufferedImage baseImage = ImageIO.read(new File("sjc_region.png"));int[][] coords = new  int[][] {

{714,219},{822,256},

{797,329},{710,300},{711,293},{666,271}};

Path2D.Float regionOfInterest = new Path2D.Float();boolean isFirst = true;double firstX=0,firstY=0;

for(int[] coord:coords){  int x = coord[0]; int y = coord[1];  if (isFirst)

{regionOfInterest.moveTo(x,y);firstX = x;firstY = y;

isFirst = false;}

  else { regionOfInterest.lineTo(x,y); }}

regionOfInterest.lineTo(firstX,firstY);

 

Desenhando em ImagensPath2D Float pathForWholeImage = new Path2D Float();

Page 58: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 58/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 58 /146

Path2D.Float pathForWholeImage new Path2D.Float();pathForWholeImage.moveTo(0,0);pathForWholeImage.lineTo(baseImage.getWidth(),0);pathForWholeImage.lineTo(baseImage.getWidth(),baseImage.getHeight());

pathForWholeImage.lineTo(0,baseImage.getHeight());pathForWholeImage.lineTo(0,0);Area wholeImage = new Area(pathForWholeImage);

 wholeImage.subtract(new Area(regionOfInterest));

Graphics2D g2d = (Graphics2D)baseImage.getGraphics();g2d.setRenderingHint(RenderingHints. KEY_ANTIALIASING,

RenderingHints.VALUE_ANTIALIAS_ON );g2d.setColor(new Color(255,255,255,100));g2d.fill(wholeImage);g2d.setStroke(new BasicStroke(5f));g2d.setColor(new Color(255,0,0,200));g2d.draw(regionOfInterest);

JFrame frame = new JFrame("Highlighting image regions");

ImageIcon icon = new ImageIcon(baseImage);JLabel label = new JLabel(icon);frame.getContentPane().add(new JScrollPane(label));frame.setDefaultCloseOperation(JFrame. EXIT_ON_CLOSE);frame.pack(); frame.setVisible(true);

 

Desenhando em Imagens

Page 59: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 59/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 59 /146

 

 

Page 60: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 60/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 60 /146

Operadores da API JAI

 

Operadores da API JAI: Introdução

● Classe JAI provê método create

Page 61: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 61/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 61 /146

● Classe JAI provê método create.● Vários operadores são registrados, chamados de forma

unificada.● Parâmetros (se houver) são passados através de instância

de ParameterBlock.

● Método retorna instância de RenderedOp → cast paraPlanarImage se necessário.

 

Relembrando: Representação de Imagens

Page 62: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 62/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 62 /146

RenderedImage

PlanarImage

WritableRenderedImage BufferedImage

RenderedOp

ImageJAI

 TiledImageAPI JAI

 

Operadores da API JAI: invert 

● Inverte os valores dos pixels

Page 63: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 63/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 63 /146

● Inverte os valores dos pixels. – Tipos com sinal: saída = -entrada

 – Tipos sem sinal: saída = máximo - entrada

public static void main(String[] args){PlanarImage input = JAI.create("fileload", args[0]);PlanarImage output = JAI.create("invert", input);

JFrame frame = new JFrame();frame.setTitle("Invert image "+args[0]);frame.getContentPane().add(

  new DisplayTwoSynchronizedImages(input,output));frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.pack();frame.setVisible(true);

}

 

Operadores da API JAI: invert

Page 64: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 64/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 64 /146

 

Operadores da API JAI: binarize

● Transforma pixels em valores binários por comparação com

Page 65: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 65/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 65 /146

Transforma pixels em valores binários por comparação com

constante (1 se ≥ constante).

public static void main(String[] args){PlanarImage imagem = JAI.create("fileload", args[0]);ParameterBlock pb = new ParameterBlock();pb.addSource(imagem);pb.add(127.0);PlanarImage binarizada = JAI.create("binarize", pb);JFrame frame = new JFrame("Imagem binarizada");frame.add(new DisplayTwoSynchronizedImages(imagem,binarizada));frame.pack();frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);

}

 

Operadores da API JAI: binarize

Page 66: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 66/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 66 /146

 

Operadores da API JAI: convolve

● Convolução com um kernel

Page 67: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 67/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 67 /146

Convolução com um kernel . – Este exemplo: suavização.

  public static void main(String[] args){PlanarImage imagem = JAI.create("fileload", args[0]);

  float[] kernelMatrix = { 1f/25f, 1f/25f, 1f/25f, 1f/25f, 1f/25f,1f/25f, 1f/25f, 1f/25f, 1f/25f, 1f/25f,1f/25f, 1f/25f, 1f/25f, 1f/25f, 1f/25f,1f/25f, 1f/25f, 1f/25f, 1f/25f, 1f/25f,1f/25f, 1f/25f, 1f/25f, 1f/25f, 1f/25f};

KernelJAI kernel = new KernelJAI(5,5,kernelMatrix);PlanarImage bordas = JAI.create("convolve",imagem,kernel);JFrame frame = new JFrame("Suavização da imagem");frame.add(new DisplayTwoSynchronizedImages(imagem,bordas));frame.pack();frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);}

 

Operadores da API JAI: convolve

Page 68: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 68/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 68 /146

 

Operadores da API JAI: convolve

● Convolução com um kernel.

Page 69: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 69/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 69 /146

Convolução com um kernel . – Este exemplo: detecção de bordas horizontais (Sobel).

  public static void main(String[] args){PlanarImage imagem = JAI.create("fileload", args[0]);

  float[] kernelMatrix = { -1, -2, -1,0, 0, 0,1, 2, 1 };

KernelJAI kernel = new KernelJAI(3,3,kernelMatrix);PlanarImage bordas = JAI.create("convolve",imagem,kernel);JFrame frame = new JFrame("Bordas horizontais");frame.add(new DisplayTwoSynchronizedImages(imagem,bordas));frame.pack();frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);}

 

Operadores da API JAI: convolve

Page 70: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 70/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 70 /146

 

Operadores da API JAI: dilate

● Expansão de regiões da imagem com elemento estrutural.

Page 71: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 71/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 71 /146

p g g  public static void main(String[] args)

{PlanarImage imagem = JAI.create("fileload", args[0]);

  float[] estrutura = { 0, 0, 0, 0, 0, 0, 0,0, 1, 1, 1, 1, 1, 0,0, 1, 1, 1, 1, 1, 0,0, 1, 1, 1, 1, 1, 0,0, 1, 1, 1, 1, 1, 0,0, 1, 1, 1, 1, 1, 0,

0, 0, 0, 0, 0, 0, 0};KernelJAI kernel = new KernelJAI(7,7,estrutura);ParameterBlock p = new ParameterBlock();p.addSource(imagem);p.add(kernel);PlanarImage dilatada = JAI.create("dilate",p);JFrame frame = new JFrame("Imagem dilatada");

frame.add(new DisplayTwoSynchronizedImages(imagem,dilatada));frame.pack();frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);}

 

Operadores da API JAI: dilate

Page 72: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 72/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 72 /146

Regiões brancas são dilatadas!

 

Operadores da API JAI: erode

● Redução de regiões da imagem com elemento estrutural.

Page 73: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 73/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 73 /146

ç g g  public static void main(String[] args)

{

PlanarImage imagem = JAI.create("fileload", args[0]);  float[] estrutura = { 0, 0, 0, 0, 0, 0, 0,

0, 1, 1, 1, 1, 1, 0,0, 1, 1, 1, 1, 1, 0,0, 1, 1, 1, 1, 1, 0,0, 1, 1, 1, 1, 1, 0,0, 1, 1, 1, 1, 1, 0,

0, 0, 0, 0, 0, 0, 0};KernelJAI kernel = new KernelJAI(7,7,estrutura);ParameterBlock p = new ParameterBlock();p.addSource(imagem);p.add(kernel);PlanarImage erodida = JAI.create("erode",p);JFrame frame = new JFrame("Imagem erodida");

frame.add(new DisplayTwoSynchronizedImages(imagem,erodida));frame.pack();frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);}

 

Operadores da API JAI: erode

Page 74: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 74/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 74 /146

Regiões brancas são dilatadas!

 

Operadores da API JAI: rotate

● Rotação dos pixels da imagem em redor de um ponto.

Page 75: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 75/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 75 /146

  public static void main(String[] args)

{PlanarImage imagem = JAI.create("fileload",args[0]);  float angle = (float)Math.toRadians(45);  // Usamos o centro da imagem para rotação  float centerX = imagem.getWidth()/2f;  float centerY = imagem.getHeight()/2f;

ParameterBlock pb = new ParameterBlock();

pb.addSource(imagem);pb.add(centerX);pb.add(centerY);pb.add(angle);pb.add(new InterpolationBilinear());PlanarImage rotacionada = JAI.create("rotate", pb);JFrame frame = new JFrame("Imagem rotacionada");frame.add(new DisplayTwoSynchronizedImages(imagem,rotacionada));frame.pack();frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);}

 

Operadores da API JAI: rotate

Page 76: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 76/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 76 /146

Coordenadas dos cantos daimagem rotacionada:(-39, -136) – (558, 461)

 

Translação da Origem de ImagensOriginal Região para recorte

Page 77: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 77/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 77 /146

Origem200,200

 Tamanho400x300

Região recortada Recorte e translaçãoMínimo

200,200

 Tamanho400x300

Máximo600,500

Mínimo0,0

 Tamanho400x300

Máximo400,300

 

Operadores da API JAI: rotate

● JAI permite imagens com pixels com coordenadas negativas!

Page 78: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 78/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 78 /146

 – DisplayJAI, ImageIO e

JAI.create(“filestore”) não. – Solução: mover a origem da imagem com o operador 

translate.public static void main(String[] args){

PlanarImage imagem = JAI.create("fileload",args[0]);  float angle = (float)Math.toRadians(45);  // Usamos o centro da imagem para rotação  float centerX = imagem.getWidth()/2f;  float centerY = imagem.getHeight()/2f;ParameterBlock pb = new ParameterBlock();pb.addSource(imagem);

pb.add(centerX);pb.add(centerY);pb.add(angle);pb.add(new InterpolationBilinear());PlanarImage rotacionada = JAI.create("rotate", pb);

 

Operadores da API JAI: rotate

  // Ajustamos a origem da imagempb = new ParameterBlock();

Page 79: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 79/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 79 /146

pb new ParameterBlock();pb.addSource(rotacionada);

pb.add((float)-rotacionada.getMinX());pb.add((float)-rotacionada.getMinY());PlanarImage rotacionadaOK =

JAI.create("translate",pb,null);JFrame frame = new JFrame("Imagem rotacionada");frame.add(

  new DisplayTwoSynchronizedImages(imagem,rotacionadaOK));frame.pack();frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);}

 

Operadores da API JAI: rotate

Page 80: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 80/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 80 /146

 

Operadores da API JAI: scale

●  Aumenta ou diminui a quantidade de pixels na imagem.V l d i l d i l d

Page 81: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 81/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 81 /146

 – Valores dos pixels podem ser interpolados.

  public static void main(String[] args){PlanarImage imagem = JAI.create("fileload",args[0]);

  float scale = 0.3f;ParameterBlock pb = new ParameterBlock();pb.addSource(imagem);pb.add(scale);pb.add(scale);pb.add(0.0F);pb.add(0.0F);pb.add(new InterpolationNearest());PlanarImage reescalada = JAI.create("scale", pb);JFrame frame = new JFrame("Imagem reescalada");

frame.add(new DisplayTwoSynchronizedImages(imagem,reescalada));frame.pack();frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);}

 

Operadores da API JAI: scale

Page 82: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 82/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 82 /146

 

Operadores da API JAI: crop, translate, scale

● Pequena aplicação que recorta e amplia uma região em uma

i

Page 83: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 83/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 83 /146

imagem.● Parâmetros passados pela linha de comando.public static void main(String[] args){PlanarImage imagem = JAI.create("fileload",args[0]);ParameterBlock pb = new ParameterBlock();

  float x = Float.parseFloat(args[1]);  float y = Float.parseFloat(args[2]);  float w = Float.parseFloat(args[3]);  float h = Float.parseFloat(args[4]);  float z = Float.parseFloat(args[5]);

 

Operadores da API JAI: crop, translate, scale

  // Recortab ddS (i )

Page 84: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 84/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 84 /146

pb.addSource(imagem);pb.add(x);pb.add(y);pb.add(w);pb.add(h);PlanarImage recortada = JAI.create("crop",pb,null);

  // Reposicionapb = new ParameterBlock();pb.addSource(recortada);pb.add((float)-x);pb.add((float)-y);PlanarImage recortadaOK = JAI.create("translate",pb,null);

 

Operadores da API JAI: crop, translate, scale

  // Amplia (2 versões)pb = new ParameterBlock();

Page 85: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 85/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 85 /146

pb.addSource(recortadaOK);

pb.add(z);pb.add(z);pb.add(0.0F);pb.add(0.0F);pb.add(new InterpolationNearest());PlanarImage resultado1 = JAI.create("scale", pb);

pb =new

ParameterBlock();pb.addSource(recortadaOK);pb.add(z);pb.add(z);pb.add(0.0F);pb.add(0.0F);

pb.add(new

InterpolationBicubic(2));PlanarImage resultado2 = JAI.create("scale", pb);

 

Operadores da API JAI: crop, translate, scale

JFrame frame = new JFrame("Recorte ampliado");frame.add(

Di l T S h i dI ( l d 1 l d 2))

Page 86: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 86/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 86 /146

  new DisplayTwoSynchronizedImages(resultado1,resultado2));frame.pack();frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);}

 java wvc/operadores/Recorta astro013.jpg 461 896 24 27 20

 

Operadores da API JAI: histogram

● Operador sem imagem resultante: calcula histogramas em

uma imagem

Page 87: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 87/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 87 /146

uma imagem.

 – Histogramas são recuperadors como propriedades doRenderedOp resultante.

public static void main(String[] args){

PlanarImage image = JAI.create("fileload", args[0]);  // Primeiro histograma com 256 bins.ParameterBlock pb1 = new ParameterBlock();pb1.addSource(image);pb1.add(null);pb1.add(1); pb1.add(1);pb1.add(new int[]{256});

pb1.add(new double[]{0}); pb1.add(new double[]{256});PlanarImage dummyImage1 = JAI.create("histogram", pb1);Histogram histo1 =(Histogram)dummyImage1.getProperty("histogram");

 

Operadores da API JAI: histogram

  // Segundo histograma com 32 bins.ParameterBlock pb2 = new ParameterBlock();pb2 addSource(image);

Page 88: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 88/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 88 /146

pb2.addSource(image);pb2.add(null);

pb2.add(1); pb2.add(1);pb2.add(new int[]{32});pb2.add(new double[]{0}); pb2.add(new double[]{256});PlanarImage dummyImage2 = JAI.create("histogram", pb2);Histogram histo2 =(Histogram)dummyImage2.getProperty("histogram");

  // Exibimos os histogramas usando um componente específico.JFrame f = new JFrame("Histogramas");DisplayHistogram dh1 = new DisplayHistogram(histo1,"256 bins");dh1.setBinWidth(2); dh1.setHeight(160); dh1.setIndexMultiplier(1);DisplayHistogram dh2 = new DisplayHistogram(histo2,"32 bins");dh2.setBinWidth(16); dh2.setHeight(160);dh2.setIndexMultiplier(8);dh2.setSkipIndexes(2);

f.getContentPane().setLayout(new GridLayout(2,1));f.getContentPane().add(dh1); f.getContentPane().add(dh2);f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);f.pack(); f.setVisible(true);}

 

Operadores da API JAI: histogram

Page 89: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 89/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 89 /146

 

Aplicação: Pan Sharpening 

●  Alguns satélites tem bandas com resoluções diferentes.● Podemos usar combinações de bandas (cores e

Page 90: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 90/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 90 /146

● Podemos usar combinações de bandas (cores e

pancromáticas) para obter melhor resolução espacial.

 

Aplicação: Pan Sharpening PlanarImage iRed = JAI.create("fileload",args[0]);PlanarImage iGreen = JAI.create("fileload",args[1]);PlanarImage iBlue = JAI.create("fileload",args[2]);

Page 91: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 91/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 91 /146

PlanarImage panImage = JAI.create("fileload",args[3]);ParameterBlock pb = new ParameterBlock();pb.addSource(iRed);pb.addSource(iGreen);pb.addSource(iBlue);PlanarImage rgbImage = JAI.create("bandmerge", pb);

pb = new ParameterBlock();pb.addSource(rgbImage);

float scaleX = (1f*panImage.getWidth()/iRed.getWidth());float scaleY = (1f*panImage.getHeight()/iRed.getHeight());pb.add(scaleX);pb.add(scaleY);rgbImage = JAI.create("scale",pb);

 

Aplicação: Pan Sharpening IHSColorSpace ihs = IHSColorSpace.getInstance();ColorModel IHSColorModel =  new ComponentColorModel(ihs,

Page 92: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 92/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 92 /146

  new  int []{8,8,8},

  false,false,Transparency.OPAQUE,DataBuffer.TYPE_BYTE);

pb = new ParameterBlock();pb.addSource(rgbImage);pb.add(IHSColorModel);RenderedImage imageIHS = JAI.create("colorconvert", pb);

PlanarImage[] IHSBands = new PlanarImage[3];for(int band=0;band<3;band++)

{pb = new ParameterBlock();pb.addSource(imageIHS);

pb.add(new 

 int

[]{band});IHSBands[band] = JAI.create("bandselect",pb);}

 

Aplicação: Pan Sharpening ImageLayout imageLayout = new ImageLayout();imageLayout.setColorModel(IHSColorModel);imageLayout.setSampleModel(imageIHS.getSampleModel());

Page 93: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 93/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 93 /146

RenderingHints rendHints =

new RenderingHints(JAI. KEY_IMAGE_LAYOUT,imageLayout);pb = new ParameterBlock();pb.addSource(panImage);pb.addSource(IHSBands[1]);pb.addSource(IHSBands[2]);RenderedImage panSharpenedIHSImage =

JAI.create("bandmerge", pb, rendHints);

pb = new ParameterBlock();pb.addSource(panSharpenedIHSImage);pb.add(rgbImage.getColorModel()); // RGB color modelPlanarImage finalImage = JAI.create("colorconvert", pb);

JFrame frame = new JFrame("IHS Pan Sharpening");

frame.add(new DisplayTwoSynchronizedImages(rgbImage,finalImage));frame.pack();frame.setDefaultCloseOperation(JFrame. EXIT_ON_CLOSE);frame.setVisible(true);

 

Aplicação: Pan Sharpening 

Page 94: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 94/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 94 /146

 

Aplicação: Pan Sharpening 

Page 95: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 95/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 95 /146

 

 

Page 96: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 96/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 96 /146

Criando Novos Operadorescom a API JAI

 

Criando Novos Operadores● Qual tipo de operação estamos implementando?

 – SourcelessOpImage: operadores sem imagens de entrada.

Page 97: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 97/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 97 /146

p g p g

 – PointOpImage: pixels da saída dependem dos mesmos pixelsda entrada.

 – AreaOpImage: pixels da saída dependem de área ao redor dos

da entrada.

 – GeometricOpImage: pixels da saída podem depender detodos da entrada.

 – StatisticsOpImage: operadores que calculam estatísticas

sobre imagem de entrada.

 

Criando Novos Operadores● Receita de bolo (relativamente) simples para imagens

renderizadas.

Page 98: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 98/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 98 /146

1.Criar classe que herda de XXXOpImage. – Como XXXOpImage é abstrata, devemos implementar métodos

que fazem o processamento (quase sempre computeTile).

2.Criar classe que implementa

RenderedImageFactory. – Implementa método create.

 

Criando Novos Operadores3.Criar classe que implementa OperationDescriptor 

ou herda de OperationDescriptorImpl, que

Page 99: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 99/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 99 /146

p p p , q

descreve os parâmetros e valores default do operador.4.Registrar o novo operador junto ao

OperationRegistry e RIFRegistry (podemos

criar método para registro na classe do passo anterior).

 

Novo Operador: segmenta3● Segmentador por limiar semelhante a binarize, mas

com 2 limiares.

Page 100: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 100/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 100 /146

● Classe que herda de PointOpImage. – Contém construtor para inicializar atributos e método

computeTile.

public class Segmenta3OpImage extends PointOpImage

{  private RenderedImage source;  private int threshold1,threshold2;

  public Segmenta3OpImage(RenderedImage source,int th1,int th2,ImageLayout layout,RenderingHints hints,

  boolean b)

{  super(source,layout,hints,b);  this.source = source;  this.threshold1 = th1; this.threshold2 = th2;

}

Passo 1

 

Novo Operador: segmenta3  public Raster computeTile(int x,int y)

{Raster r = source.getTile(x,y);int minX = r getMinX();

Passo 1

Page 101: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 101/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 101 /146

  int minX = r.getMinX();

  int minY = r.getMinY();  int width = r.getWidth();  int height = r.getHeight();  // Criamos um WritableRaster da região sendo considerada.

WritableRaster wr =r.createCompatibleWritableRaster(minX,minY,width,height);

  for(int l=0;l<r.getHeight();l++)

  for(int c=0;c<r.getWidth();c++)  for(int b=0;b<r.getNumBands();b++)

{  int p = r.getSample(c+minX,l+minY,b);  if (p < threshold1) p = 0;

else if (p > threshold2) p = 255;  else p = 127;

wr.setSample(c+minX,l+minY,b,p);}

  return wr;}

 

Novo Operador: segmenta3

Passo 2public class Segmenta3RIF implements RenderedImageFactory

Page 102: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 102/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 102 /146

p g p g y

{  public RenderedImage create(ParameterBlock paramBlock,RenderingHints hints)

{RenderedImage source = paramBlock.getRenderedSource(0);

  int threshold1 = paramBlock.getIntParameter(0);

  int threshold2 = paramBlock.getIntParameter(1);ImageLayout layout = new ImageLayout(source);  return new Segmenta3OpImage(source,threshold1,threshold2,

layout,hints,false);}

}

 

Novo Operador: segmenta3

Passo 3public class Segmenta3Descriptor extends OperationDescriptorImpl{

Page 103: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 103/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 103 /146

{

  private static final String opName = "segmenta3";  private static final String vendorName =

"Hypothetical Image Processing Lab";  private static final String[][] resources =

{{"GlobalName", opName},{"LocalName", opName},{"Vendor", vendorName},{"Description","A simple 3-level image segmentation operator"},{"DocURL", "http://www.lac.inpe.br/~rafael.santos"},{"Version", "1.0"},{"arg0Desc", "First Threshold Value"},{"arg1Desc", "Second Threshold Value"}

};  private static final String[] supportedModes = {"rendered"};

 

Novo Operador: segmenta3

Passo 3

private static final String[] paramNames = {"1st threshold",

Page 104: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 104/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 104 /146

p a e s a c a S g[] pa a a es { s es o d ,

  "2nd threshold"};  private static final Class[] paramClasses = {Integer.class,Integer.class};

  private static final Object[] paramDefaults = {new Integer(85),  new Integer(170) };  private static final Range[] validParamValues =

{

  new Range(Integer.class, Integer. MIN_VALUE, Integer. MAX_VALUE),  new Range(Integer.class, Integer. MIN_VALUE, Integer. MAX_VALUE)

};  private static final int numSources = 1;  private static boolean registered = false;

 

Novo Operador: segmenta3

Passo 3/4 public Segmenta3Descriptor(){

  super(resources,supportedModes,numSources,paramNames,paramClasses paramDefaults validParamValues);

Page 105: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 105/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 105 /146

  paramClasses,paramDefaults,validParamValues);

}

  public static void register(){

  if (!registered ){OperationRegistry op =JAI.getDefaultInstance().getOperationRegistry();

Segmenta3Descriptor desc = new Segmenta3Descriptor();op.registerDescriptor(desc);Segmenta3RIF rif = new Segmenta3RIF();RIFRegistry.register(op,opName,vendorName,rif);

  registered = true;

}}

 

Novo Operador: segmenta3  public static void main(String[] args)

{Segmenta3Descriptor.register();PlanarImage imagem = JAI.create("fileload", args[0]);

Page 106: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 106/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 106 /146

g g ( , g [ ]);

ParameterBlock p = new ParameterBlock();p.addSource(imagem);p.add(new Integer(120));p.add(new Integer(200));PlanarImage resultado = JAI.create("segmenta3",p);JFrame frame = new JFrame("Imagem binarizada");frame.add(new DisplayTwoSynchronizedImages(imagem,resultado));

frame.pack();frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);}

 

Novo Operador: contapixels● Conta número de pixels com cor semelhante a um parâmetro

(com tolerância).

Page 107: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 107/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 107 /146

Classe que herda de StatisticsOpImage. – Contém construtor para inicializar atributos e vários métodos para

acumular estatísticas.

Passo 1

public class ContaPixelsOpImage extends StatisticsOpImage

{  private Color target;  private Float tolerance;private Long count;

 public ContaPixelsOpImage(RenderedImage source,

Color target,Float tolerance)

{  super(source,null,source.getMinX(),source.getMinY(),1,1);  this.target = target; this.tolerance = tolerance;  count = null;

}

 

Novo Operador: contapixelsPasso 1

  protected void accumulateStatistics(String name, Raster raster,Object stats)

Page 108: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 108/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 108 /146

{  if (count == null) count = new Long(0);  int r,g,b;  for(int l=0;l<raster.getHeight();l++)  for(int c=0;c<raster.getWidth();c++)

{  int x = raster.getMinX()+c;

  int y = raster.getMinY()+l;r = raster.getSample(x,y,0);g = raster.getSample(x,y,1);b = raster.getSample(x,y,2);

  float dist = (target.getRed()-r)*(target.getRed()-r)+(target.getGreen()-g)*(target.getGreen()-g)+(target.getBlue()-b)*(target.getBlue()-b);

  if (dist<=tolerance*tolerance) count++;}

}

 

Novo Operador: contapixelsPasso 1 protected Object createStatistics(String arg0)

{  if (count == null) count = new Long(0);  return count;

Page 109: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 109/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 109 /146

;

} protected String[] getStatisticsNames(){

  return new String[]{"count"};}

 

public Object getProperty(String name){

  if (count == null) super.getProperty(name);  return count;

}

 

Novo Operador: contapixels

Passo 2

public class ContaPixelsRIF implements RenderedImageFactory

Page 110: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 110/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 110 /146

public class ContaPixelsRIF implements RenderedImageFactory

{  public RenderedImage create(ParameterBlock paramBlock,

RenderingHints hints){RenderedImage source = paramBlock.getRenderedSource(0);Color target = (Color)paramBlock.getObjectParameter(0);Float tolerance = (Float)paramBlock.getObjectParameter(1);

  return new ContaPixelsOpImage(source,target,tolerance);}

}

 

Novo Operador: contapixels

Passo 3public class ContaPixelsDescriptor extends OperationDescriptorImpl{

Page 111: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 111/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 111 /146

{  private static final String opName = "contapixels";  private static final String vendorName =

"Hypothetical Image Processing Lab";  private static final String[][] attributes =

{{"GlobalName", opName},

{"LocalName", opName},{"Vendor", vendorName},{"Description", "A simple RGB pixel counting operator"},{"DocURL", "http://www.lac.inpe.br/~rafael.santos"},{"Version", "1.0"},{"arg0Desc", "Target value (color used for similarity)"},{"arg1Desc", "Tolerance value"},

};  private static final String[] modes = {"rendered"};

 

Novo Operador: contapixelsPasso 3

  private static final int numSources = 1;  private static final String[] paramNames = {attributes[6][0],

attributes[7][0]};

Page 112: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 112/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 112 /146

  attributes[7][0]};  private static final Class[] paramClasses = {Color.class,

Float.class};  private static final Object[] paramDefaults =

{ new Color(0,0,0),new Float(0) };  private static boolean registered = false;

  public ContaPixelsDescriptor(){  super(attributes, modes,numSources,paramNames,

paramClasses,paramDefaults,null);}

 

Novo Operador: contapixelsPasso 4

  public static void register(){

Page 113: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 113/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 113 /146

  if (!registered ){OperationRegistry op =JAI.getDefaultInstance().getOperationRegistry();

ContaPixelsDescriptor desc = new ContaPixelsDescriptor();op.registerDescriptor(desc);ContaPixelsRIF rif = new ContaPixelsRIF();

RIFRegistry.register(op,opName,vendorName,rif);  registered = true;

}}

 

Novo Operador: contapixels  public static void main(String[] args)

{ContaPixelsDescriptor.register();PlanarImage input = JAI.create("fileload", args[0]);

Page 114: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 114/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 114 /146

  int r = Integer.parseInt(args[1]);  int g = Integer.parseInt(args[2]);  int b = Integer.parseInt(args[3]);  float t = Float.parseFloat(args[4]);

Color color = new Color(r,g,b);ParameterBlock p = new ParameterBlock();p.addSource(input);

p.add(color);p.add(t);PlanarImage output = JAI.create("contapixels",p);Long count = (Long)output.getProperty("count");System.out.println("Existem "+count+

  " pixels com cores semelhantes a "+color);}

 

 

Page 115: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 115/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 115 /146

Extras: I/O

 

Que formatos são suportados?public static void main(String[] args)

{String[] iFormatos = ImageIO.getReaderMIMETypes();System.out.println("Leitura: ");

Page 116: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 116/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 116 /146

  for(String f:iFormatos){System.out.print(f+" ");}

System.out.println("\nGravação: ");String[] oFormatos = ImageIO.getWriterMIMETypes();

  for(String f:oFormatos){System.out.print(f+" ");}

System.out.println();}

Leitura:image/jpeg image/png image/x-png image/vnd.wap.wbmp image/gif image/bmpGravação:image/png image/jpeg image/x-png image/vnd.wap.wbmp image/bmp image/gif

 

Compactando Imagens● Forma mais simples: abrir imagem em formato menos

compactado e salvar em formato mais compactado.●

Page 117: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 117/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 117 /146

Lembrar sempre que existe perda de informações com JPEGe GIF!

● Método mais inteligente: controlar a compactação.

 

Como compactar mais?  public static void main(String[] args) throws IOException

{  // Load the image (it is hard-coded here to make the code

// simpler).String imageFile = "/tmp/folhas.tif";

Page 118: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 118/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 118 /146

Veja mais em http://www.lac.inpe.br/JIPCookbook

String imageFile /tmp/folhas.tif ;BufferedImage i = ImageIO.read (new File(imageFile));

  showImage("Original Image", i);  // Show results with different compression ratio.  compressAndShow (i, 0.5f);

}

 

Como compactar mais?public static void compressAndShow(BufferedImage image, float quality)throws IOException{

  // Get a ImageWriter for jpeg format.Iterator<ImageWriter> writers = ImageIO.getImageWritersBySuffix("jpeg");

Page 119: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 119/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 119 /146

  if (!writers.hasNext())throw new IllegalStateException("No writers found");ImageWriter writer = (ImageWriter) writers.next();

  // Create the ImageWriteParam to compress the image.ImageWriteParam param = writer.getDefaultWriteParam();param.setCompressionMode(ImageWriteParam. MODE_EXPLICIT );param.setCompressionQuality(quality);

  // The output will be a ByteArrayOutputStream (in memory)ByteArrayOutputStream bos = new ByteArrayOutputStream(32768);ImageOutputStream ios = ImageIO.createImageOutputStream(bos);writer.setOutput(ios);writer.write(null, new IIOImage(image, null, null), param);ios.flush(); // otherwise the buffer size will be zero!

  // From the ByteArrayOutputStream create a RenderedImage.ByteArrayInputStream in = new ByteArrayInputStream(bos.toByteArray());

RenderedImage out = ImageIO.read (in);  int size = bos.toByteArray().length;  showImage("Compressed to " + quality + ": " + size + " bytes", out);}

Veja mais em http://www.lac.inpe.br/JIPCookbook

 

Como compactar mais?  private static void showImage(String title,RenderedImage image)

{JFrame f = new JFrame(title);f.getContentPane().add(new DisplayJAI(image));f.pack();

Page 120: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 120/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 120 /146

p ();f.setVisible(true);f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}

Original 0.5 0.1

Veja mais em http://www.lac.inpe.br/JIPCookbook

 

 

Page 121: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 121/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 121 /146

Extras: Pixels

 

Mini-aplicação: Conversão RGB ↔ IHS● IHS: Intensity, Hue and Saturation.● Cores representadas por:

 –

Page 122: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 122/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 122 /146

Intensity: brilho percebido da cor, 0 a 100% (preto = 0%). – Hue (croma): cor “bruta”, 0 a 359 graus (0 graus = vermelho). – Saturation: intensidade da cor, 0 a 100% (branco = 100%).

● Variantes: HSV, HSB, HSL, etc.

 

Mini-aplicação: Conversão RGB ↔ IHS● Integração de imagens de diferentes sensores

 – RGB→ IHS, substitui banda I por banda de maior resolução,

Page 123: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 123/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 123 /146

converte novamente IHS RGB● Manipulação de contraste e brilho

 – RGB→ IHS, manipula brilho e contraste da banda I, converte

novamente IHS→ RGB

● Nosso exemplo: converte RGB→ IHS, substitui I e S por 

100% constantes, reconverte para RGB.

 

Mini-aplicação: Conversão RGB ↔ IHSpublic class RGBtoIHS{

  public static void main(String[] args){PlanarImage imagem = JAI.create("fileload", args[0]);

C d l d S

Page 124: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 124/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 124 /146

  // Converte para o modelo de cores IHS.IHSColorSpace ihs = IHSColorSpace.getInstance();ColorModel modeloIHS =

  new ComponentColorModel(ihs,  new int []{8,8,8},  false,false,

Transparency.OPAQUE,DataBuffer.TYPE_BYTE) ;ParameterBlock pb = new ParameterBlock();pb.addSource(imagem);pb.add(modeloIHS);RenderedImage imagemIHS = JAI.create("colorconvert", pb);

 

Mini-aplicação: Conversão RGB ↔ IHS  // Extraímos as bandas I, H e S.

RenderedImage[] bandas = new RenderedImage[3];  for(int band=0;band<3;band++)

{pb = new ParameterBlock();b ddS (i IHS)

Page 125: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 125/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 125 /146

pb.addSource(imagemIHS);pb.add(new int[]{band});bandas[band] = JAI.create("bandselect",pb);}

  // Criamos bandas constantes para as bandas I e S.pb = new ParameterBlock();

pb.add((float)imagem.getWidth());pb.add((float)imagem.getHeight());pb.add(new Byte[]{(byte)255});RenderedImage novaIntensidade = JAI.create("constant",pb);pb = new ParameterBlock();pb.add((float)imagem.getWidth());pb.add((float)imagem.getHeight());

pb.add(new Byte[]{(byte)255});RenderedImage novaSaturação = JAI.create("constant",pb);

 

Mini-aplicação: Conversão RGB ↔ IHS  // Juntamos as bandas H e as I e S constantes.  // Devemos passar um RenderingHint que indica que o modelo

// de cor IHS será usado.ImageLayout imageLayout = new ImageLayout();imageLayout.setColorModel(modeloIHS);

i L t tS l M d l(i IHS tS l M d l())

Page 126: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 126/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 126 /146

imageLayout.setSampleModel(imagemIHS.getSampleModel());RenderingHints rendHints =new RenderingHints(JAI. KEY_IMAGE_LAYOUT ,imageLayout);

pb = new ParameterBlock();pb.addSource(novaIntensidade);pb.addSource(bandas[1]);pb.addSource(novaSaturação);RenderedImage imagemIHSModificada =JAI.create("bandmerge", pb, rendHints);

  // Convertemos de volta para RGB.pb = new ParameterBlock();pb.addSource(imagemIHSModificada);pb.add(imagem.getColorModel()); // Imagem original era em RGB!

RenderedImage imagemFinal = JAI.create("colorconvert", pb);

 

Mini-aplicação: Conversão RGB ↔ IHSJFrame frame = new JFrame("Modificação via IHS");frame.add(new DisplayTwoSynchronizedImages(imagem,imagemFinal));frame.pack();frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);

}

Page 127: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 127/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 127 /146

}}

 

 

Page 128: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 128/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 128 /146

Extras: Display

 

Mini-aplicação: Visualizador com Ícone● Mostra imagens grandes com pequeno ícone e pan.public class DisplayThumbnail extends DisplayJAI 

implements MouseMotionListener,MouseListener{

private PlanarImage originalImage;i

Page 129: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 129/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 129 /146

  private PlanarImage originalImage;  private float scale;  private int imageXTiles,imageYTiles;  private int imageTileWidth,imageTileHeight;  private int imageWidth,imageHeight;  private int visibleRegionWidth,visibleRegionHeight;  private int thumbWidth,thumbHeight;  // The size of the border around the thumbnail.

  private final int border = 10;  // The scaled viewport (dimensions are scaled/translated by the border).  private Rectangle2D scaledViewport;  private Color viewportColor;  // Colors to be used when the mouse is/isn't over the viewport.  private static Color viewportOn = new Color(120,255,120);  private static Color viewportOff = new Color(0,192,0);  // Coordinates obtained when we click (press) the mouse button to start

  // dragging the viewport.  private int lastX,lastY;  // Those coordinates represent the region where we can safely drag the  // viewport without "falling outside" the image boundaries.  private int minValidX,minValidY,maxValidX,maxValidY;

 

Mini-aplicação: Visualizador com Ícone  public DisplayThumbnail(PlanarImage image,float scale,  int width,int height)

{  this.scale = scale;  originalImage = image;

visibleRegionWidth = width; visibleRegionHeight = height;

Page 130: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 130/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 130 /146

  visibleRegionWidth = width; visibleRegionHeight = height;  // Get some stuff about the image.  imageXTiles = image.getNumXTiles();

imageYTiles = image.getNumYTiles();  imageTileWidth = image.getTileWidth();  imageTileHeight = image.getTileHeight();  imageWidth = image.getWidth(); imageHeight = image.getHeight();

  // Must create a thumbnail image using that scale.ParameterBlock pb = new ParameterBlock();pb.addSource(image);pb.add(scale); pb.add(scale); pb.add(0.0F); pb.add(0.0F);pb.add(new InterpolationNearest());PlanarImage thumbnail = JAI.create("scale", pb, null);

  // Let's get the width and height of the thumbnail.

  thumbWidth = thumbnail.getWidth();thumbHeight = thumbnail.getHeight();

 

Mini-aplicação: Visualizador com Ícone  // Now let's add a border.

pb = new ParameterBlock();pb.addSource(thumbnail);pb.add(new Integer(border)); pb.add(new Integer(border));pb.add(new Integer(border)); pb.add(new Integer(border));

pb add(new BorderExtenderConstant(new double[]{0 0 128}));thumbnail = JAI create("border" pb);

Page 131: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 131/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 131 /146

pb.add(new BorderExtenderConstant(new double[]{0,0,128}));thumbnail = JAI.create( border ,pb);  // Shift the image to the original position

pb = new ParameterBlock();pb.addSource(thumbnail); pb.add(1.0f*border); pb.add(1.0f*border);thumbnail = JAI.create("translate",pb,null);

  // Use this thumbnail as the image for the DisplayJAI component.set(thumbnail);

  // We'd like to listen to mouse movements.addMouseMotionListener(this);addMouseListener(this);

  // Initially the scaled viewport will be positioned at border,border.  scaledViewport =

new Rectangle2D.Float(border,border,width*scale,height*scale);  // We assume that the mouse is off the viewport.  viewportColor = viewportOff ;

}

 

Mini-aplicação: Visualizador com Ícone  public synchronized void paintComponent(Graphics g)

{  super.paintComponent(g);

Graphics2D g2d = (Graphics2D)g;  // Paint the tile grid.

g2d setColor(Color YELLOW);g2d setComposite(AlphaComposite getInstance(

Page 132: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 132/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 132 /146

g2d.setColor(Color.YELLOW );g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,0.5f));

  float x1,x2,y1,y2;  // Vertical tiles' boundaries.

x1 = x2 = border;y1 = border; y2 = border+thumbHeight;

  for(int tx=0;tx<=imageXTiles;tx++)

{g2d.drawLine((int)x1,(int)y1,(int)x2,(int)y2);x1 += imageTileWidth*scale;x2 += imageTileWidth*scale;}

 

Mini-aplicação: Visualizador com Ícone  // Horizontal tiles' boundaries.

x1 = border; x2 = border+thumbWidth;y1 = y2 = border;

  for(int ty=0;ty<=imageYTiles;ty++){

g2d.drawLine((int

)x1,(int

)y1,(int

)x2,(int

)y2);y1 += imageTileHeight*scale;

Page 133: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 133/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 133 /146

g2d.drawLine(( )x1,( )y1,( )x2,( )y2);y1 += imageTileHeight scale;y2 += imageTileHeight*scale;}

  // Paint a red border.g2d.setColor(Color.RED);g2d.drawRect(border,border,thumbWidth,thumbHeight);

  // Paint the viewport.

g2d.setColor(viewportColor);g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,1f));Stroke stroke = new BasicStroke(2f);g2d.setStroke(stroke);g2d.draw(scaledViewport);}

 

Mini-aplicação: Visualizador com Ícone  public void mouseMoved(MouseEvent e)

{  int x = e.getX(); int y = e.getY();  // Ignore events outside the border.  if ((x < border) || (y < border) ||

(x > border+thumbWidth) || (y > border+thumbHeight))t

Page 134: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 134/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 134 /146

(x border thumbWidth) || (y border thumbHeight))  return;  // Are we inside the viewport rectangle ?  if (scaledViewport.contains(x,y)) viewportColor = viewportOn;  else viewportColor = viewportOff ;  // Hopefully it will repaint only the needed section.

Rectangle repaintBounds =

  new Rectangle((int)scaledViewport.getX()-5,(int)scaledViewport.getY()-5,(int)scaledViewport.getWidth()+10,(int)scaledViewport.getHeight()+10);

repaint(repaintBounds);}

 

Mini-aplicação: Visualizador com Ícone  public void mousePressed(MouseEvent e)

{  // Store the new dragging starting points.  lastX = e.getX(); lastY = e.getY();  // Calculate the new window w/ viewport movements.

  minValidX = lastX-(int

)scaledViewport.getX()+border;minValidY = lastY-(int)scaledViewport.getY()+border;

Page 135: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 135/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 135 /146

( ) p g () ;  minValidY lastY (int)scaledViewport.getY() border;  maxValidX = border+thumbWidth-(int)scaledViewport.getWidth()+

(lastX-(int)scaledViewport.getX());  maxValidY = border+thumbHeight-(int)scaledViewport.getHeight()+

(lastY-(int)scaledViewport.getY());}

  public void mouseDragged(MouseEvent e)

{  int x = e.getX(); int y = e.getY();  if (x > maxValidX) x = maxValidX-1;  if (x < minValidX) x = minValidX;  if (y > maxValidY) y = maxValidY-1;  if (y < minValidY) y = minValidY;  if ((x >= minValidX) && (y >= minValidY) &&

(x <= maxValidX) && (y <= maxValidY)){updateLocation(x, y); lastX = x; lastY = y;}

}

 

Mini-aplicação: Visualizador com Ícone  public void updateLocation(int x,int y)

{  // Store the approximate region where the viewport was before the change.

Rectangle initBounds =  new Rectangle((int)scaledViewport.getX()-5,

(int)scaledViewport.getY()-5,(int)scaledViewport.getWidth()+10,

Page 136: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 136/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 136 /146

( ) p g () ,(int)scaledViewport.getHeight()+10);

  // Recalculate new position for the viewport, based on mouse coordinates.  double origX = scaledViewport.getX()+x-lastX;  double origY = scaledViewport.getY()+y-lastY;  // Reposition the viewport.  scaledViewport.setFrame(origX,origY,

  scaledViewport.getWidth(),scaledViewport.getHeight());  // Store the approximate region where the viewport is after the change.

Rectangle finalBounds =  new Rectangle((int)scaledViewport.getX()-5,

(int)scaledViewport.getY()-5,(int)scaledViewport.getWidth()+10,(int)scaledViewport.getHeight()+10);

  // Repaint only that section.repaint(finalBounds.union(initBounds));}

 

Mini-aplicação: Visualizador com Íconepublic PlanarImage getImage(){

  // Get the boundaries in the original image coordinates.  float fromX = (float)Math.round ((scaledViewport.getX()-border)/scale);  float fromY = (float)Math.round ((scaledViewport.getY()-border)/scale);  float width = (float)Math.round (scaledViewport.getWidth()/scale);  float height = (float)Math.round (scaledViewport.getWidth()/scale);

Page 137: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 137/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 137 /146

g p g ;  // Fix rounding errors to avoid exceptions on the crop.fromX = Math. min(fromX,(imageWidth-visibleRegionWidth));fromY = Math. min(fromY,(imageHeight-visibleRegionHeight));

  // Create a ParameterBlock with information for the cropping.ParameterBlock pb = new ParameterBlock();pb.addSource(originalImage);

pb.add(fromX); pb.add(fromY); pb.add(width); pb.add(height);  // Create the output image by cropping the input image.PlanarImage output = JAI.create("crop",pb,null);

  // Translate the image origin.pb = new ParameterBlock();pb.addSource(output);pb.add(-fromX); pb.add(-fromY);

  // Create the output image by translating itself.  return JAI.create("translate",pb,null);}

 

Mini-aplicação: Visualizador com Ícone  public Rectangle getCroppedImageBounds()

{  int fromX = (int)Math.round ((scaledViewport.getX()-border)/scale);  int fromY = (int)Math.round ((scaledViewport.getY()-border)/scale);  int width = (int)Math.round (scaledViewport.getWidth()/scale);

  int height = (int)Math.round (scaledViewport.getWidth()/scale);return new Rectangle(fromX fromY width height);

Page 138: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 138/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 138 /146

  return new Rectangle(fromX,fromY,width,height);}

  public Rectangle getViewportBounds(){Rectangle temp = scaledViewport.getBounds();

temp.setBounds((int)temp.getX()-border,(int)temp.getY()-border,(int)temp.getWidth(),(int)temp.getHeight());  return temp;

}

 

Mini-aplicação: Visualizador com Íconepublic class DisplayThumbnailApp extends JFrame implements MouseMotionListener{

  private DisplayThumbnail dt; private DisplayJAI dj; private JLabel world,view;

  public DisplayThumbnailApp(PlanarImage image,int dWidth,int dHeight){

  super("Interactive Thumbnail Example");SpringLayout layout = new SpringLayout();C t i t tP tC t tP ()

Page 139: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 139/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 139 /146

Container contentPane = getContentPane();contentPane.setLayout(layout);

  dt = new DisplayThumbnail(image,0.05f,dWidth,dHeight);  dt.addMouseMotionListener(this);  dj = new DisplayJAI(dt.getImage());  dj.setPreferredSize(new Dimension(dWidth,dHeight));  dj.setMinimumSize(new Dimension(dWidth,dHeight));

  dj.setMaximumSize(new Dimension(dWidth,dHeight));JPanel borderDisplay = new JPanel(new BorderLayout());borderDisplay.add(dj);borderDisplay.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));JLabel worldL = new JLabel("World: "); world = new JLabel("");JLabel viewL = new JLabel("Thumb: "); view = new JLabel("");contentPane.add(dt); contentPane.add(borderDisplay);contentPane.add(worldL); contentPane.add(world);contentPane.add(viewL); contentPane.add(view);(organização do layout removida)setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setResizable(false); pack(); setVisible(true);}

 

Mini-aplicação: Visualizador com Ícone  public void mouseDragged(MouseEvent e)

{  dj.set(dt.getImage());  // Gets some information about the viewport and cropped image.

Rectangle crop = dt.getCroppedImageBounds();Rectangle viewp = dt.getViewportBounds();

  // Change the labels' contents with this information.ld (

Page 140: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 140/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 140 /146

  world.setText(""+crop.x+","+crop.y+  " ("+crop.width+"x"+crop.height+")");  view.setText(""+viewp.x+","+viewp.y+  " ("+viewp.width+"x"+viewp.height+")");

}

  public void mouseMoved(MouseEvent e) { }

  public static void main(String[] args){PlanarImage image = JAI.create("fileload", args[0]);

  new DisplayThumbnailApp(image,640,640);}

 

Mini-aplicação: Visualizador com Ícone

Page 141: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 141/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 141 /146

 

 

Page 142: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 142/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 142 /146

Outros Tópicos

 

Tópicos para Pesquisa e Desenvolvimento● Processamento por pixels x processamento por regiões

 – Imagens de alta resolução – Novos algoritmos de classificação – Modelagem de conhecimento

Page 143: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 143/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 143 /146

g – Modelos de mistura – Inteligência artificial

http://gras.ku.dk/software/ecognition.htm

 

Para saber mais...● http://www.lac.inpe.br/JIPCookbook

http://www.lac.inpe.br/~rafael.santos● Introductory Digital Image Processing: A Remote Sensing Perspective

(John R. Jensen)

Page 144: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 144/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 144 /146

( )● Digital Image Processing Algorithms and Applications (Ioannis Pitas)● Digital Image Processing (Rafael C. Gonzalez, Richard E. Woods)

 

Para saber mais...● Fundamentals of Digital Image Processing ( Anil K. Jain)● Classification Methods for Remotely Sensed Data (Brandt Tso, Paul M.

Mather )● Pattern Recognition and Image Analysis (Earl Gose, Richard 

Page 145: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 145/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 145 /146

g g y (Johnsonbaugh, Steve Jost )

 

Para saber mais...● Fuzzy Algorithms: With Applications to Image Processing and Pattern

Recognition (Zheru Chi, H. Yan, Z.R. Chi, Hong Yan, Tuan Pham)● The Pocket Handbook of Image Processing Algorithms In C (Harley R.

Myler, Arthur R. Weeks)I lli Th E h B i d h C (M i A Fi hl

Page 146: Intro Pi Java

5/11/2018 Intro Pi Java - slidepdf.com

http://slidepdf.com/reader/full/intro-pi-java-55a2343056115 146/146

Fevereiro/2010 http://www.lac.inpe.br/~rafael.santos 146 /146

● Intelligence: The Eye, the Brain, and the Computer (Martin A. Fischler,

Oscar Firschein)