Limiar [RESOLVIDO]

[color=red]// seleciona a imagem
BufferedImage img = ImageIO.read(fc.getSelectedFile());

// Altera os pixels
for (int y = 0; y < img.getHeight(); y++)
for (int x = 0; x < img.getWidth(); x++) {
Color color = new Color(img.getRGB(x, y));
if (color.equals(Color.BLACK)) {
img.setRGB(x, y, Color.WHITE.getRGB());
}
}
// Grava a saída no arquivo output.png
ImageIO.write(img, “png”, new File(“output.png”));
}
}[/color]

vc precisa fazer o complemento subtraindo o valor do pixel pelo máximo valor dele;

por exemplo em um pixel de 8 bits = 255 - f(x,y)

*onde f(x,y) é a coordenada do pixel que você quer alterar.

Para imagens de apenas 1 bit por pixel(imagens binarizadas) é só alterar para 0 ou 1;

é o seguinte, eu carrego a imagem, ai faço o for para percorrer todos pixel certo?
ai eu quero fazer um if, para mim comparar se na coordenada ta preto ou branco, se tiver preto eu pinto para branco e vice-versa,
so q eu nao sei como fazer isso direito, poderia me dar uma ajuda?

[quote=MauroHumberto]é o seguinte, eu carrego a imagem, ai faço o for para percorrer todos pixel certo?
ai eu quero fazer um if, para mim comparar se na coordenada ta preto ou branco, se tiver preto eu pinto para branco e vice-versa,
so q eu nao sei como fazer isso direito, poderia me dar uma ajuda?[/quote]

Opa, este artigo vai sanar as suas dúvidas. Dá uma lida com calma.

http://javaboutique.internet.com/tutorials/rasters/

É só aplicar o que o Julio acabou de te falar…

[code]package br.com.guj.imagem;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;

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

public class Negativo {
private static JFileChooser chooser = new JFileChooser();

static {
	chooser.setFileFilter(new FileNameExtensionFilter(&quot;Imagens&quot;, &quot;jpg&quot;,
			&quot;png&quot;, &quot;bmp&quot;));
	chooser.setAcceptAllFileFilterUsed(false);
}

public static void main(String[] args) {
	try {
		if (chooser.showOpenDialog(null) != JFileChooser.APPROVE_OPTION)
			return;

		File file = chooser.getSelectedFile();
		BufferedImage img = ImageIO.read(file);
		// Inverte a imagem
		for (int y = 0; y &lt; img.getHeight(); ++y)
			for (int x = 0; x &lt; img.getWidth(); ++x) {
				Color pixel = new Color(img.getRGB(x, y));
				// Aplicamos a fórmula que o julio falou
				Color inverso = new Color(
						255 - pixel.getRed(),
						255 - pixel.getGreen(), 
						255 - pixel.getBlue());

				// Definimos novamente no pixel
				img.setRGB(x, y, inverso.getRGB());
			}

		file = new File(file.getParentFile(), &quot;inverso.png&quot;);
		ImageIO.write(img, &quot;png&quot;, file);
		JOptionPane.showMessageDialog(null, &quot;&lt;html&gt;&lt;body&gt;Imagem:<br>"
				+ file.getAbsolutePath() + "<br>Gerada com sucesso!");
	} catch (Exception e) {
		JOptionPane.showMessageDialog(null,
				"Não foi possível inverter a imagem.");
	}

}

}
[/code]

1 curtida

Só um detalhe o código que você postou ali em cima (e que demorei a ler pq vc não usou a tag code), está correto. Porém, ele só funciona para imagens binarizadas, ou seja, aquelas que ou o pixel é inteiramente preto (0) ou o pixel é inteiramente branco (255). Não funciona para escala de cinza ou para imagens coloridas.

Seria legar dar uma olhada nos rasters que o julio passou por questões de performance. Porém, se você realmente for trabalhar com imagens e processamento de vídeo, saia do Java e use a opencv com C++. A performance é incomparavelmente melhor. Outra API que pode te ajudar, se vc quiser se manter com o Java, é o binding de OpenCV para java, chamado JavaCV.

O exemplo do vini godoy acima é bem prático. Ele vai criar um efeito de “negativo” em imagens coloridas(as que possuem 3 bandas(verm, verd, azu).

Se você precisar de um resultado na escala de cinza você pode aplicar a “média” nas bandas :

ec(x,y) = (r(x,y)+g(x,y)+b(x,y))/3

ou mesmo pegar somente a luminância aplicando as constantes(a lumiância é somente a intensidade da luz)

Y(x,y) = ((r(x,y) 0.3086)+(g(x,y)0.6094)+(b(x,y)0.0820)

Outra possibilidade é fazer limiarização, caso você tenha uma imagem colorida. Ou seja, transformar a imagem em binária (só com tons 0 ou 255).

Isso geralmente é feito através de uma constante, chamada de limiar (threshold).
Toda luminância abaixo dela, terá o pixel setado para 0, acima, para 255.

Basicamente, é só aplicar uma das fórmulas do post acima e tratar isso com um operador ternário:

lim(x,y) = ec(x,y) &lt; t ? 0 : 255;

Uma forma comum para se descobrir um bom valor para limiar automaticamente, é usar o algorítmo de otsu:
http://www.labbookpages.co.uk/software/imgProc/otsuThreshold.html