Seleção e Processamento de Imagem

Olá, alguem saberia me informar o melhor jeito de trabalhar em uma imagem pixel a pixel? eu desenvolvi o seguinte código fonte para analisar os tons de cinza em uma imagem, mas ele sempre me retorna que todos os pixels sao cinzas x(
alguem consegue ver uma solução melhor pra trabalhar com os ppixels?

[code] JFileChooser Destino = new JFileChooser();
Destino.setDialogTitle(“Selecione a imagem para análise…”);
Destino.showOpenDialog(this);
int Cont = 0;
ImageIcon Imagem = new ImageIcon(Destino.getSelectedFile().getAbsolutePath());
IMG = new BufferedImage(Imagem.getIconWidth(), Imagem.getIconHeight(), 1);
for(int i = 0; i < IMG.getWidth(); i++){
for(int j = 0; j < IMG.getHeight(); j++){
Pixel = new Color(IMG.getRGB(i, j));
if((Pixel.getRed() == Pixel.getGreen()) && (Pixel.getRed() == Pixel.getBlue())){
Cont++;
}

            }  
        }          
        this.Percentual = Cont;  
        JOptionPane.showMessageDialog(null, this.Percentual + " é a quantidade de tons de cinza que tem na imagem");  [/code]

Uma soluções seria usando BufferedImage mesmo, realizando operações com bits ou ainda usando a classe Color:

[code]
package com.togoworks.procimg;

import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;

public class GrayCounter {
public static void main(String[] args) {
try {
BufferedImage image;
JFileChooser fileChooser = new JFileChooser();

		fileChooser.showOpenDialog(null);
		image = ImageIO.read(fileChooser.getSelectedFile());
		
		int count = 0;
		for (int y = 0; y < image.getHeight(); y++) {
			for (int x = 0; x < image.getHeight(); x++) {
				final int rgb = image.getRGB(x, y);
				
				/*
				 * Como um pixel é representado por um inteiro de 4-bytes (32 bit)
				 * da seguinte maneira:
				 * 
				 * 00000000 00000000 00000000 11111111
				 * ^ Alpha  ^Red     ^Green   ^Blue
				 * 
				 * Podemos realizar alguns deslocamentos(operações com bits) obtendo: 
				 */
				final int red = (rgb >> 16) & 0x000000FF;
				final int green = (rgb >>8 ) & 0x000000FF;
				final int blue = (rgb) & 0x000000FF;
				
				//Comparando as intensidades 
				if (red == green && green == blue) {
					//Caso verdade temos um nível de cinza
					count++;
				}
			}
		}
		
		JOptionPane.showMessageDialog(null, String.format("Níveis de cinza: %d", count));
		
	} catch (IOException e) {
		e.printStackTrace();
	}
	
}

}[/code]
Referências:

  1. http://www.lac.inpe.br/~rafael.santos/Docs/CursoInverno/2009/ProcImagens-CI2009.pdf
  2. http://stackoverflow.com/questions/2615522/java-bufferedimage-getting-red-green-and-blue-individually

Em termos de performance, o melhor jeito é usando rasters. Se quiser ver muito material de referência sobre o assunto, leia:

Embora o processamento de imagens seja mais facilmente realizado em C++, com a opencv (existe um binding para essa biblioteca em Java chamado javacv).