Limiar [RESOLVIDO]

7 respostas
M

[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]

7 Respostas

J

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;

M

é 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?

J

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?

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

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

V

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

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.");
		}

	}
}
V

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.

J

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)

V

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

Criado 13 de fevereiro de 2012
Ultima resposta 14 de fev. de 2012
Respostas 7
Participantes 3