Transformação de imagem

11 respostas
S

Boas,

Estou a tentar fazer um programa que pegue numa imagem e tenha a opção de desfocar ou coloca-la mais nitida...

Depois de algum tempo e pesquisa, consegui desfocar a imagem, o problema é mesmo como fazer para a tornar mais nitida, ando a volta com isto á seculos e não consigo fazer essa parte do código :? :?

Aqui fica o que eu fiz até agora:

package a.m.imagem;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.image.*;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;

/**
 *
 * @author fnac
 */
public class AMImagem {

    private static RenderedImage ni;

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws IOException {
        // TODO code application logic here
        String nome = "";
        BufferedImage image = null;
        final JFileChooser fc = new JFileChooser();
        int returnVal = fc.showOpenDialog(null);
        if(returnVal == JFileChooser.APPROVE_OPTION)
                {
                    nome = fc.getSelectedFile().getPath();
                }
        else
        {
        System.exit(1);
        }
        File f1 = new File(nome);
        image = ImageIO.read(f1);
        //lançar imaguem
        JFrame frame = new JFrame();
        JLabel label = new JLabel(new ImageIcon(image));
        frame.getContentPane().add(label, BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);
        int H;
        int W;
        H = image.getHeight(null);
        W = image.getWidth(null);
        int nb = image.getSampleModel().getNumBands();
        int[] pixel = new int[nb];
        Raster inputRaster = image.getData();
        //defenir um vextor para correr tudo
        int[] pixels = new int[nb * W * H];
        //vai buscar todos pixeis
        inputRaster.getPixels(0, 0, W, H, pixels);

        //Criar nova imaguem com novas dimensoes!
        BufferedImage ni = new BufferedImage(W, H, BufferedImage.TYPE_INT_RGB);

        WritableRaster outputRaster = ni.getRaster();
       
        for (int i = 1; i < W-1; i++) {
            for (int j = 1; j < H-1; j++) {
                int piexel1 = image.getRGB(i, j);
                int blue1 = piexel1 & 0xFF;
                int green1 = (piexel1 >> 8) & 0xFF;
                int red1 = (piexel1 >> 16) & 0xFF;

                int pixel2 = image.getRGB(i - 1, j - 1);
                int blue2 = pixel2 & 0xFF;
                int green2 = (pixel2 >> 8) & 0xFF;
                int red2 = (pixel2 >> 16) & 0xFF;

                int pixel3 = image.getRGB(i - 1, j);
                int blue3 = pixel3 & 0xFF;
                int green3 = (pixel3 >> 8) & 0xFF;
                int red3 = (pixel3 >> 16) & 0xFF;
                //System.out.println(i + " " + j + " " + H + "  " + W);
                int pixel4 = image.getRGB(i - 1, j + 1);
                int blue4 = pixel4 & 0xFF;
                int green4 = (pixel4 >> 8) & 0xFF;
                int red4 = (pixel4 >> 16) & 0xFF;

                int pixel5 = image.getRGB(i, j - 1);
                int blue5 = pixel5 & 0xFF;
                int green5 = (pixel5 >> 8) & 0xFF;
                int red5 = (pixel5 >> 16) & 0xFF;

                int pixel6 = image.getRGB(i, j + 1);
                int blue6 = pixel6 & 0xFF;
                int green6 = (pixel6 >> 8) & 0xFF;
                int red6 = (pixel6 >> 16) & 0xFF;

                int pixel7 = image.getRGB(i + 1, j - 1);
                int blue7 = pixel7 & 0xFF;
                int green7 = (pixel7 >> 8) & 0xFF;
                int red7 = (pixel7 >> 16) & 0xFF;

                int pixel8 = image.getRGB(i + 1, j);
                int blue8 = pixel8 & 0xFF;
                int green8 = (pixel8 >> 8) & 0xFF;
                int red8 = (pixel8 >> 16) & 0xFF;

                int pixel9 = image.getRGB(i + 1, j - 1);
                int blue9 = pixel9 & 0xFF;
                int green9 = (pixel9 >> 8) & 0xFF;
                int red9 = (pixel9 >> 16) & 0xFF;


                int bluefinal = (blue1 + blue2 + blue3 + blue4 + blue5 + blue6 + blue7 + blue8 + blue9) / 9;
                int redfinal = (red1 + red2 + red3 + red4 + red5 + red6 + red7 + red8 + red9) / 9;
                int greenfinal = (green1 + green2 + green3 + green4 + green5 + green6 + green7 + green8 + green9) / 9;



                int[] color = {redfinal, greenfinal, bluefinal};
                outputRaster.setPixel(i, j, color);
            }
        }


        ni.setData(outputRaster);
        ImageIO.write(ni, "JPEG", new File("image1.jpg"));
        JFrame frame0 = new JFrame();
        JLabel label0 = new JLabel(new ImageIcon(ni));
        frame0.getContentPane().add(label0, BorderLayout.CENTER);
        frame0.setLocation(W+20, 0);
        frame0.pack();
        frame0.setVisible(true);

    }
}

Será possível alguém me ajudar nos calculos dos pixels para conseguir por a imagem mais nitida?

desde já um muito obrigado

11 Respostas

V

Você realmente entende o que está fazendo, ou está programando por tentativa e erro?
Porque o ideal seria modelar uma classe para seu kernel, e basear o processamento desses filtros através de matrizes.

Assim você poderia implementar filtros de blur diferentes.

Um detalhe. É mais fácil extrair as cores da imagem desse jeito:

Color pixel1 = new Color(int piexel1 = image.getRGB(i, j));

A partir daí, pixel1 passa a ter os métodos getAlpha(), getRed(), getGreen() e getBlue().

Já que você está usando o getRGB(), que é lento, pode também usar o setRGB(). Assim seu programa fica mais homogêneo. Se realmente quiser performance, dê uma olhada nesse post:
http://guj.com.br/java/244860-roadmap-processamento-de-imagens

A teoria para melhoria do processo de imagem pode ser encontrada aqui:
http://www.imatest.com/docs/sharpening/
http://gene.bio.jhu.edu/sharpening/sharpen2.html

O nome disso é em inglês é digital image sharpening. Basicamente, o processo consiste em eliminar parte da cor dos vizinhos de um determinado pixel.

S

desde já um muito obrigado :smiley:

o facto de estar a usar esta forma é porque foi assim que eu dei nas aulas, e para fazer este trabalho tenho de o fazer desta maneira

vou dar uma olhadela nos tutoriais :smiley:

G

a linha 106 não seria:

int pixel9 = image.getRGB(i + 1, j + 1);

???

pq ela ta lendo o pixel q a 96 leu.

G

mudei esse trecho:

for (int i = 1; i < W-1; i++) {  
            for (int j = 1; j < H-1; j++) {  
                int piexel1 = image.getRGB(i, j);  
                int blue1 = piexel1 & 0xFF;  
                int green1 = (piexel1 >> 8) & 0xFF;  
                int red1 = (piexel1 >> 16) & 0xFF;  
  
                int pixel2 = image.getRGB(i - 1, j - 1);  
                int blue2 = pixel2 & 0xFF;  
                int green2 = (pixel2 >> 8) & 0xFF;  
                int red2 = (pixel2 >> 16) & 0xFF;  
  
                int pixel3 = image.getRGB(i - 1, j);  
                int blue3 = pixel3 & 0xFF;  
                int green3 = (pixel3 >> 8) & 0xFF;  
                int red3 = (pixel3 >> 16) & 0xFF;  
                //System.out.println(i + " " + j + " " + H + "  " + W);  
                int pixel4 = image.getRGB(i - 1, j + 1);  
                int blue4 = pixel4 & 0xFF;  
                int green4 = (pixel4 >> 8) & 0xFF;  
                int red4 = (pixel4 >> 16) & 0xFF;  
  
                int pixel5 = image.getRGB(i, j - 1);  
                int blue5 = pixel5 & 0xFF;  
                int green5 = (pixel5 >> 8) & 0xFF;  
                int red5 = (pixel5 >> 16) & 0xFF;  
  
                int pixel6 = image.getRGB(i, j + 1);  
                int blue6 = pixel6 & 0xFF;  
                int green6 = (pixel6 >> 8) & 0xFF;  
                int red6 = (pixel6 >> 16) & 0xFF;  
  
                int pixel7 = image.getRGB(i + 1, j - 1);  
                int blue7 = pixel7 & 0xFF;  
                int green7 = (pixel7 >> 8) & 0xFF;  
                int red7 = (pixel7 >> 16) & 0xFF;  
  
                int pixel8 = image.getRGB(i + 1, j);  
                int blue8 = pixel8 & 0xFF;  
                int green8 = (pixel8 >> 8) & 0xFF;  
                int red8 = (pixel8 >> 16) & 0xFF;  
  
                int pixel9 = image.getRGB(i + 1, j - 1);  
                int blue9 = pixel9 & 0xFF;  
                int green9 = (pixel9 >> 8) & 0xFF;  
                int red9 = (pixel9 >> 16) & 0xFF;  
  
  
                int bluefinal = (blue1 + blue2 + blue3 + blue4 + blue5 + blue6 + blue7 + blue8 + blue9) / 9;  
                int redfinal = (red1 + red2 + red3 + red4 + red5 + red6 + red7 + red8 + red9) / 9;  
                int greenfinal = (green1 + green2 + green3 + green4 + green5 + green6 + green7 + green8 + green9) / 9;  
  
  
  
                int[] color = {redfinal, greenfinal, bluefinal};  
                outputRaster.setPixel(i, j, color);  
            }  
        }

pra ficar assim:

Color[] Pixels = new Color[9]; 
        
        for (int i = 1; i < W-1; i++) {  
            for (int j = 1; j < H-1; j++) {  
                Pixels[0] = new Color(image.getRGB(i, j));
                Pixels[1] = new Color(image.getRGB(i - 1, j - 1));  
                Pixels[2] = new Color(image.getRGB(i - 1, j));  
                Pixels[3] = new Color(image.getRGB(i - 1, j + 1));  
                Pixels[4] = new Color(image.getRGB(i, j - 1));  
                Pixels[5] = new Color(image.getRGB(i, j + 1));  
                Pixels[6] = new Color(image.getRGB(i + 1, j - 1));  
                Pixels[7] = new Color(image.getRGB(i + 1, j));  
                Pixels[8] = new Color(image.getRGB(i + 1, j - 1));  ///// AINDA ACHO Q É (1, j + 1)
                
                int bluefinal  = 0;  
                int redfinal   = 0;  
                int greenfinal = 0;  
                
                for (int k = 0; k < Pixels.length; k++) {
                    redfinal   += Pixels[k].getRed();  
                    greenfinal += Pixels[k].getGreen();
                	bluefinal  += Pixels[k].getBlue();  
				} 
                
                bluefinal  /= 9;  
                redfinal   /= 9;  
                greenfinal /= 9;
  
                int[] color = {redfinal, greenfinal, bluefinal};  
                outputRaster.setPixel(i, j, color);  
            }  
        }
G

mas dps resolvi fazer assim:

for (int i = 1; i < W-1; i++) {  
            for (int j = 1; j < H-1; j++) {  

                int bluefinal  = 0;  
                int redfinal   = 0;  
                int greenfinal = 0;
                
            	for (int ww = -1; ww < 2; ww++) {
            	    for (int hh = -1; hh < 2; hh++) {
            			Color c = new Color(image.getRGB(i + ww, j + hh));  
                        
                        redfinal   += c.getRed();  
                        greenfinal += c.getGreen();
                    	bluefinal  += c.getBlue();  
            	    }
            	} 
         	
                int[] color = {redfinal / 9, greenfinal / 9, bluefinal / 9};  
                outputRaster.setPixel(i, j, color);  
           }  
        }
J
GilsonNunes:
mas dps resolvi fazer assim:
for (int i = 1; i < W-1; i++) {  
            for (int j = 1; j < H-1; j++) {  

                int bluefinal  = 0;  
                int redfinal   = 0;  
                int greenfinal = 0;
                
            	for (int ww = -1; ww < 2; ww++) {
            	    for (int hh = -1; hh < 2; hh++) {
            			Color c = new Color(image.getRGB(i + ww, j + hh));  
                        
                        redfinal   += c.getRed();  
                        greenfinal += c.getGreen();
                    	bluefinal  += c.getBlue();  
            	    }
            	} 
         	
                int[] color = {redfinal / 9, greenfinal / 9, bluefinal / 9};  
                outputRaster.setPixel(i, j, color);  
           }  
        }

A biblioteca de imagem do java já possui o algoritmo de convolução espacial em que você pode criar diversos filtros com base em uma máscara(kernel). O que você quer é usar um filtro passa alta. Em processamento de sinais esse filtro é usado para filtrar as baixas frequências do sinal luminoso, que é justamente a transição suave de um pixel para outro. Esse filtro aumenta a nitidez da imagem(falando vulgarmente), enquanto o filtro passa baixa faz justamente o contrário.

A máscara do passa alta é justamente
0 -1 0
-1 +5 -1
0 -1 0

Abaixo o filtro passa baixa usando a propria api do java:
Detalhe é que a máscara é a média, ou seja o resultado é a média dos vizinhos

1/9 1/9 1/9
1/9 1/9 1/9
1/9 1/9 1/9

float[] matrix = {
        0.111f, 0.111f, 0.111f, 
        0.111f, 0.111f, 0.111f, 
        0.111f, 0.111f, 0.111f, 
    };

    BufferedImageOp op = new ConvolveOp( new Kernel(3, 3, matrix) );
    blurredImage = op.filter(sourceImage, destImage);

[img]http://www.jhlabs.com/ip/flower.jpg[/img] [img]http://www.jhlabs.com/ip/blur1.jpg[/img]

Para o Passa Alta use a máscara do mesmo citada acima.

http://www.jhlabs.com/ip/blurring.html
http://www.cbpf.br/cat/download/publicacoes/pdf/ProcessamentoImagens.PDF

S

Continuo sem conseguir descobrir que calculos preciso de fazer no algoritmo para tornar a imagem mais nitida :frowning: :frowning:

Ainda não consegui perceber os metodos de calculo, mas vou continuar a procurar :smiley: :smiley: :smiley:

Valeu pessoal :wink: :wink:

S
package a.m.imagem;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.image.*;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;

/**
 *
 * @author fnac
 */
public class AMImagem {

    private static RenderedImage ni;

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws IOException {
        // TODO code application logic here
        String nome = "";
        BufferedImage image = null;
        final JFileChooser fc = new JFileChooser();
        int returnVal = fc.showOpenDialog(null);
        if(returnVal == JFileChooser.APPROVE_OPTION)
                {
                    nome = fc.getSelectedFile().getPath();
                }
        else
        {
        System.exit(1);
        }
        File f1 = new File(nome);
        image = ImageIO.read(f1);
        //lançar imaguem
        JFrame frame = new JFrame();
        JLabel label = new JLabel(new ImageIcon(image));
        frame.getContentPane().add(label, BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);
        int H;
        int W;
        H = image.getHeight(null);
        W = image.getWidth(null);
        int nb = image.getSampleModel().getNumBands();
        int[] pixel = new int[nb];
        Raster inputRaster = image.getData();
        //definir um vector para correr tudo
        int[] pixels = new int[nb * W * H];
        //vai buscar todos pixeis
        inputRaster.getPixels(0, 0, W, H, pixels);

        //Criar nova imagem com novas dimensoes!
        BufferedImage ni = new BufferedImage(W, H, BufferedImage.TYPE_INT_RGB);

        WritableRaster outputRaster = ni.getRaster();
        
        int k;
        int l;
        int sharp;
        int  temp;
        int r=0,g=0,b=0;
        
        
        int sumr=0;
        int sumg=0;
        int sumb=0;
       
        int sharpen_filter[sharp_w][sharp_h]={{0,-1,0},{-1,5,-1},{0,-1,0}};
        int sharp_sum=1;
        
        for (int i = 1; i < W-1; i++) {    
            for (int j = 1; j < H-1; j++) {  
                for (k=0; k<sharp_w;k++){
                    for{l=0;1<sharp_h;l++){
                
          int pixel1 = image.getRGB(i, j);
                int blue1 = pixel1 & 0xFF;
                int green1 = (pixel1 >> 8) & 0xFF;
                int red1 = (pixel1 >> 16) & 0xFF;

                int pixel2 = image.getRGB(i - 1, j - 1);
                int blue2 = pixel2 & 0xFF;
                int green2 = (pixel2 >> 8) & 0xFF;
                int red2 = (pixel2 >> 16) & 0xFF;

                int pixel3 = image.getRGB(i - 1, j);
                int blue3 = pixel3 & 0xFF;
                int green3 = (pixel3 >> 8) & 0xFF;
                int red3 = (pixel3 >> 16) & 0xFF;

                int pixel4 = image.getRGB(i - 1, j + 1);
                int blue4 = pixel4 & 0xFF;
                int green4 = (pixel4 >> 8) & 0xFF;
                int red4 = (pixel4 >> 16) & 0xFF;

                int pixel5 = image.getRGB(i, j - 1);
                int blue5 = pixel5 & 0xFF;
                int green5 = (pixel5 >> 8) & 0xFF;
                int red5 = (pixel5 >> 16) & 0xFF;

                int pixel6 = image.getRGB(i, j + 1);
                int blue6 = pixel6 & 0xFF;
                int green6 = (pixel6 >> 8) & 0xFF;
                int red6 = (pixel6 >> 16) & 0xFF;

                int pixel7 = image.getRGB(i + 1, j - 1);
                int blue7 = pixel7 & 0xFF;
                int green7 = (pixel7 >> 8) & 0xFF;
                int red7 = (pixel7 >> 16) & 0xFF;

                int pixel8 = image.getRGB(i + 1, j);
                int blue8 = pixel8 & 0xFF;
                int green8 = (pixel8 >> 8) & 0xFF;
                int red8 = (pixel8 >> 16) & 0xFF;

                int pixel9 = image.getRGB(i + 1, j - 1);
                int blue9 = pixel9 & 0xFF;
                int green9 = (pixel9 >> 8) & 0xFF;
                int red9 = (pixel9 >> 16) & 0xFF;  
           
           
                    }
                    sumr/=sharp_sum;
                    sumr/=sharp_sum;
                    sumr/=sharp_sum;
                    
                    putpixel(temp,i,j,(sumr,sumg,sumb));
                    }
                    
       
                   
       }    
    }    


        ni.setData(outputRaster);
        ImageIO.write(ni, "JPEG", new File("image1.jpg"));
        JFrame frame0 = new JFrame();
        JLabel label0 = new JLabel(new ImageIcon(ni));
        frame0.getContentPane().add(label0, BorderLayout.CENTER);
        frame0.setLocation(W+20, 0);
        frame0.pack();
        frame0.setVisible(true);

    }
}

Após alguma pesquisa cheguei aqui, mas ainda tenho alguns erros....

S

como posso eu retirar parte da cor dos pixels vizinhos?

S
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package a.m.imagem;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.image.*;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;

/**
 *
 * @author fnac
 */
public class AMImagem {

    private static RenderedImage ni;

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws IOException {
        // TODO code application logic here
        String nome = "";
        BufferedImage image = null;
        final JFileChooser fc = new JFileChooser();
        int returnVal = fc.showOpenDialog(null);
        if(returnVal == JFileChooser.APPROVE_OPTION)
                {
                    nome = fc.getSelectedFile().getPath();
                }
        else
        {
        System.exit(1);
        }
        File f1 = new File(nome);
        image = ImageIO.read(f1);
        //lançar imaguem
        JFrame frame = new JFrame();
        JLabel label = new JLabel(new ImageIcon(image));
        frame.getContentPane().add(label, BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);
        float[] matrix = {  
       0f, -1f, 0f,   
       -1f, +5f, -1f,   
       0f, -1f, 0f,   
        };  
        
        
        int H;
        int W;
        H = image.getHeight()-matrix.length;
        W = image.getWidth()-matrix.length;
        int nb = image.getSampleModel().getNumBands();
        int[] pixel = new int[nb];
        Raster inputRaster = image.getData();
        //defenir um vextor para correr tudo
        int[] pixels = new int[nb * W * H];
        //vai buscar todos pixeis
        inputRaster.getPixels(0, 0, W, H, pixels);

        //Criar nova imaguem com novas dimensoes!
        BufferedImage ni = new BufferedImage(W, H, BufferedImage.TYPE_INT_RGB);

        WritableRaster outputRaster = ni.getRaster();
        
       
        for (int i = 0; i < W-1; i++) {    
    for (int j = 0; j < H-1; j++) {    
  
        int bluefinal  = 0;    
        int redfinal   = 0;    
        int greenfinal = 0;  
          
        for (int x = 0; x <matrix.length; x++) {  
            for (int y = 0; y< matrix.length; y++) {  
                Color c = new Color(image.getRGB(i + x, j + y));    
                  
                redfinal   =+ c.getRed();    
                greenfinal =+ c.getGreen();  
                bluefinal  =+ c.getBlue();    
            }  
        }   


       
  
                BufferedImageOp op = new ConvolveOp( new Kernel(3, 3, matrix) );  
                int[] color = {redfinal, greenfinal, bluefinal};  
                outputRaster.setPixel(i, j, color);    
   }    
} 


        ni.setData(outputRaster);
        ImageIO.write(ni, "JPEG", new File("Imagemmodificada.jpg"));
        JFrame frame0 = new JFrame();
        JLabel label0 = new JLabel(new ImageIcon(ni));
        frame0.getContentPane().add(label0, BorderLayout.CENTER);
        frame0.setLocation(W+20, 0);
        frame0.pack();
        frame0.setVisible(true);

    }
}

Graças a vossa ajuda já so falta perceber como fazer os calculos para coloca-la mais nitida :P :P :P :P

S

melhor, tenho e de por a matriz a percorrer a imagem -.-’’

Criado 13 de abril de 2012
Ultima resposta 14 de abr. de 2012
Respostas 11
Participantes 4