Blogger templates

Comunidade java aberto - Participe da nossa comunidade no facebook (clique aqui)

Visitas

quinta-feira, 4 de julho de 2013

Processamento Digital de Imagens (PDI) com Java

,


Tratar imagens digitalmente é uma coisa cada vez mais comum, seja para fazer correções de luz, cor, retirar imperfeições ou tratá-las para uma determinada finalidade, como identificar elementos na imagem de forma automática (ex: identificar uma placa de carro em uma imagem).

Para tal, é necessária a utilização de um ou de vários filtros para que o objetivo seja alcançado. A seguir, uma lista com alguns dos filtros mais usados e uma breve explicação sobre eles:

  • Desaturação (escala de cinza): deixa uma imagem em escala de cinza, ou seja, uma imagem colorida terá apenas pixels brancos, pretos ou cinzas;
  • Binarização (Threshold): consiste em deixar uma imagem em preto e branco, cada pixel da imagem original se transforma em um pixel totalmente branco (RGB #FFFFFF) ou totalmente preto (RGB #000000). Para determinar se um pixel da imagem original se tornará preto ou branco é usado um limiar, um valor que determina a partir de qual ponto um pixel se tornará preto ou se tornará branco. A imagem tratada por este filtro não contém pixel cinza, apenas preto e/ou branco, diferente da desaturação;
  • Negativo: este filtro faz com que a cor de cada pixel da imagem original se transforme na cor inversa (ex: pixel branco se transforma em pixel preto). A cor inversa é o valor da subtração entre 255 e o valor RGB. Ex: para um amarelo com valor RGB 255, 240, 0, sua cor inversa é o RGB 0, 15, 255.
  • Mediana: filtro usado para eliminar ruídos da imagem. O algoritmo faz um cálculo da média de cores de uma certa região de pixels e determina a cor média daquele trecho da imagem. Se houver um pixel preto (ruído) em meio há vários pixels brancos a aplicação do filtro eliminará este pixel preto, tirando o ruído da imagem.
Saiba mais sobre tratamento digital de imagens: PDI
Conheça os principais filtros do Adobe Photoshop: Filtros Photoshop
Bom, agora vamos ao que interessa: criar os filtros utilizando a linguagem JAVA!
Vou criar uma classe chamada App1 que simplesmente vai aplicar o filtro para deixar uma imagem em escala de cinza, e outra classe chamada Filtro que conterá os algoritmos dos filtros. A classe Exibicao servirá apenas para exibir as imagens utilizadas em um componente JFrame, nada muito funcional, apenas para deixar o exemplo mais “bonitinho”.

App1.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class App1 {
 
    public static void main(String[] args) throws IOException {
 
        try {
            //carrega nova imagem
            BufferedImage imagem1 = ImageIO.read(new File("images/imagem1.jpg"));
            //instancia um filtro e aplica a escala de cinza
            Filtro filtro = new Filtro();
            filtro.escalaDeCinza(imagem1);
            //gera uma nova imagem a partir da imagem1
            ImageIO.write(imagem1,"jpg",new File("images/imagem2.jpg"));
 
            //aqui apenas para demonstração,
            //carreguei novamente as duas imagens para exibi-las dentro de um JFrame
            imagem1 = ImageIO.read(new File("images/imagem1.jpg"));
            BufferedImage imagem2 = ImageIO.read(new File("images/imagem2.jpg"));
            Exibicao show = new Exibicao();
            show.exibirImagem(imagem1, imagem2);
            System.out.println("Filtro aplicado com sucesso!");
        }
        catch(IOException e){
            System.out.println("Erro! Verifique se o arquivo especificado existe e tente novamente.");
        }
        catch(Exception e){
            System.out.println("Erro! " + e.getMessage());
        }
    }
 
}
Filtro.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
public class Filtro {
 
    //método de aplicação do filtro escala de cinza
    //recebe como parâmetro uma imagem
    public static BufferedImage escalaDeCinza(BufferedImage imagem) {
        //pegar largura e altura da imagem
        int width = imagem.getWidth();
        int height = imagem.getHeight();
 
        int media = 0;
        //laço para varrer a matriz de pixels da imagem
        for (int i = 0; i < width; i++) {
            for (int j = 0; j < height; j++) {               //rgb recebe o valor RGB do pixel em questão                int rgb = imagem.getRGB(i, j);              int r = (int)((rgb&0x00FF0000)>>>16); //R
                int g = (int)((rgb&0x0000FF00)>>>8);  //G
                int b = (int) (rgb&0x000000FF);       //B
 
                //media dos valores do RGB
                //será o valor do pixel na nova imagem
                media = (r + g + b) / 3;
 
                //criar uma instância de Color
                Color color = new Color(media, media, media);
                //setar o valor do pixel com a nova cor
                imagem.setRGB(i, j, color.getRGB());
            }
        }
        return imagem;
    }
 
    public static BufferedImage negativo(BufferedImage image) {
        int width = image.getWidth();
        int height = image.getHeight();
        for (int i = 0; i < width; i++) {
            for (int j = 0; j < height; j++) {               int rgb = image.getRGB(i, j);               //a cor inversa é dado por 255 menos o valor da cor                 int r = 255 - (int)((rgb&0x00FF0000)>>>16);
                int g = 255 - (int)((rgb&0x0000FF00)>>>8);
                int b = 255 - (int) (rgb&0x000000FF);
                Color color = new Color(r, g, b);
                image.setRGB(i, j, color.getRGB());
            }
        }
        return image;
    }
 
    public static BufferedImage threshold(BufferedImage image, int limiar) {
        int width = image.getWidth();
        int height = image.getHeight();
        for (int i = 0; i < width; i++) {
            for (int j = 0; j < height; j++) {               int rgb = image.getRGB(i, j);               int r = (int)((rgb&0x00FF0000)>>>16);
                int g = (int)((rgb&0x0000FF00)>>>8);
                int b = (int) (rgb&0x000000FF);
                int media = (r + g + b) / 3;
                Color white = new Color(255, 255, 255);
                Color black = new Color(0, 0, 0);
                //como explicado no artigo, no threshold definimos um limiar,
                //que é um valor "divisor de águas"
                //pixels com valor ABAIXO do limiar viram pixels PRETOS,
                //pixels com valor ACIMA do limiar viram pixels BRANCOS
                if (media < limiar)
                    image.setRGB(i, j, black.getRGB());
                else
                    image.setRGB(i, j, white.getRGB());
            }
        }
        return image;
    }
Exibicao.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class Exibicao {
 
    public static void exibirImagem(BufferedImage image) {
        ImageIcon icon = new ImageIcon(image);
        JLabel imageLabel = new JLabel(icon);
        JFrame frame = new JFrame();
        Container contentPane = frame.getContentPane();
        contentPane.setLayout(new GridLayout());
        contentPane.add(new JScrollPane(imageLabel));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(800, 600);
        frame.setVisible(true);
    }
 
    public static void exibirImagem(BufferedImage image, BufferedImage image2) {
        ImageIcon icon = new ImageIcon(image);
        JLabel imageLabel = new JLabel(icon);
        ImageIcon icon2 = new ImageIcon(image2);
        JLabel imageLabel2 = new JLabel(icon2);
        JFrame frame = new JFrame();
        Container contentPane = frame.getContentPane();
        contentPane.setLayout(new GridLayout());
        contentPane.add(new JScrollPane(imageLabel));
        contentPane.add(new JScrollPane(imageLabel2));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(1100, 680);
        frame.setVisible(true);
    }
}

1 comentários:

  • 3 de outubro de 2015 10:50

    E a classe "Color"???????

    delete

Postar um comentário

Insira seu comentário

 

Java Aberto Copyright © 2011 -- Template created by O Pregador -- Powered by Blogger