SlideShare uma empresa Scribd logo
1 de 81
Baixar para ler offline
ERCEMAPI 2009
 29 de Outubro
 Parnaíba-PI




 MC 5: Técnicas de Processamento
         é
 Digital de Imagens com Java
 Iális Cavalcante – Engenharia da Computação
 UFC / Campus de Sobral
Objetivos

  • Apresentar técnicas básicas que envolvem
    Processamento Digital de Imagens (PDI);

  • Apresentar APIs Java voltada para PDI;

  • Desenvolver uma pequena aplicação em
                      p q       p ç
    Java para descrição de regiões.
E quem é o apresentador?
Agenda
1. Introdução
2. APIs Java para Imagem
2 API J           I
3.
3 Técnicas de Processamento Digital de
   Imagens (PDI)

4. Proposta de um Aplicativo de PDI

5. Considerações Finais
• Vi ã Geral sobre PDI
              Visão G l b
            • Aplicações Reais




1. INTRODUÇÃO
Introdução
 • PDI possui alguns conceitos em comum com
   Visão Computacional e Computação Gráfica
   (caso de Análise de Imagens - FootScanAge).
              á

 • Pixels formam uma imagem – função f(x,y)

 • Primeiros registros de estudo – NASA (Guerra
   Fria)

 • Aplicações Multidisciplinares
Comparativo



    Imagem                                         Imagem
                   Processamento de Imagens




                              Dado



  Computação Gráfica
  C    t ã G áfi                          Visão Computacional
Definição de Imagem
Histórico




           1921
                                                 1922

      Anos 20 – Sistema Bartlane
      Transmissão de Imagens via cabo submarino
                        g
      Uma semana para três horas – Londres para Nova York
Histórico




        Anos 20 (1925) – Sistema Bartlane
        Aumento para cinco níveis de brilho
Histórico




      Primeira imagem da Lua.
      Obtida pela nave espacial americana Ranger 7.
                                                 7
      31 de julho de 1964, 9:09 (17 minutos antes do impacto).
Aplicações em Saúde                90
                                               1
                             120                   60
                                           0.8


                                          0.6
                       150                               30
                                         0.4
                                         04


                                         0.2


                 180                                           0




                       210                               330




                             240                   300

                                   270
Aplicações em Saúde
Aplicações na Indústria Petrolífera
Aplicações na Agropecuária
Aplicações na Biologia
 p    ç            g
Aplicações em Imagens SAR
• API JAI
     • API I
           ImageJ
                J




2. APIS JAVA PARA IMAGEM
Formatos de Imagens

 • TIFF, GIF, PNG, JPEG, BMP, PBM, PGM,
   PMN

 • P d i d nos anos 80 e 90.
   Padronizados          90

 • Suportados pela maioria das APIs e
   linguagens
   ling agens de p og amação
                 programação.
Uso da linguagem Java
                                                   Why Java?

• Atrativos:
       i
   – Livre;
   – Portável (“write once, run anywhere”);
   – Sintaxe similar à linguagem C;
   – Possui facilidade de internacionalização dos caracteres;
   – Vasta documentação;
   – Coletor de lixo (para desalocação automática de 
     memória);
   – Facilidade de criação de programação distribuída e 
     concorrente;
   – P di
     Paradigma Orientado a Objetos.
                 O i t d Obj t
Java Advanced Imaging (JAI) API
                 g g(     )


                              PlanarImage

               ColorModel                        Raster

                ColorSpace                    SampleModel


                                               DataBuffer


Estrutura da classe de suporte a imagem na API JAI. Adaptado de Santos (2004).
Java Advanced Imaging (JAI) API
                 g g(     )
 • Leitura/Escrita de Imagens

 public class EScomJAI {
   public static void main(String[] args) {
       // leitura da imagem
       PlanarImage i
       Pl      I      image = JAI
                               JAI.create("fileload", "L
                                       t ("fil l d" "Lenna.png");
                                                              ")
       double[][] bandCombine = {{0.21f,0.71f,0.08f,0.0f}};
       // conversão do modelo de cores
       image = JAI.create("BandCombine", image, bandCombine);
       // escrita do arquivo
       JAI.create("filestore",image,"lennagl.png","PNG");
   }
 }
ImageJ API
          Plugin     Plugin    Plugin    Plugin     Plugin




                              ImageJ



                       AWT




                                Java


  Estrutura geral da API ImageJ. Adaptado de Burger & Burge (2009).
ImageJ API Software

 • Uso de plugins expande a comunidade de
   desenvolvedores;;

 • Di
   Disponibiliza um software com a execução
         ibili        ft                 ã
   de todas as funcionalidades
   implementadas;
Listagem: ExibeImagem.java
 public class ExibeImagem extends JFrame {
     public ExibeImagem() throws IOException { // início do construtor
             BufferedImage imagem = ImageIO.read(new File(“Lenna.png”));
             String infoImagem = “Dimensões: ”+imagem.getWidth()+
             “x”+imagem.getHeight()+“ Bandas: ”+ imagem.getRaster().getNumBands();
             ImageIcon icone = new ImageIcon(imagem);
             JLabel labImagem = new JLabel(icone);
             (…) // adiciona labImagem e infoImage à interface
             this.setVisible(true);
      } // fim do construtor
      // Método principal
      p
      public static void main(String args[]){
                                (    g g []){
             try{ // tratamento de exceção de E/S
                         ExibeImagem appExibeImg = new ExibeImagem();
             }
             }catch(IOException exc){
                    (        p        ){
                          System.out.println(“Erro de leitura! ”+exc.getMessage());
             }
     } // fim do método principal
 } // fim da classe
Resultado: ExibeImagem.java




  Imagem Original. Fonte: Imagem
adaptada de http://www.lenna.org/.
   p           p //            g/
                                     Imagem exibida pela classe.
•   Tipos de Imagens
         •   Realce
         •   Segmentação
         •   Morfologia Matemática




3. TÉCNICAS DE
PROCESSAMENTO
DIGITAL DE IMAGENS
Técnicas de Base para Aplicativo

 • Realce – Negativo e Filtragem (Passa-Baixa e
   Passa-Alta )

 • Segmentação – Limiarização e Watershed

 • Morfologia Matemática – Erosão Dilatação
                           Erosão, Dilatação,
   Abertura e Fechamento
Tipos de Imagens




 Imagem Binária
    g              Imagem em
                        g           Imagem Colorida
                                       g
                  Níveis de Cinza
CMYK




RGB




HSV
double[][] bandCombine = { {R, G, B, 0.0f} };
image = JAI.create("BandCombine", image, bandCombine);




    R = 1.0f                 R = 0.0f                R = 0.0f
    G = 0.0f                 G = 1.0f                G = 0.0f
    B = 0.0f                 B = 0.0f                B = 1.0f
Negativo de uma Imagem
  g                g
• Negativo de uma Imagem
  – Realce com processamento ponto-a-ponto
                              ponto a ponto
  – Aplicações em imagens médicas
  – Reverter a ordem do preto para o branco
     • Intensidade da imagem de saída diminui
     • Intensidade da entrada aumenta
     • s=L–1–r
Negativo de uma Imagem
  g                g
s = T(r)
Claro




                      T(r)
    ro
Escur




                                                 Imagem Original

                                         r
             Escuro           Claro
         Função de Transformação
            ç                ç




                             Imagem Processada
Presença de Ruído em Imagens

• Distorções em uma imagem afetam a
         õ                     f
  percepção da sua real informação;

• Uma distorção crítica é a presença de ruído;
  – Implica em nova informação na imagem;

• Normalmente os ruídos são definidos por
                                      p
  uma distribuição estatística:
  – modelo gaussiano, speckle, poisson, etc.
           g        , p      ,p       ,
Efeito do Ruído




   Imagem Original




       Mudanças de Perspectivas
            ç          p
Efeito do Ruído




   Imagem Ruidosa
    “Sal e Pimenta”




        Mudanças de Perspectivas
             ç          p
Efeito do Ruído




   Imagem Ruidosa
      Speckle




       Mudanças de Perspectivas
            ç          p
Efeito do Ruído


                                     Presença de ruído Poisson.


    Imagem Original




              Presença de ruído   Presença de ruído Speckle.
               “Sal e pimenta”.
Realce com Processamento por Máscara




     (1)             (2)




             (3)              (4)
Realce com Processamento por Máscara




            Exemplo de Máscara (3x3)




• g(x,y) = T[f(x,y)] (T opera em uma vizinhança de
  g( ,y)    [ ( ,y)] ( p                      ç
  pixels)
• z5’ = R = w1z1 + w2z1+ ... + w9z9 (Filtro Linear)
                                     (            )
  – z5’: soma ponderada de pixels na vizinhança de z5
• z5 = max(zk, k = 1, 2, ... 9)          (Filtro Não-Linear)
                                                 Não Linear)
  – Não satisfaz a condição de um filtro linear
Tipos de Filtragem
  p            g

 • A distribuição de valores na máscara
   define o tipo de filtragem:
              p           g
   – Passa-alta
      • Aguçamento das bordas;
   – Passa-baixa
      •S
       Supressão d ruído, b
              ã de íd borramento d imagem;
                              t da i
   – Passa-banda
      • Restauração da imagem.
Detectores de Bordas (Gradiente – Passa-Alta)




Imagem Original                     Filtro de Prewitt




                  Filtro de Sobel                       Filtro de Roberts
Definição de Gradiente




      (a)                     (b)         s = [1 2 1; 0 0 0; -1 -2 -1];
                                          A = zeros(10);
                                                    ( );
Figura
Fig a – (a) Imagem original; (b) Imagem
                        o iginal
                                          A(3:7,3:7) = ones(5);
após aplicação do filtro de Sobel.
                                          H = conv2(A,s);
                                          mesh(H)
Filtro de Suavização (passa-baixa)
• São úteis para redução de ruído e borramento de
  imagens
  – Detalhes são perdidos
      • O tamanho da máscara (ou seja vizinhança) determina o grau
                                   seja,
        de suavização e perda de detalhes.
  – Os elementos da máscara devem ser números positivos
                                              p
  – Exemplo: Média Local




  – R = 1/9 (1z1 + 1z2 + ... +1z9)              normalizado: dividido por 9
Filtro por mediana (não-linear)
• Substitua f(x,y) pela mediana [f(x’,y’)] onde (x’,y’) pertence a 
  vizinhança
          ç
• Muito efetivo na remoção do ruído com componentes do 
  tipo espigada (“spike”, ocorrências aleatórias de valores 
  brancos e pretos)
• Preserva melhor as bordas
• Exemplo:
                 10   20   20
                                                Ordenar
                 20   15   20        (10,15,20,20,20,20,20,25,100)

                 25   20   100



   – Mediana = 20, então substitua (15) por (20)
Filtragem da Mediana




  Imagem Ruidosa                   Filtragem com Janela 3x3
   “Sal e Pimenta”




              Filtragem com Janela 5x5            Filtragem com Janela 7x7
Limiarização
         ç

 • Comprime a faixa de nível de cinza de pouco
                        í
   interesse
   – Inclinação da linha entre [0,1]
 • Alargamento da faixa de nível de cinza de maior
   interesse
      – Inclinação da linha monotonicamente crescente


   – r1 = r2
   – s1 = 0 e s2 = L – 1
Limiarização
         ç
   s = T(r)
 Claro




                       T(r)
     ro
 Escur




                                                  Imagem Original

                                      r
              Escuro          Claro
    Função de Transformação




                              Imagem Processada
Limiarização
         ç




 Imagem Original   Limiar de 130




                      Limiar de 140   Limiar de 150
Watershed

 • Conside ando uma imagem em tom de cinza como
   Considerando ma                   cin a
   uma superfície topográfica:
   – Todos os vales foram perfurados na sua área mais
     funda da superfície;
   – Toda a superfície é lentamente preenchida por água,
     este irá progressivamente inundar todas as bacias da
     imagem;
      • Represas podem ser aumentadas onde a água vem de dois
        pontos distintos, podendo se unir;
               distintos
   – Ao fim da inundação, cada bacia é cercada por cumes
     (represas) representando seu limite.
   – Este processo define a divisão das regiões presentes
     na imagem.
Watershed




 Imagem Original   Imagem em Níveis de Cinza




                      Imagem com Marcadores    Imagem Final
Watershed




Animação sobre Watershed. Fonte: http://cmm.ensmp.fr/~beucher/wtshed.html.
Watershed

 • O objetos das imagens são definidos como
   Os bj t d i              ã d fi id
   as regiões de muitos valores de escala de
   cinza constantes.
    i        t t

 • O operador gradiente irá realçar os limites
   dos objetos (fim da inundação).
         j     (              ç )

 • Os marcadores indicam, de forma bruta,
                   indicam           bruta
   onde os objetos estão localizados na imagem
   (ponto de partida da inundação).
Morfologia Matemática
        • Elemento Estruturante (EE):
                  – Structuring Element (SE)
                  – Pequeno conjunto usado para reconhecer a
                    morfologia do objeto de interesse em uma imagem.
                        f l     d b      d
                  – Forma e tamanho devem ser adaptados para as
                    propriedades geométricas da imagem processada.
                          i d d        ét i   d i               d

0.5
05

 1                                                        1                                                       1

1.5
                                                          2                                                       2
 2
                                                          3                                                       3
2.5

 3                                                        4                                                       4

3.5
                                                          5                                                       5
 4
                                                          6                                                       6
4.5

 5                                                        7                                                       7

5.5                                                       0.5   1   1.5   2   2.5   3   3.5   4   4.5   5   5.5       1   2   3   4   5   6   7
  0.5   1   1.5   2   2.5   3   3.5   4   4.5   5   5.5
Morfologia Matemática
 • Erosão e Dilatação
 • A partir destes: Abertura e Fechamento
     p
Morfologia Matemática

 • Erosão não é o inverso da dilatação!
   – Uma erosão seguida de uma dilatação nem
     sempre retorna a imagem original.

      •B   quadrado 3x3
Morfologia Matemática




   Imagem Original                               Resultado da Erosão




            R

Elemento Estruturante
     Raio = 11
                        Resultado da Dilatação
Morfologia Matemática
• Abertura
   – Resultado da erosão seguida da dilatação;
       • Usando o mesmo elemento estruturante.

       • γB(X) = δB(εB(X))


   – Propriedades:
       • Idempotente;
       • Crescente;
       • Anti-extensiva; ?
                                          (a)                      (b)
                             Figura–Abertura com EE circular: (a) imagem original
                             e (b) sobreposição do resultado.
                               ( )      p ç
Resultado da abertura é sempre menor ou igual à
imagem original.
Morfologia Matemática
• Fechamento
   – Dual da Abertura;
   – Resultado da dilatação seguida da erosão
       • Usando o mesmo elemento estruturante.
       • φB(X) = εB(δB(X))


   – Propriedades:
       • Idempotente;
       • Crescente;
       • Extensiva; ?


Resultado da abertura é                (a)                        (b)
sempre maior ou igual à
           i     i   l     Figura – Fechamento com EE circular:
                           (a) imagem original e (b) sobreposição do resultado.
imagem original.
Morfologia Matemática




   Imagem Original                                Resultado da Abertura




            R

Elemento Estruturante
     Raio = 11
                        Resultado do Fechamento
Morfologia Matemática



 Imagem Original              Resultado da Erosão   Resultado da Dilatação




                   Resultado da Abertura   Resultado do Fechamento
• Definição do aplicativo
                    • Uso da API ImageJ
                    • Desenvolvimento




4. PROPOSTA DE UM
APLICATIVO DE PDI
Fluxograma
  u og a a         Imagem 
                   Ruidosa


                   Filtragem
             (eliminação do ruído)



                 Segmentação
             (separação de regiões)
             (separação de regiões)



                  Objeto está         Não
                     bem                    Pós‐Processamento
                 identificado?

                  Sim
                   Imagem 
                   Imagem
                  Processada
Aplicando Filtro da Mediana
    // objeto “imagem"” da classe java.awt.Image instanciado
    // com a imagem original
    ByteProcessor processador = new ByteProcessor(imagem);
    processador.medianFilter();
    // resultado do filtro é p
                             passado ao objeto “imagem”
                                          j        g
    imagem = processador.createImage();




         Imagem Ruidosa                  Imagem Filtrada
Aplicando Segmentação
   // objeto “imagem” da classe java.awt.Image instanciado
   // com a imagem filtrada
   ByteProcessor processador = new ByteProcessor(imagem);
   // “valorLimiar” é inteiro e que indica o limiar da segmentação
   p
   processador.threshold(valorLimiar);
                          (           );
   // resultado da limiarização é passado ao objeto “imagem”
   imagem = processador.createImage();




          Imagem Filtrada                Imagem Segmentada
Aplicando Fechamento
// objeto “imagem” da classe Image instanciado com a imagem segmentada
ByteProcessor processador = new ByteProcessor(imagem);
// etapa de dilatação - 1o passo do fechamento
processador.dilate(1,0);
imagem = processador.createImage();
processador = new B P
         d           ByteProcessor(imagem);
                                  (i      )
// etapa de erosão - 2o passo do fechamento
p
processador.erode(1,0);
                   ( , );
imagem = processador.createImage();


                                                         Imagem Segmentada




                                                      Imagem Final
Melhor uso de memória

 • E i
   Evitar o acúmulo de variáveis estáticas no
              ú l d       iá i      ái
   método principal
   – Para auxiliar o desempenho do coletor de lixo
     da máquina virtual Java.
 • O uso de variáveis estáticas deve ser
   evitado
   – Ocupam muito recurso de memória
   – São as últimas instâncias a serem eliminadas
     pelo garbage collector
Melhor uso de memória

   Execução do garbage collector:
 • E     ã d      b      ll
   – System.gc() ou

   – Runtime rt = Runtime.getRuntime();
                          g         ();
     rt.gc();
     long mem = rt freeMemory();
                 rt.freeMemory();

 • E     ã frequente d gc() pode resultar
   Execução f      t de () d         lt
   na degradação do desempenho.
Listagem: SegRdI.java (visão geral)
    public class S RdI extends JF
       bli l       SegRdI t d JFrame {
    // atributos
    JPanel painelPrinc, painelBotoes;
    JButton b b b
              btnAbrir, btnProc, b
                                 btnLimpar, b
                                            btnSair;
    File fileName;         ImagePlus imagemIJ;
    // inicialização dos componentes gráficos
    public void iniciaComponentes() { ... }
    // método da ação ao clicar o botão Abrir
    private void abrirActionPerformed(ActionEvent evt) { … }
    // método da ação ao clicar o botão Processar
    private void processarActionPerformed(ActionEvent evt) { … }
    // método da ação ao clicar o botão Limpar
    private void limparActionPerformed(ActionEvent evt) { … }
    // método da ação ao clicar o botão Sair
    private void sairActionPerformed(ActionEvent evt) { System.exit(0); }
    // construtor padrão
    public SegRdI() { this.iniciaComponentes(); }
    // método principal
                 p    p
    public static void main(String[] args) { SegRdI aplicacao = new SegRdI(); }
    } // fim da classe
Listagem: SegRdI.java (inicia interface gráfica)
 public void iniciaComponentes(){
     this.setLayout(new BorderLayout()); painelPrinc = new JPanel();
     painelPrinc.setLayout(new BorderLayout()); this.add(painelPrinc, BorderLayout.CENTER);
     painelBotoes = new JP
        i lB t           JPanel(); painelBotoes.setLayout(new Fl L
                               l()   i lB t       tL    t(     FlowLayout());
                                                                          t())
     this.add(painelBotoes, BorderLayout.SOUTH);

    // adicionando botões
    btnAbrir = new JButton(); painelBotoes.add(btnAbrir); btnAbrir.setText(“ Abrir ... ”);
    btnProc = new JButton(); painelBotoes.add(btnProc); btnProc.setText(“Processar”);
    // -> faz-se o mesmo para os botões “btnLimpar” e “btnSair”
                                         btnLimpar     btnSair

    // configurar ações dos botões
    btnAbrir.addActionListener(new
    btnAbrir addActionListener(new ActionListener() {
           public void actionPerformed(ActionEvent evt) { abrirActionPerformed(evt); } } );
    btnProc.addActionListener( ... ); // relacionar com o método processarActionPerformed
    btnLimpar.addActionListener( ... ); // relacionar com o método limparActionPerformed
           p                     (                                     p
    btnSair.addActionListener( ... ); // relacionar com o método sairActionPerformed

      this.setVisible(true);      this.setSize(450,350);
      this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
 } // fim do método initComponents
Listagem: SegRdI.java (limpar interface)

 private void limparActionPerformed(ActionEvent evt) {
    ImagePlus imp = new ImagePlus();
    ImageCanvas ic = new ImageCanvas(imp);
         g                     g       ( p)
    painelPrinc.removeAll();
    p
    painelPrinc.add(ic,BorderLayout.CENTER);
                   ( ,         y          );
 } // fim do método limparActionPerformed
Listagem: SegRdI.java (abrir imagem)
 private void abrirActionPerformed(ActionEvent evt) {
     // exibe caixa de diálogo para abrir arquivo de imagem
     JFileChooser dialogo = new JFileChooser();
     dialogo.setFileSelectionMode(JFileChooser.FILES_ONLY);
     int result = dialogo.showOpenDialog(this);
     if (result == JFileChooser CANCEL OPTION) return;
                     JFileChooser.CANCEL_OPTION)
     // recupera arquivo selecionado
     fileName = dialogo.getSelectedFile();
     // exibe erro se inválido
     if (fileName == null || fileName.getName().equals(“”)) {
               JOptionPane.showMessageDialog(this, “Nome de Arquivo Inválido”,
               “Nome de Arquivo Inválido”, JOptionPane ERROR MESSAGE);
                                 Inválido” JOptionPane.ERROR_MESSAGE);         return; }
     imagemIJ = new ImagePlus(fileName.toString());
     JScrollPane sp = new JScrollPane( JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                                   JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
                                   JS llP      HORIZONTAL SCROLLBAR AS NEEDED)
     ImageCanvas ic = new ImageCanvas(imagemIJ); sp.add(ic);
     sp.setSize(imagemIJ.getWidth(), imagemIJ.getHeight());
     painelPrinc.add(sp,BorderLayout.CENTER);
             l       dd(      d           C      )
 } // fim do método abrirActionPerformed
Listagem: SegRdI.java (processamento da imagem - I)

  private void processarActionPerformed(ActionEvent evt) {
      Image image = imagemIJ.getImage();
      ByteProcessor b t P
      B t P            byteProc = new B t P
                                         ByteProcessor(image);
                                                        (i       )
      byteProc.medianFilter();
      image = byteProc.createImage();
      ImagePlus i Filt = new I
      I      Pl imFilt            ImagePlus(“filtragem”,image);
                                         Pl (“filt       ”i       )
      // descobrindo maior valor de nível de cinza
      int max = -1;
      for(int lin = 0; lin < imFilt.getHeight(); lin++)
             for(int col = 0; col < imFilt.getWidth(); col++){
                         int[] pixels = imFilt.getPixel(col, lin);
                         if (pixels[0]>max) max = pixels[0]; }
      image = imFilt.getImage(); byteProc = new ByteProcessor(image);
      // aplicando a segmentação através de limiarização
      byteProc.threshold(max-1);
      image = byteProc.createImage();
      ImagePlus imSeg = new ImagePlus(“segmentacao”,image);
      image = imSeg.getImage(); byteProc = new ByteProcessor(image);
Listagem: SegRdI.java (processamento da imagem - II)

      // inicialmente aplica-se a dilatação
      byteProc.dilate(1,0);
      image = b t P
      i          byteProc.createImage();
                              t I      ()
      ImagePlus imDil = new ImagePlus(“dilatacao”,image);
      image = imDil.getImage();           byteProc = new ByteProcessor(image);
      // posteriormente aplica-se a erosão
      byteProc.erode(1,0);
      image = byteProc createImage();
                 byteProc.createImage();
      ImagePlus imErosao = new ImagePlus(“erosao”,image);
      JScrollPane sp = new JScrollPane(
             JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
             JS llP      VERTICAL SCROLLBAR AS NEEDED
             JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
      ImageCanvas ic = new ImageCanvas(imErosao); sp.add(ic);
           g                       g
      sp.setSize(imErosao.getWidth(), imErosao.getHeight());
      painelPrinc.removeAll();
      painelPrinc.add(sp,BorderLayout.CENTER);
      painelPrinc add(sp BorderLayout CENTER);
  } // fim do método processarActionPerformed
Listagem: SegRdI.java (acrescentando escrita)

    // adotando a API Java 2D (alternativa para ImageJ)
    BufferedImage bi = new BufferedImage(imErosao getWidth()
                             BufferedImage(imErosao.getWidth(),
            imErosao.getHeight(), BufferedImage.TYPE_BYTE_BINARY);
    Graphics2D g2 = bi.createGraphics();
        p       g                 p   ();
    g2.drawImage(image, 0, 0, null);
    g2.dispose();
    try { ImageIO.write(bi, "png", new File("imagemFinal.png")); }
    catch(IOException ioe) { System.out.println( ioe.getMessage() ); }

    // ou ainda, misturando com a API JAI
    PlanarImage imagemFinal = JAI.create("awtimage", image);
              g       g                    (       g ,     g );
    JAI.create("filestore",imagemFinal,"imagemFinal.png","PNG");
Aplicativo
Pra
            P encerrar o assunto...
                              t




5. CONSIDERAÇÕES FINAIS
Conclusões e Considerações Finais
                      ç

 • Algumas noções de PDI foram expostas
   para o desenvolvimento de um aplicativo
   específico;
 • Nas APIs Java:
   – a JAI apresenta melhor tratamento de
     entrada/saída;
   – ImageJ traz mais implementações básicas em
                                         á
     sua versão padrão;
   – As duas são bem flexíveis e extensíveis;
                          í            í
   – Pode-se criar um aplicativo combinando as
     duas APIs.
Dúvidas?
Dú id ?
Se gostou então podemos conversar ...
     gostou,

                            ... encontre me aqui:
                                encontre-me


http://engcomp.sobral.ufc.br/professores/ialis/


http://www.linkedin.com/pub/ialis-cavalcante/13/b35/46


http://osum.sun.com/profile/IalisJunior


http://www.slideshare.net/ialis                   ialis@ufc.br
Obrigado, ...
... e vamos para o almoço!

Mais conteúdo relacionado

Semelhante a Processamento digital de imagens com Java

Computacao grafica python v2
Computacao grafica python v2Computacao grafica python v2
Computacao grafica python v2Jean Lopes
 
Aula 09 imagens vetoriais
Aula 09   imagens vetoriaisAula 09   imagens vetoriais
Aula 09 imagens vetoriaisFábio Costa
 
Aula 09 imagens vetoriais
Aula 09   imagens vetoriaisAula 09   imagens vetoriais
Aula 09 imagens vetoriaisFábio Costa
 
Projeto Marvin
Projeto MarvinProjeto Marvin
Projeto Marvinmarvinproj
 
Computação Gráfica em Python
Computação Gráfica em PythonComputação Gráfica em Python
Computação Gráfica em Pythongsroma
 
PROCESSAMENTO DE IMAGENS - FORMULÁRIO.pdf
PROCESSAMENTO DE IMAGENS - FORMULÁRIO.pdfPROCESSAMENTO DE IMAGENS - FORMULÁRIO.pdf
PROCESSAMENTO DE IMAGENS - FORMULÁRIO.pdfestudosfaculdade05fa
 
Pil e segmentacao automatica de vídeo
Pil e segmentacao automatica de vídeoPil e segmentacao automatica de vídeo
Pil e segmentacao automatica de vídeowhanderley freitas
 
Desktop publishing
Desktop publishingDesktop publishing
Desktop publishingUNESP
 
Processamento de Imagem - Campinho
Processamento de Imagem - CampinhoProcessamento de Imagem - Campinho
Processamento de Imagem - Campinhozacssa
 

Semelhante a Processamento digital de imagens com Java (14)

Minicurso Ercemapi 2011
Minicurso Ercemapi 2011Minicurso Ercemapi 2011
Minicurso Ercemapi 2011
 
Computacao grafica python v2
Computacao grafica python v2Computacao grafica python v2
Computacao grafica python v2
 
Aula 09 imagens vetoriais
Aula 09   imagens vetoriaisAula 09   imagens vetoriais
Aula 09 imagens vetoriais
 
Aula 09 imagens vetoriais
Aula 09   imagens vetoriaisAula 09   imagens vetoriais
Aula 09 imagens vetoriais
 
Projeto Marvin
Projeto MarvinProjeto Marvin
Projeto Marvin
 
Computação Gráfica em Python
Computação Gráfica em PythonComputação Gráfica em Python
Computação Gráfica em Python
 
PROCESSAMENTO DE IMAGENS - FORMULÁRIO.pdf
PROCESSAMENTO DE IMAGENS - FORMULÁRIO.pdfPROCESSAMENTO DE IMAGENS - FORMULÁRIO.pdf
PROCESSAMENTO DE IMAGENS - FORMULÁRIO.pdf
 
Pil e segmentacao automatica de vídeo
Pil e segmentacao automatica de vídeoPil e segmentacao automatica de vídeo
Pil e segmentacao automatica de vídeo
 
Desktop publishing
Desktop publishingDesktop publishing
Desktop publishing
 
Matemática I - Tópico 04: Equações do 1º e 2º graus e Inequações
Matemática I - Tópico 04: Equações do 1º e 2º graus e InequaçõesMatemática I - Tópico 04: Equações do 1º e 2º graus e Inequações
Matemática I - Tópico 04: Equações do 1º e 2º graus e Inequações
 
Processamento de Imagem - Campinho
Processamento de Imagem - CampinhoProcessamento de Imagem - Campinho
Processamento de Imagem - Campinho
 
Digital Definitivo
Digital DefinitivoDigital Definitivo
Digital Definitivo
 
Vrml aula 89
Vrml aula 89Vrml aula 89
Vrml aula 89
 
11477 41952-1-pb
11477 41952-1-pb11477 41952-1-pb
11477 41952-1-pb
 

Mais de Ialis Cavalcante (14)

Assembleia com os Discentes - SACEC
Assembleia com os Discentes - SACECAssembleia com os Discentes - SACEC
Assembleia com os Discentes - SACEC
 
Unidade7 1
Unidade7 1Unidade7 1
Unidade7 1
 
Programacao logica
Programacao logicaProgramacao logica
Programacao logica
 
05 poo-ii
05   poo-ii05   poo-ii
05 poo-ii
 
Unidade06
Unidade06Unidade06
Unidade06
 
Introducao ao greenfoot
Introducao ao greenfootIntroducao ao greenfoot
Introducao ao greenfoot
 
Dinamicas
DinamicasDinamicas
Dinamicas
 
Interface grafica
Interface graficaInterface grafica
Interface grafica
 
Unidade05
Unidade05Unidade05
Unidade05
 
Unidade04
Unidade04Unidade04
Unidade04
 
Unidade03
Unidade03Unidade03
Unidade03
 
Unidade02
Unidade02Unidade02
Unidade02
 
CCT 23Maio2009 Sobral
CCT 23Maio2009 SobralCCT 23Maio2009 Sobral
CCT 23Maio2009 Sobral
 
Introducao ao LaTeX
Introducao ao LaTeXIntroducao ao LaTeX
Introducao ao LaTeX
 

Processamento digital de imagens com Java

  • 1. ERCEMAPI 2009 29 de Outubro Parnaíba-PI MC 5: Técnicas de Processamento é Digital de Imagens com Java Iális Cavalcante – Engenharia da Computação UFC / Campus de Sobral
  • 2. Objetivos • Apresentar técnicas básicas que envolvem Processamento Digital de Imagens (PDI); • Apresentar APIs Java voltada para PDI; • Desenvolver uma pequena aplicação em p q p ç Java para descrição de regiões.
  • 3. E quem é o apresentador?
  • 4. Agenda 1. Introdução 2. APIs Java para Imagem 2 API J I 3. 3 Técnicas de Processamento Digital de Imagens (PDI) 4. Proposta de um Aplicativo de PDI 5. Considerações Finais
  • 5. • Vi ã Geral sobre PDI Visão G l b • Aplicações Reais 1. INTRODUÇÃO
  • 6. Introdução • PDI possui alguns conceitos em comum com Visão Computacional e Computação Gráfica (caso de Análise de Imagens - FootScanAge). á • Pixels formam uma imagem – função f(x,y) • Primeiros registros de estudo – NASA (Guerra Fria) • Aplicações Multidisciplinares
  • 7. Comparativo Imagem Imagem Processamento de Imagens Dado Computação Gráfica C t ã G áfi Visão Computacional
  • 9. Histórico 1921 1922 Anos 20 – Sistema Bartlane Transmissão de Imagens via cabo submarino g Uma semana para três horas – Londres para Nova York
  • 10. Histórico Anos 20 (1925) – Sistema Bartlane Aumento para cinco níveis de brilho
  • 11. Histórico Primeira imagem da Lua. Obtida pela nave espacial americana Ranger 7. 7 31 de julho de 1964, 9:09 (17 minutos antes do impacto).
  • 12. Aplicações em Saúde 90 1 120 60 0.8 0.6 150 30 0.4 04 0.2 180 0 210 330 240 300 270
  • 18. • API JAI • API I ImageJ J 2. APIS JAVA PARA IMAGEM
  • 19. Formatos de Imagens • TIFF, GIF, PNG, JPEG, BMP, PBM, PGM, PMN • P d i d nos anos 80 e 90. Padronizados 90 • Suportados pela maioria das APIs e linguagens ling agens de p og amação programação.
  • 20. Uso da linguagem Java Why Java? • Atrativos: i – Livre; – Portável (“write once, run anywhere”); – Sintaxe similar à linguagem C; – Possui facilidade de internacionalização dos caracteres; – Vasta documentação; – Coletor de lixo (para desalocação automática de  memória); – Facilidade de criação de programação distribuída e  concorrente; – P di Paradigma Orientado a Objetos. O i t d Obj t
  • 21. Java Advanced Imaging (JAI) API g g( ) PlanarImage ColorModel Raster ColorSpace SampleModel DataBuffer Estrutura da classe de suporte a imagem na API JAI. Adaptado de Santos (2004).
  • 22. Java Advanced Imaging (JAI) API g g( ) • Leitura/Escrita de Imagens public class EScomJAI { public static void main(String[] args) { // leitura da imagem PlanarImage i Pl I image = JAI JAI.create("fileload", "L t ("fil l d" "Lenna.png"); ") double[][] bandCombine = {{0.21f,0.71f,0.08f,0.0f}}; // conversão do modelo de cores image = JAI.create("BandCombine", image, bandCombine); // escrita do arquivo JAI.create("filestore",image,"lennagl.png","PNG"); } }
  • 23. ImageJ API Plugin Plugin Plugin Plugin Plugin ImageJ AWT Java Estrutura geral da API ImageJ. Adaptado de Burger & Burge (2009).
  • 24. ImageJ API Software • Uso de plugins expande a comunidade de desenvolvedores;; • Di Disponibiliza um software com a execução ibili ft ã de todas as funcionalidades implementadas;
  • 25. Listagem: ExibeImagem.java public class ExibeImagem extends JFrame { public ExibeImagem() throws IOException { // início do construtor BufferedImage imagem = ImageIO.read(new File(“Lenna.png”)); String infoImagem = “Dimensões: ”+imagem.getWidth()+ “x”+imagem.getHeight()+“ Bandas: ”+ imagem.getRaster().getNumBands(); ImageIcon icone = new ImageIcon(imagem); JLabel labImagem = new JLabel(icone); (…) // adiciona labImagem e infoImage à interface this.setVisible(true); } // fim do construtor // Método principal p public static void main(String args[]){ ( g g []){ try{ // tratamento de exceção de E/S ExibeImagem appExibeImg = new ExibeImagem(); } }catch(IOException exc){ ( p ){ System.out.println(“Erro de leitura! ”+exc.getMessage()); } } // fim do método principal } // fim da classe
  • 26. Resultado: ExibeImagem.java Imagem Original. Fonte: Imagem adaptada de http://www.lenna.org/. p p // g/ Imagem exibida pela classe.
  • 27. Tipos de Imagens • Realce • Segmentação • Morfologia Matemática 3. TÉCNICAS DE PROCESSAMENTO DIGITAL DE IMAGENS
  • 28. Técnicas de Base para Aplicativo • Realce – Negativo e Filtragem (Passa-Baixa e Passa-Alta ) • Segmentação – Limiarização e Watershed • Morfologia Matemática – Erosão Dilatação Erosão, Dilatação, Abertura e Fechamento
  • 29. Tipos de Imagens Imagem Binária g Imagem em g Imagem Colorida g Níveis de Cinza
  • 31. double[][] bandCombine = { {R, G, B, 0.0f} }; image = JAI.create("BandCombine", image, bandCombine); R = 1.0f R = 0.0f R = 0.0f G = 0.0f G = 1.0f G = 0.0f B = 0.0f B = 0.0f B = 1.0f
  • 32. Negativo de uma Imagem g g • Negativo de uma Imagem – Realce com processamento ponto-a-ponto ponto a ponto – Aplicações em imagens médicas – Reverter a ordem do preto para o branco • Intensidade da imagem de saída diminui • Intensidade da entrada aumenta • s=L–1–r
  • 33. Negativo de uma Imagem g g s = T(r) Claro T(r) ro Escur Imagem Original r Escuro Claro Função de Transformação ç ç Imagem Processada
  • 34. Presença de Ruído em Imagens • Distorções em uma imagem afetam a õ f percepção da sua real informação; • Uma distorção crítica é a presença de ruído; – Implica em nova informação na imagem; • Normalmente os ruídos são definidos por p uma distribuição estatística: – modelo gaussiano, speckle, poisson, etc. g , p ,p ,
  • 35. Efeito do Ruído Imagem Original Mudanças de Perspectivas ç p
  • 36. Efeito do Ruído Imagem Ruidosa “Sal e Pimenta” Mudanças de Perspectivas ç p
  • 37. Efeito do Ruído Imagem Ruidosa Speckle Mudanças de Perspectivas ç p
  • 38. Efeito do Ruído Presença de ruído Poisson. Imagem Original Presença de ruído Presença de ruído Speckle. “Sal e pimenta”.
  • 39. Realce com Processamento por Máscara (1) (2) (3) (4)
  • 40. Realce com Processamento por Máscara Exemplo de Máscara (3x3) • g(x,y) = T[f(x,y)] (T opera em uma vizinhança de g( ,y) [ ( ,y)] ( p ç pixels) • z5’ = R = w1z1 + w2z1+ ... + w9z9 (Filtro Linear) ( ) – z5’: soma ponderada de pixels na vizinhança de z5 • z5 = max(zk, k = 1, 2, ... 9) (Filtro Não-Linear) Não Linear) – Não satisfaz a condição de um filtro linear
  • 41. Tipos de Filtragem p g • A distribuição de valores na máscara define o tipo de filtragem: p g – Passa-alta • Aguçamento das bordas; – Passa-baixa •S Supressão d ruído, b ã de íd borramento d imagem; t da i – Passa-banda • Restauração da imagem.
  • 42. Detectores de Bordas (Gradiente – Passa-Alta) Imagem Original Filtro de Prewitt Filtro de Sobel Filtro de Roberts
  • 43. Definição de Gradiente (a) (b) s = [1 2 1; 0 0 0; -1 -2 -1]; A = zeros(10); ( ); Figura Fig a – (a) Imagem original; (b) Imagem o iginal A(3:7,3:7) = ones(5); após aplicação do filtro de Sobel. H = conv2(A,s); mesh(H)
  • 44. Filtro de Suavização (passa-baixa) • São úteis para redução de ruído e borramento de imagens – Detalhes são perdidos • O tamanho da máscara (ou seja vizinhança) determina o grau seja, de suavização e perda de detalhes. – Os elementos da máscara devem ser números positivos p – Exemplo: Média Local – R = 1/9 (1z1 + 1z2 + ... +1z9)              normalizado: dividido por 9
  • 45. Filtro por mediana (não-linear) • Substitua f(x,y) pela mediana [f(x’,y’)] onde (x’,y’) pertence a  vizinhança ç • Muito efetivo na remoção do ruído com componentes do  tipo espigada (“spike”, ocorrências aleatórias de valores  brancos e pretos) • Preserva melhor as bordas • Exemplo: 10 20 20 Ordenar 20 15 20 (10,15,20,20,20,20,20,25,100) 25 20 100 – Mediana = 20, então substitua (15) por (20)
  • 46. Filtragem da Mediana Imagem Ruidosa Filtragem com Janela 3x3 “Sal e Pimenta” Filtragem com Janela 5x5 Filtragem com Janela 7x7
  • 47. Limiarização ç • Comprime a faixa de nível de cinza de pouco í interesse – Inclinação da linha entre [0,1] • Alargamento da faixa de nível de cinza de maior interesse – Inclinação da linha monotonicamente crescente – r1 = r2 – s1 = 0 e s2 = L – 1
  • 48. Limiarização ç s = T(r) Claro T(r) ro Escur Imagem Original r Escuro Claro Função de Transformação Imagem Processada
  • 49. Limiarização ç Imagem Original Limiar de 130 Limiar de 140 Limiar de 150
  • 50. Watershed • Conside ando uma imagem em tom de cinza como Considerando ma cin a uma superfície topográfica: – Todos os vales foram perfurados na sua área mais funda da superfície; – Toda a superfície é lentamente preenchida por água, este irá progressivamente inundar todas as bacias da imagem; • Represas podem ser aumentadas onde a água vem de dois pontos distintos, podendo se unir; distintos – Ao fim da inundação, cada bacia é cercada por cumes (represas) representando seu limite. – Este processo define a divisão das regiões presentes na imagem.
  • 51. Watershed Imagem Original Imagem em Níveis de Cinza Imagem com Marcadores Imagem Final
  • 52. Watershed Animação sobre Watershed. Fonte: http://cmm.ensmp.fr/~beucher/wtshed.html.
  • 53. Watershed • O objetos das imagens são definidos como Os bj t d i ã d fi id as regiões de muitos valores de escala de cinza constantes. i t t • O operador gradiente irá realçar os limites dos objetos (fim da inundação). j ( ç ) • Os marcadores indicam, de forma bruta, indicam bruta onde os objetos estão localizados na imagem (ponto de partida da inundação).
  • 54. Morfologia Matemática • Elemento Estruturante (EE): – Structuring Element (SE) – Pequeno conjunto usado para reconhecer a morfologia do objeto de interesse em uma imagem. f l d b d – Forma e tamanho devem ser adaptados para as propriedades geométricas da imagem processada. i d d ét i d i d 0.5 05 1 1 1 1.5 2 2 2 3 3 2.5 3 4 4 3.5 5 5 4 6 6 4.5 5 7 7 5.5 0.5 1 1.5 2 2.5 3 3.5 4 4.5 5 5.5 1 2 3 4 5 6 7 0.5 1 1.5 2 2.5 3 3.5 4 4.5 5 5.5
  • 55. Morfologia Matemática • Erosão e Dilatação • A partir destes: Abertura e Fechamento p
  • 56. Morfologia Matemática • Erosão não é o inverso da dilatação! – Uma erosão seguida de uma dilatação nem sempre retorna a imagem original. •B quadrado 3x3
  • 57. Morfologia Matemática Imagem Original Resultado da Erosão R Elemento Estruturante Raio = 11 Resultado da Dilatação
  • 58. Morfologia Matemática • Abertura – Resultado da erosão seguida da dilatação; • Usando o mesmo elemento estruturante. • γB(X) = δB(εB(X)) – Propriedades: • Idempotente; • Crescente; • Anti-extensiva; ? (a) (b) Figura–Abertura com EE circular: (a) imagem original e (b) sobreposição do resultado. ( ) p ç Resultado da abertura é sempre menor ou igual à imagem original.
  • 59. Morfologia Matemática • Fechamento – Dual da Abertura; – Resultado da dilatação seguida da erosão • Usando o mesmo elemento estruturante. • φB(X) = εB(δB(X)) – Propriedades: • Idempotente; • Crescente; • Extensiva; ? Resultado da abertura é (a) (b) sempre maior ou igual à i i l Figura – Fechamento com EE circular: (a) imagem original e (b) sobreposição do resultado. imagem original.
  • 60. Morfologia Matemática Imagem Original Resultado da Abertura R Elemento Estruturante Raio = 11 Resultado do Fechamento
  • 61. Morfologia Matemática Imagem Original Resultado da Erosão Resultado da Dilatação Resultado da Abertura Resultado do Fechamento
  • 62. • Definição do aplicativo • Uso da API ImageJ • Desenvolvimento 4. PROPOSTA DE UM APLICATIVO DE PDI
  • 63. Fluxograma u og a a Imagem  Ruidosa Filtragem (eliminação do ruído) Segmentação (separação de regiões) (separação de regiões) Objeto está  Não bem  Pós‐Processamento identificado? Sim Imagem  Imagem Processada
  • 64. Aplicando Filtro da Mediana // objeto “imagem"” da classe java.awt.Image instanciado // com a imagem original ByteProcessor processador = new ByteProcessor(imagem); processador.medianFilter(); // resultado do filtro é p passado ao objeto “imagem” j g imagem = processador.createImage(); Imagem Ruidosa Imagem Filtrada
  • 65. Aplicando Segmentação // objeto “imagem” da classe java.awt.Image instanciado // com a imagem filtrada ByteProcessor processador = new ByteProcessor(imagem); // “valorLimiar” é inteiro e que indica o limiar da segmentação p processador.threshold(valorLimiar); ( ); // resultado da limiarização é passado ao objeto “imagem” imagem = processador.createImage(); Imagem Filtrada Imagem Segmentada
  • 66. Aplicando Fechamento // objeto “imagem” da classe Image instanciado com a imagem segmentada ByteProcessor processador = new ByteProcessor(imagem); // etapa de dilatação - 1o passo do fechamento processador.dilate(1,0); imagem = processador.createImage(); processador = new B P d ByteProcessor(imagem); (i ) // etapa de erosão - 2o passo do fechamento p processador.erode(1,0); ( , ); imagem = processador.createImage(); Imagem Segmentada Imagem Final
  • 67. Melhor uso de memória • E i Evitar o acúmulo de variáveis estáticas no ú l d iá i ái método principal – Para auxiliar o desempenho do coletor de lixo da máquina virtual Java. • O uso de variáveis estáticas deve ser evitado – Ocupam muito recurso de memória – São as últimas instâncias a serem eliminadas pelo garbage collector
  • 68. Melhor uso de memória Execução do garbage collector: • E ã d b ll – System.gc() ou – Runtime rt = Runtime.getRuntime(); g (); rt.gc(); long mem = rt freeMemory(); rt.freeMemory(); • E ã frequente d gc() pode resultar Execução f t de () d lt na degradação do desempenho.
  • 69. Listagem: SegRdI.java (visão geral) public class S RdI extends JF bli l SegRdI t d JFrame { // atributos JPanel painelPrinc, painelBotoes; JButton b b b btnAbrir, btnProc, b btnLimpar, b btnSair; File fileName; ImagePlus imagemIJ; // inicialização dos componentes gráficos public void iniciaComponentes() { ... } // método da ação ao clicar o botão Abrir private void abrirActionPerformed(ActionEvent evt) { … } // método da ação ao clicar o botão Processar private void processarActionPerformed(ActionEvent evt) { … } // método da ação ao clicar o botão Limpar private void limparActionPerformed(ActionEvent evt) { … } // método da ação ao clicar o botão Sair private void sairActionPerformed(ActionEvent evt) { System.exit(0); } // construtor padrão public SegRdI() { this.iniciaComponentes(); } // método principal p p public static void main(String[] args) { SegRdI aplicacao = new SegRdI(); } } // fim da classe
  • 70. Listagem: SegRdI.java (inicia interface gráfica) public void iniciaComponentes(){ this.setLayout(new BorderLayout()); painelPrinc = new JPanel(); painelPrinc.setLayout(new BorderLayout()); this.add(painelPrinc, BorderLayout.CENTER); painelBotoes = new JP i lB t JPanel(); painelBotoes.setLayout(new Fl L l() i lB t tL t( FlowLayout()); t()) this.add(painelBotoes, BorderLayout.SOUTH); // adicionando botões btnAbrir = new JButton(); painelBotoes.add(btnAbrir); btnAbrir.setText(“ Abrir ... ”); btnProc = new JButton(); painelBotoes.add(btnProc); btnProc.setText(“Processar”); // -> faz-se o mesmo para os botões “btnLimpar” e “btnSair” btnLimpar btnSair // configurar ações dos botões btnAbrir.addActionListener(new btnAbrir addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { abrirActionPerformed(evt); } } ); btnProc.addActionListener( ... ); // relacionar com o método processarActionPerformed btnLimpar.addActionListener( ... ); // relacionar com o método limparActionPerformed p ( p btnSair.addActionListener( ... ); // relacionar com o método sairActionPerformed this.setVisible(true); this.setSize(450,350); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } // fim do método initComponents
  • 71. Listagem: SegRdI.java (limpar interface) private void limparActionPerformed(ActionEvent evt) { ImagePlus imp = new ImagePlus(); ImageCanvas ic = new ImageCanvas(imp); g g ( p) painelPrinc.removeAll(); p painelPrinc.add(ic,BorderLayout.CENTER); ( , y ); } // fim do método limparActionPerformed
  • 72. Listagem: SegRdI.java (abrir imagem) private void abrirActionPerformed(ActionEvent evt) { // exibe caixa de diálogo para abrir arquivo de imagem JFileChooser dialogo = new JFileChooser(); dialogo.setFileSelectionMode(JFileChooser.FILES_ONLY); int result = dialogo.showOpenDialog(this); if (result == JFileChooser CANCEL OPTION) return; JFileChooser.CANCEL_OPTION) // recupera arquivo selecionado fileName = dialogo.getSelectedFile(); // exibe erro se inválido if (fileName == null || fileName.getName().equals(“”)) { JOptionPane.showMessageDialog(this, “Nome de Arquivo Inválido”, “Nome de Arquivo Inválido”, JOptionPane ERROR MESSAGE); Inválido” JOptionPane.ERROR_MESSAGE); return; } imagemIJ = new ImagePlus(fileName.toString()); JScrollPane sp = new JScrollPane( JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); JS llP HORIZONTAL SCROLLBAR AS NEEDED) ImageCanvas ic = new ImageCanvas(imagemIJ); sp.add(ic); sp.setSize(imagemIJ.getWidth(), imagemIJ.getHeight()); painelPrinc.add(sp,BorderLayout.CENTER); l dd( d C ) } // fim do método abrirActionPerformed
  • 73. Listagem: SegRdI.java (processamento da imagem - I) private void processarActionPerformed(ActionEvent evt) { Image image = imagemIJ.getImage(); ByteProcessor b t P B t P byteProc = new B t P ByteProcessor(image); (i ) byteProc.medianFilter(); image = byteProc.createImage(); ImagePlus i Filt = new I I Pl imFilt ImagePlus(“filtragem”,image); Pl (“filt ”i ) // descobrindo maior valor de nível de cinza int max = -1; for(int lin = 0; lin < imFilt.getHeight(); lin++) for(int col = 0; col < imFilt.getWidth(); col++){ int[] pixels = imFilt.getPixel(col, lin); if (pixels[0]>max) max = pixels[0]; } image = imFilt.getImage(); byteProc = new ByteProcessor(image); // aplicando a segmentação através de limiarização byteProc.threshold(max-1); image = byteProc.createImage(); ImagePlus imSeg = new ImagePlus(“segmentacao”,image); image = imSeg.getImage(); byteProc = new ByteProcessor(image);
  • 74. Listagem: SegRdI.java (processamento da imagem - II) // inicialmente aplica-se a dilatação byteProc.dilate(1,0); image = b t P i byteProc.createImage(); t I () ImagePlus imDil = new ImagePlus(“dilatacao”,image); image = imDil.getImage(); byteProc = new ByteProcessor(image); // posteriormente aplica-se a erosão byteProc.erode(1,0); image = byteProc createImage(); byteProc.createImage(); ImagePlus imErosao = new ImagePlus(“erosao”,image); JScrollPane sp = new JScrollPane( JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JS llP VERTICAL SCROLLBAR AS NEEDED JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); ImageCanvas ic = new ImageCanvas(imErosao); sp.add(ic); g g sp.setSize(imErosao.getWidth(), imErosao.getHeight()); painelPrinc.removeAll(); painelPrinc.add(sp,BorderLayout.CENTER); painelPrinc add(sp BorderLayout CENTER); } // fim do método processarActionPerformed
  • 75. Listagem: SegRdI.java (acrescentando escrita) // adotando a API Java 2D (alternativa para ImageJ) BufferedImage bi = new BufferedImage(imErosao getWidth() BufferedImage(imErosao.getWidth(), imErosao.getHeight(), BufferedImage.TYPE_BYTE_BINARY); Graphics2D g2 = bi.createGraphics(); p g p (); g2.drawImage(image, 0, 0, null); g2.dispose(); try { ImageIO.write(bi, "png", new File("imagemFinal.png")); } catch(IOException ioe) { System.out.println( ioe.getMessage() ); } // ou ainda, misturando com a API JAI PlanarImage imagemFinal = JAI.create("awtimage", image); g g ( g , g ); JAI.create("filestore",imagemFinal,"imagemFinal.png","PNG");
  • 77. Pra P encerrar o assunto... t 5. CONSIDERAÇÕES FINAIS
  • 78. Conclusões e Considerações Finais ç • Algumas noções de PDI foram expostas para o desenvolvimento de um aplicativo específico; • Nas APIs Java: – a JAI apresenta melhor tratamento de entrada/saída; – ImageJ traz mais implementações básicas em á sua versão padrão; – As duas são bem flexíveis e extensíveis; í í – Pode-se criar um aplicativo combinando as duas APIs.
  • 80. Se gostou então podemos conversar ... gostou, ... encontre me aqui: encontre-me http://engcomp.sobral.ufc.br/professores/ialis/ http://www.linkedin.com/pub/ialis-cavalcante/13/b35/46 http://osum.sun.com/profile/IalisJunior http://www.slideshare.net/ialis ialis@ufc.br
  • 81. Obrigado, ... ... e vamos para o almoço!