Java e Opencv

Pessoal, eu gostaria de tirar uma duvida com vocês…

Alguem já mexeu, ou sabe o caminho, ou até se existe a biblioteca OPEN CV para JAVA…

Meu professor de computação grafica falou que existe mais eu não consegui encontrar nada…

Gostaria de deixar minhas imagens (fotos) em escala cinza e depois preto e branco…

Alguem sabe como fazer, se é a OPEN CV que faz isso mesmo, ou não…

Se alguem pudesse me dar alguma dica ficaria muito feliz…

Outra duvida tosca minha é para fixar uma casa decimal haha…

Minha variavel é do tipo double só que aparece no meu textfield com muitas casas decimais… eu coloquei o codigo assim:


txtF11.setText(String.valueOf((aux11*temp11)+(aux12*temp21)));

txtF11 é o nome do meu textfield, só que eu gostaria que ele ficasse aparecendo só com duas casas decimais…

Me falaram que dava para mexer nas propriedades dele, mais nada consegui…

Se alguem pudesse me ajudar nessas duvidas, sei que o da imagem é mais trampo, mais se alguem puder me dar uns exemplos, de codigos, umas dicas

um forte abraço e fiquem com Deus!!!

Em primeiro lugar, evite postar tópicos usando APENAS LETRAS MAIÚSCULAS.

Biblioteca java com opencv: http://code.google.com/p/javacv/

Para limitar o número de casas decimais, use o String.format:

Se você só quer deixar as imagens em escala de cinza, usar a OpenCV é como usar um canhão para matar uma mosca. Você pode fazer isso com o próprio Java2D:

BufferedImage imagem = ImageIO.read(new File("imagem.png")); BufferedImage pretaEbranca = new BufferedImage(imagem.getWidth(), imagem.getHeight(), BufferedImage.TYPE_BYTE_GRAY); Graphics2D g2d = pretaEBranca.createGraphics(); g2d.drawImage(imagem, 0,0, null); g2d.dispose(); ImageIO.write(pretaEBranca, "png", new File("imagempb.png"));

Você pode fazer depois a binarização usando um algorítmo de threshold simples, a menos que seu professor exija algo mais sofisticado, o que não deve ser o caso.

A opencv tem diversas operações. Além de conversão em diferentes formatos, ela também possui operadores morfológicos (dilatação, erosão, abertura, fechamento, reconstrução), filtros (bordas, suavização, etc) e até funções para segmentação (knn, svn, etc) e rastreamento. É uma blioteca muito completa e extremamente otimizada.

Segue um exemplo do programa, fazendo a conversão para escala de cinza e limiriazação simples:

[code]package br.com.guj;

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

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

public class Imagem {

public static void main(String[] args) {
	JFileChooser chooser = new JFileChooser();
	chooser.setFileFilter(new FileNameExtensionFilter("Image files", "png",
			"jpg", "bmp"));
	chooser.setAcceptAllFileFilterUsed(false);

	if (chooser.showOpenDialog(null) != JFileChooser.APPROVE_OPTION)
		return;

	try {
		// Carregamos a imagem do disco
		File img = chooser.getSelectedFile();
		BufferedImage image = ImageIO.read(img);

		// Geramos uma versão em escala de cinza
		BufferedImage gray = toGrayscale(image);
		ImageIO.write(gray, "png", newFile(img, "gray"));

		// Geramos uma versão binária a partir da versão em escala de cinza.
		BufferedImage binary = toBinary(gray, 128);
		ImageIO.write(binary, "png", newFile(img, "binary"));
	} catch (Exception e) {
		JOptionPane.showMessageDialog(null, "Erro ao processar imagem.");
		e.printStackTrace();
	}
}

/**
 * Converte a imagem para escala de cinza.
 * 
 * @param image Imagem a ser convertida
 * @return a Imagem convertida.
 */
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;
}

/**
 * Converte a imagem para binário usando um algorítmo de threshold simples.
 * Tudo que estiver abaixo do threshold será convertido para preto. Acima ou
 * igual ao threshold será convertido para branco.
 * 
 * @param image
 *            Imagem a ser convertida (apenas o canal r será considerado).
 *            Use uma escala já transformada em escala de cinza para
 *            melhores resultados.
 * @param t
 *            Valor do threshold.
 */
private static BufferedImage toBinary(BufferedImage image, int t) {
	int BLACK = Color.BLACK.getRGB();
	int WHITE = Color.WHITE.getRGB();

	BufferedImage output = new BufferedImage(image.getWidth(),
			image.getHeight(), BufferedImage.TYPE_BYTE_GRAY);

	// Percorre a imagem definindo na saída o pixel como branco se o valor
	// na entrada for menor que o threshold, ou como preto se for maior.
	for (int y = 0; y < image.getHeight(); y++)
		for (int x = 0; x < image.getWidth(); x++) {
			Color pixel = new Color(image.getRGB(x, y));
			output.setRGB(x, y, pixel.getRed() < t ? BLACK : WHITE);
		}

	return output;
}

/**
 * Gera um nome de arquivo baseado no nome fornecido. O arquivo terá o mesmo
 * caminho do nome original.
 * <p>
 * Exemplo: Se o arquivo for c:\fish.png e a string de detalhe for "gray" a
 * saída será c:\fish-gray.png
 * 
 * A extensão final sempre será png.
 * 
 * @param file Arquivo original
 * @param detail String de detalhe
 * @return O nome do arquivo.
 */
private static File newFile(File file, String detail) {
	return new File(file.getParentFile(), file.getName().substring(0,
			file.getName().indexOf("."))
			+ "-" + detail + ".png");

}

}
[/code]

Em anexo, as imagens geradas pelo programa (usei threshold de 175, e não 128, para obter um resultado melhor na binarização).
Se quiser conhecer um processo para descobrir o threshold automaticamente, procure pelo algoritmo de otsu.





1 curtida

Amigo, eu já consegui criar e fazer o exemplo que vc me passou…
Tem jeito de fazer assim: eu criei uma imagem pelo qual eu guardo em banco (BINARY)

byte[] imageDataByteArray = new byte[(int) arquivo.length()];
                   InputStream is = new FileInputStream(arquivo);
                   is.read(imageDataByteArray);
                   is.close();

Tem jeito desse binario ou da imagem que pego do arquivo do PC criar a imagem em binario e em cinza para jogar no banco ao inves de salvar???

2

Ola Gostaria de saber como tirar uma foto da webcam utilizando o framework opencv.
Desde ja obrigado.

Basta usar a classe VideoCapture. Esse programa, presente nos exemplos da opencv, apresenta o vídeo da câmera e captura um screenshot sempre que o espaço é pressionado:

[code]/*

  • starter_video.cpp
  • Created on: Nov 23, 2010
  •  Author: Ethan Rublee
    
  • A starter sample for using opencv, get a video stream and display the images
  • easy as CV_PI right?
    */
    #include “opencv2/highgui/highgui.hpp”
    #include <opencv2/objdetect/objdetect.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    #include <iostream>
    #include <vector>
    #include <stdio.h>

using namespace cv;
using namespace std;

//hide the local functions in an anon namespace
namespace
{
void help(char** av)
{
cout << "\nThis program justs gets you started reading images from video\n"
"Usage:\n./" << av[0] << " <video device number>\n" << "q,Q,esc – quit\n"
<< "space – save frame\n\n"
<< "\tThis is a starter sample, to get you up and going in a copy pasta fashion\n"
<< "\tThe program captures frames from a camera connected to your computer.\n"
<< "\tTo find the video device number, try ls /dev/video* \n"
<< "\tYou may also pass a video file, like my_vide.avi instead of a device number"
<< endl;
}

int process(VideoCapture& capture)
{
std::vector<DataMatrixCode> codes;
int n = 0;
char filename[200];
string window_name = “video | q or esc to quit”;
cout << “press space to save a picture. q or esc to quit” << endl;
namedWindow(window_name, CV_WINDOW_KEEPRATIO); //resizable window;
Mat frame;
for (;:wink:
{
capture >> frame;
if (frame.empty())
continue;
cv::Mat gray;
cv::cvtColor(frame,gray,CV_RGB2GRAY);
findDataMatrix(gray, codes);
drawDataMatrixCodes(codes, frame);
imshow(window_name, frame);
char key = (char) waitKey(5); //delay N millis, usually long enough to display and capture input
switch (key)
{
case ‘q’:
case ‘Q’:
case 27: //escape key
return 0;
case ’ ': //Save an image
sprintf(filename, “filename%.3d.jpg”, n++);
imwrite(filename, frame);
cout << "Saved " << filename << endl;
break;
default:
break;
}
}
return 0;
}

}

int main(int ac, char** av)
{

if (ac != 2)
{
help(av);
return 1;
}
std::string arg = av[1];
VideoCapture capture(arg); //try to open string, this will attempt to open it as a video file
if (!capture.isOpened()) //if this fails, try to open as a video camera, through the use of an integer param
capture.open(atoi(arg.c_str()));
if (!capture.isOpened())
{
cerr << "Failed to open a video device or video file!\n" << endl;
help(av);
return 1;
}
return process(capture);
}[/code]

Muito Obrigado mesmo!!! ja aproveitando seus conhecimentos, mais uma duvida, é possivel implementar um filtro pela foto utilizando essa tecnologia?

O que você quer dizer com “um filtro pela foto”?

Desculpa me expressei mal, quis dizer…reconhecimento facial o que ja tinha no forum http://www.guj.com.br/java/232668-deteccao-e-reconhecimento-de-faces.
Valeu.

Só to achando meio complicado para configurar o opencv no dev.

Espero que por “dev” você não queria dizer o “devcpp”.

Se for, provavelmente o opencv não vai funcionar lá. O devcpp é uma IDE antiga (a última versão saiu há 6 anos atrás), que vem com uma versão pré-histórica do MinGW.
A Opencv 2.0 usa muitos recursos novos de templates.

Se quiser uma IDE portável, use o QT Creator:
http://qt.nokia.com/products/developer-tools/

E se quiser fazer para Windows, use o Visual Studio Express:
http://www.microsoft.com/express

Se precisar de uma IDE pequena e portátil como o devcpp, use o Code::Blocks:
http://www.codeblocks.org/

Só não use o DevCpp. É sempre problemático trabalhar com material de museu.

Oi, estou precisando utilizar reconhecimento facial em uma aplicacao.
A ideia seria utilizar a captura da imagem pela webcam e analisar as informacoes da expressao facial tipo boca, olhos, sombrancelha…
É possivel utlizar a javacv para isso? Seria necessario utilizar algum algoratismo?
Obrigada

Dá para fazer, mas não é trivial. Você terá que escrever seu próprio algorítmo.
Deve ter soluções dessas prontas.

Olá pessoal, tudo bem?

só aproveitando o tópico… tenho uma curiosidade…

um amigo meu falou que o JavaCV não funcionava muito bem e era bem mais complicado usá-lo, e que eu era pra usar a versão em C/C++ mesmo… mas tem um problema nisso, não entendo nada de C e no projetinho que estou pensando em fazer gostaria de trabalhar com Java, até pq envolve GlassFish e também Android… a minha dúvida seria: Essa informação procede? é mesmo complicado usar JavaCV ou não tem nada a ver?

Explicando um pouco o projeto: gostaria de identificar padrões de cores em uma imagem, quando me refiro a padrões de cores, quero dizer que terei basicamente 3 cores em uma imagem que gostaria de identificar… e a forma com que elas se apresentam podem ser distintas, mas de forma geral são praticamente circulares, mas detalhe: geralmente uma dentro da outra. O que eu preciso é: 1) identificar esse circulo de determinada cor 2) conseguir o perímetro dele 3) em cima do perímetro calcular a área e achar o centro desse perímetro

seria muito complicado conseguir isso?

agradeço a atenção

Primeiro de tudo. Não existe “C/C++”. O que existem são duas linguagens:

  • Linguagem C: Que usa programação estruturada. Para ele existe a OpenCV 1
  • Linguagem C++: Que suporta os paradigmas estruturado, orientado a objetos, genérico e funcional. A OpenCV 2 é escrita em C++.

O primeiro passo seria escolher em qual das duas você vai trabalhar (eu prefiro a versão em C++).

A OpenCV em Java roda através de um binding, fora da JVM. Não é muito mais difícil de usar do que a versão em C++, mas não espere a mesma portabilidade de uma VM java padrão (não que o Java tenha lá muita portabilidade).
A JavaCV também contém integração com outras APIs além da OpenCV, como o ARToolkit, para realidade aumentada.

Se isso é difícil ou não, depende do que é sua imagem. São imagens geradas no computador? Ou são fotos?
Se forem imagens digitais, é tão fácil que nem mesmo da opencv você realmente precisaria. Se forem fotografias, aí o buraco é bem mais embaixo. Afinal, é difícil dizer o que é uma cor e o que é um círculo, quando as condições de iluminação, ângulos e oclusão variam.

Obrigado Vini pelos esclarecimentos quando ao OpenCV, nunca trabalhei com imagens e com ele…

São imagens geradas. São bem basicas… tem um fundo padrão variando apenas em tons de cinza e as cores por cima. Cores bem definidas, não transparentes e não variando em tonalidade.

Tenho dois azuis (escuro e claro), rosa e branco… geralmente formam formas circulares (não perfeitas) uma dentro da outra… precisaria pegar o perimetro de cada cor e achar seu ponto central… em cima disso calcular a área de cada forma circular de cada cor…

Se não seria necessário OpenCV, com o que eu conseguiria o que eu preciso??

Agradeço a atenção

[quote=paulork]São imagens geradas. São bem basicas… tem um fundo padrão variando apenas em tons de cinza e as cores por cima. Cores bem definidas, não transparentes e não variando em tonalidade.
Tenho dois azuis (escuro e claro), rosa e branco… geralmente formam formas circulares (não perfeitas) uma dentro da outra… precisaria pegar o perimetro de cada cor e achar seu ponto central… em cima disso calcular a área de cada forma circular de cada cor…
Se não seria necessário OpenCV, com o que eu conseguiria o que eu preciso??[/quote]

Cara, eu falei que não seria necessário, mas não falei que seria trivial.
O quanto você entende de processamento de imagens?

Outra coisa, use o botão de attachments para anexar um exemplo de imagem. Assim fica mais fácil te ajudar.

Também não mencionei que seria fácil, estou justamente tentando definir essa “dificuldade”.
Sobre ao quanto eu entendo a resposta seria: praticamente nada!

Para entendermos melhor do que estou falando e tentar definir a complexidade, segue em anexo uma imagem…

OBS - Ponto que gostaria de saber:

  • O que gostaria de saber é qual a complexidade de se conseguir isso?
  • O que eu poderia usar para isso: OpenCV ou o que?

Agradeço a atenção pessoal…


Adquira esse livro:

Nele há um exemplo que descreve passo a passo como obter a informação que você quer.