Eu preciso ler uma imagem em tons de cinza pra fazer um algoritmo de quadtree para um trabalho de PDI. Preciso pegar o tom de cinza de cada coordenada da imagem pra fazer uma comparação.
O professor disse pra usar essa classe mas não disse mais nada e eu já olhei na API mas estou perdido.
Alguém pode me ajudar?
Para carregar um BufferedImage:
BufferedImage bi = ImageIO.read(new File("C:/suaImagem.png"));
Para pegar o tom baseado na coordenada:
Color pixel = new Color(bi.getRGB(x,y));
int tom = pixel.getRed(); //Red, Green e Blue em uma imagem Grayscale são iguais
Se a imagem for colorida, você pode passa-la para tons de cinza através do cálculo da luminância. A forma mais simples desse cálculo é:
int tom = (pixel.getRed() + pixel.getGreen() + pixel.getBlue()) / 3;
Para mais informações sobre como trabalhar com imagens:
E como seria um metodo que passa a imagem pra escala de cinza? Teria 2 for aninhado?
Poderia por favor me mostrar como seria sua implementação?
Interessante. Pode me explicar esse trecho do codigo?
Graphics2D g2d = pretaEBranca.createGraphics();
g2d.drawImage(imagem, 0,0, null);
g2d.dispose();
ImageIO.write(pretaEBranca, "png", new File("imagempb.png"));
Tem coisa aí que eu nunca vi antes.
http://www.pontov.com.br/site/java/48-java2d/93-uma-visao-rapida-sobre-o-java-2d
http://www.pontov.com.br/site/java/48-java2d/111-trabalhando-com-imagens
Vlw muito obrigado!
Eu to usando
private static BufferedImage toGrayscale(BufferedImage image){
Color cor;
int i;
for (int x = 0; x < image.getWidth(); x++) {
for (int y = 0; y < image.getHeight(); y++) {
cor = new Color(image.getRGB(x, y));
i = (cor.getRed()+cor.getGreen()+cor.getBlue())/3;
image.setRGB(x, y, i);
}
}
return image;
}
Mas a imagem ta ficando em tons de azul O.o
Claro, pois vc com a fórmula só calculou o tom da iluminação. Para que ela fique em escala de cinza, esse mesmo tom deve ser usado para os valores de R, G e B:
private static BufferedImage toGrayscale(BufferedImage image){
for (int x = 0; x < image.getWidth(); x++) {
for (int y = 0; y < image.getHeight(); y++) {
Color cor = new Color(image.getRGB(x, y));
int i = (cor.getRed()+cor.getGreen()+cor.getBlue())/3;
image.setRGB(x, y, new Color(i, i, i).getRGB());
}
}
return image;
}
No caso de grayscale, é mais rápido usar a conversão do próprio Java:
private static BufferedImage toGrayscale(BufferedImage image)
throws IOException {
BufferedImage output = new BufferedImage(image.getWidth(),
image.getHeight(), BufferedImage.TYPE_BYTE_GRAY);
Graphics2D g2d = output.createGraphics();
g2d.drawImage(image, 0, 0, null);
g2d.dispose();
return output;
}
Eu até tava usando mas me incomoda usar codigo que eu não faço ideia do que faz e esse eu tentei entender e não consegui.
Cara, agora o problema eh com esse codigo:
public static void pintarTeste(){
for (int x = 0; x < imagem.getWidth(); x++) {
for (int y = 0; y < imagem.getHeight(); y++) {
imagem.setRGB(x, y, Color.green.getRGB());
}
}
}
Depois de executa-lo a imagem aparece pra mim como toda cinza. To quase desistindo desse programa ja…
Como você criou a variável imagem? No construtor você usou o tipo TYPE_INT_ARGB?
Pq se a imagem for TYPE_BYTE_GRAY (como eu usei ali), o Java irá converter automaticamente as cores fornecidas em tons de cinza.
Vish. Como que eu faço então?
Por enquanto to usando o método que seta em tom de cinza pixel por pixel com a media do RGB.
Se sua imagem é mesmo colorida, então aquele código ali deveria funcionar sim.
Deveria deixar a imagem toda verde.
Não, realmente eu estava transformando ela em escala de cinza. Mas agora eu to deixando rgb e mandando com akele metodo de pixel por pixel mesmo.
Pior que ainda assim não estou conseguindo fazer funcionar essa bagaça. O negócio eh o seguinte, estou implementando um algoritmo de Quadtree.
Esse método tem que me retornar se o quadrante da imagem que estou analisando contém apenas pixels dentro de um intervalo que eu estabeleci (que me dará que é um objeto), se contem apenas pixels fora desse intervalo (que me dará que e só o fundo), ou se contem os dois pra eu quebrar novamente em 4 quadrantes e analisar recursivamente montando uma arvore de quatro filhos cada nó (daí o nome) onde as folhas contém só objeto ou só fundo.
public boolean AnalisaQuadrante() {
int cor;
boolean fundo = false;
boolean objeto = false;
/*
* varre o quadrante analisando pixel a pixel se este se encontra no
* intervalo de cor do objeto
*/
for (int x = quadrante.getX(); x < quadrante.getLargura(); x++) {
for (int y = quadrante.getY(); y < quadrante.getAltura(); y++) {
cor = new Color(Quadtree.imagem.getRGB(x, y)).getGreen();//lembrando que as cores sao todas iguais
System.out.print(cor+": ");
if (cor > Quadtree.getMin() && cor < Quadtree.getMax()) {
objeto = true;
System.out.println("pixel de objeto");
} else {
fundo = true;
System.out.println("pixel de fundo");
}
}
/*
* Ao final de cada linha analisa se foram encontrados pixels de
* fundo e de objeto. Se sim, já retorna false indicando que não eh folha
*/
System.out.println("Fim de linha");
if (fundo && objeto) {
System.out.println("Heterogeneo detectado");
return false;
}
}
System.out.println("Fim de Quadrante");
// se for um objeto, já pinta este quadrante
if (objeto) {
System.out.println("FOLHA OBJETO DETECTADO!!!");
this.quadrante.pintar();
} else {
System.out.println("Folha fundo detectado.");
}
return true;
}
O limiar que estou utilizando é de 0 até 250 e a imagem é
Quando eu executo ele, ele não me identifica nenhuma folha como objeto, tudo como fundo. Não sei mais o que fazer…