Javacv Detectar face em Jpanel

11 respostas
R

Olá boa tarde.

Então estou tentando fazer um programa apenas de detecção de face e não fazer uso do CanvasFrame, obtive no canal do Abner Rodrigues os meios para tal, implementei o código fazendo uso do objeto videoCapture mais não funcionou ou seja não apresenta a imagem na webcam (mais não ocorre nenhum erro), mudei e fiz uso do OpenCVFrameGrabber e sim ai funcionou porém acredito que a imagem obtida da webcan ficou com um delay…, estou usando a versão 1.4.3 do Javacv.

Mudei então para a versão 1.5 para ver se rolava com o objeto videoCapture mais ai realmente deu o tilte, piorou porque a lib deve ter tido uma refatoração grande, os import´s agora todos estão errados, consegui resolver alguns mais não todos como por exemplo o objeto imencode, resize não sei em que pacote estão.

Segue o código que esta dando certo com .

public class Painel extends javax.swing.JDialog {

    String fileName = "cascade/haarcascade-frontalface-alt.xml";
    ClassLoader classLoader = new Deteccao().getClass().getClassLoader();
    File file = new File(classLoader.getResource(fileName).getFile());

    //JavaCV
    //opencv_videoio.VideoCapture webSource = null;
    org.bytedeco.javacv.OpenCVFrameGrabber webSource;
    opencv_core.Mat cameraImage = new opencv_core.Mat();
    opencv_objdetect.CascadeClassifier cascade = new opencv_objdetect
		.CascadeClassifier(file.getAbsolutePath());
    //opencv_face.FaceRecognizer recognizer = opencv_face.LBPHFaceRecognizer.create();   
    Java2DFrameConverter paintConverter = new Java2DFrameConverter();       
    OpenCVFrameConverter.ToMat converterToMat = new OpenCVFrameConverter.ToMat();
    BytePointer mem = new BytePointer();
    opencv_core.RectVector detectedFaces = new opencv_core.RectVector();

    private Painel.DaemonThread myThread = null;

private javax.swing.JLabel label_photo;


public Painel(java.awt.Frame parent, boolean modal) {
    super(parent, modal);
    initComponents();
    //recognizer.read("C:\\photos\\classifierLBPH.yml");
    //recognizer.setThreshold(280);
    startCamera();
}


public void stopCamera() {
	if (myThread.runnable) {
       myThread.runnable = false;
       //webSource.release();
       try {
		   webSource.close();
	   } catch (Exception e) {
		   // TODO Auto-generated catch block
		   e.printStackTrace();
	   }
    }
    dispose();
}

public void startCamera() {
    new Thread() {
        @Override
        public void run() {
            //webSource = new opencv_videoio.VideoCapture(0);
            webSource = new OpenCVFrameGrabber(-1);
            myThread = new Painel.DaemonThread();
            Thread t = new Thread(myThread);
            t.setDaemon(true);
            myThread.runnable = true;
            t.start();
        }
    }.start();
}
    
private void initComponents() {
	setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
	getContentPane().setLayout(null);
	
    JPanel panelMain = new JPanel();
	label_photo = new javax.swing.JLabel();
    JPanel panel1 = new JPanel();
	  		
    //panelMain.setBackground(Color.BLUE);
    panelMain.setBounds(0, 0, 330, 420);
    getContentPane().add(panelMain);
    panelMain.setLayout(null);
    
    label_photo.setBounds(10, 10, 310, 400);
    label_photo.setBorder(new LineBorder(new Color(255, 255, 255)));
    panelMain.add(label_photo);
    
    panel1.setBorder(new LineBorder(new Color(255, 255, 255)));
    panel1.setBounds(330, 0, 430, 420);
    panel1.setBackground(new java.awt.Color(255, 255, 255));
    getContentPane().add(panel1);
    panel1.setLayout(null);
	
	setSize(new java.awt.Dimension(780, 420));
    setLocationRelativeTo(null);
}


public static void main(String arg[]) {
	/* Create and display the dialog */
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            Painel dialog = new Painel(new javax.swing.JFrame(), true);
            dialog.addWindowListener(new java.awt.event.WindowAdapter() {
                @Override
                public void windowClosing(java.awt.event.WindowEvent e) {
                    System.exit(0);
                }
            });
            dialog.setVisible(true);
        }
    });		
}

class DaemonThread implements Runnable {

    protected volatile boolean runnable = false;

    @Override
    public void run() {
        synchronized (this) {
            while (runnable) {
                try {
                	
                	webSource.start();
                	org.bytedeco.javacv.Frame frameCapturado = null;
                	
                    long startTime = System.currentTimeMillis();
                    long frame = 0;
                	while ((frameCapturado = webSource.grab()) != null && runnable) {
                    //if ( (frameCapturado = webSource.grab()) != null) {
                        //BufferedImage buff = paintConverter.getBufferedImage(frameCapturado, 1);
                        //Graphics g = canvas.getGraphics();
                        //g.drawImage(buff, 0, 0, CAPTUREWIDTH, CAPTUREHRIGHT, 0, 0, buff.getWidth(), buff.getHeight(), null);                    		                    		
                		
                        //webSource.retrieve(cameraImage);
                    	cameraImage = converterToMat.convert(frameCapturado);
                        Graphics g = label_photo.getGraphics();

                        opencv_core.Mat imageGray = new opencv_core.Mat();
                        cvtColor(cameraImage, imageGray, COLOR_BGRA2GRAY);
                        opencv_core.RectVector detectedFace = new opencv_core.RectVector();
                        cascade.detectMultiScale(imageGray, detectedFace, 1.1, 2, 0, new opencv_core.Size(150, 150), new opencv_core.Size(500, 500));

                        for (int i = 0; i < detectedFace.size(); i++) {
                            opencv_core.Rect dadosFace = detectedFace.get(i);
                            rectangle(cameraImage, dadosFace, new opencv_core.Scalar(0, 255, 0, 0));
                            opencv_core.Mat faceCapturada = new opencv_core.Mat(imageGray, dadosFace);
                            opencv_imgproc.resize(faceCapturada, faceCapturada, new opencv_core.Size(160, 160));
                        }

                        imencode(".bmp", cameraImage, mem);
                        Image im = ImageIO.read(new ByteArrayInputStream(mem.getStringBytes()));
                        BufferedImage buff = (BufferedImage) im;

                        try {
                            if (g.drawImage(buff, 0, 0, 310, 400, 0, 0, buff.getWidth(), buff.getHeight(), null)) {
                                if (runnable == false) {
                                    this.wait();
                                }
                            }
                        } catch (NullPointerException e) {
                        	e.printStackTrace();
                        }                            
                    }
                } catch (IOException | InterruptedException ex) {
                	ex.printStackTrace();
                }
            }
        }
    }
}

}

e aqui o código que esta não esta apresentando a imagem da webcam que usa o objeto VideoCapture

public class Painel2 extends javax.swing.JDialog {

    String fileName = "cascade/haarcascade-frontalface-alt.xml";
    ClassLoader classLoader = new Deteccao().getClass().getClassLoader();
    File file = new File(classLoader.getResource(fileName).getFile());

    //JavaCV
    VideoCapture webSource = null;
    //opencv_videoio.VideoCapture webSource = null;
    Mat cameraImage = new Mat();
    CascadeClassifier cascade = new CascadeClassifier(file.getAbsolutePath());
    //opencv_face.FaceRecognizer recognizer = opencv_face.LBPHFaceRecognizer.create();   

    BytePointer mem = new BytePointer();
    RectVector detectedFaces = new RectVector();

    private Painel2.DaemonThread myThread = null;    
    private javax.swing.JLabel label_photo;    

    public Painel2(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        initComponents();
        //recognizer.read("C:\\photos\\classifierLBPH.yml");
        //recognizer.setThreshold(280);
        startCamera();
    }

    public void stopCamera() {
        myThread.runnable = false;
        webSource.release();
        dispose();
    }

    public void startCamera() {
        new Thread() {
            @Override
            public void run() {
                webSource = new VideoCapture(-1);
                myThread = new Painel2.DaemonThread();
                Thread t = new Thread(myThread);
                t.setDaemon(true);
                myThread.runnable = true;
                t.start();
            }
        }.start();
    }
    
    private void initComponents() {
	    setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
	    getContentPane().setLayout(null);
	
        JPanel panelMain = new JPanel();
	    label_photo = new javax.swing.JLabel();
        JPanel panel1 = new JPanel();
	  		
        panelMain.setBounds(0, 0, 330, 420);
        getContentPane().add(panelMain);
        panelMain.setLayout(null);
    
        label_photo.setBounds(10, 10, 310, 400);
        label_photo.setBorder(new LineBorder(new Color(255, 255, 255)));
        panelMain.add(label_photo);
    
        panel1.setBorder(new LineBorder(new Color(255, 255, 255)));
        panel1.setBounds(330, 0, 430, 420);
        panel1.setBackground(new java.awt.Color(255, 255, 255));
        getContentPane().add(panel1);
        panel1.setLayout(null);
	
	    setSize(new java.awt.Dimension(780, 420));
        setLocationRelativeTo(null);
    }
	
    public static void main(String arg[]) {
        /* Create and display the dialog */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                Painel2 dialog = new Painel2(new javax.swing.JFrame(), true);
                dialog.addWindowListener(new java.awt.event.WindowAdapter() {
                    @Override
                    public void windowClosing(java.awt.event.WindowEvent e) {
                        System.exit(0);
                    }
                });
                dialog.setVisible(true);
            }
        });		
    }

    class DaemonThread implements Runnable {

        protected volatile boolean runnable = false;

        @Override
        public void run() {
            synchronized (this) {
                while (runnable) {
                    try {                    	
                        if (webSource.grab()) {                        	
                    	                            webSource.retrieve(cameraImage);
                            Graphics g = label_photo.getGraphics();

                            org.bytedeco.opencv.opencv_core.Mat imageGray = new org.bytedeco.opencv.opencv_core.Mat();
                            cvtColor(cameraImage, imageGray, COLOR_BGRA2GRAY);

                            org.bytedeco.opencv.opencv_core.RectVector detectedFace = new org.bytedeco.opencv.opencv_core.RectVector();
                            cascade.detectMultiScale(imageGray, detectedFace, 1.1, 2, 0, new org.bytedeco.opencv.opencv_core.Size(150, 150), new org.bytedeco.opencv.opencv_core.Size(500, 500));

                            for (int i = 0; i < detectedFace.size(); i++) {
                        	    org.bytedeco.opencv.opencv_core.Rect dadosFace = detectedFace.get(i);
                                rectangle(cameraImage, dadosFace, new org.bytedeco.opencv.opencv_core.Scalar(0, 255, 0, 0));
                                org.bytedeco.opencv.opencv_core.Mat faceCapturada = new org.bytedeco.opencv.opencv_core.Mat(imageGray, dadosFace);
                                resize(faceCapturada, faceCapturada, new org.bytedeco.opencv.opencv_core.Size(160, 160));                                                                
                            }

                            imencode(".bmp", cameraImage, mem);
                            Image im = ImageIO.read(new ByteArrayInputStream(mem.getStringBytes()));
                            BufferedImage buff = (BufferedImage) im;

                            try {
                                if (g.drawImage(buff, 0, 0, 310, 400, 0, 0, buff.getWidth(), buff.getHeight(), null)) {
                                    if (runnable == false) {
                                        this.wait();
                                    }
                                }
                            } catch (NullPointerException e) {
                        	    e.printStackTrace();
                            }
                        }
                    } catch (IOException | InterruptedException ex) {
                	    ex.printStackTrace();
                    }
                }
            }
        }
    }	
}

11 Respostas

FearX

Vamos ver o que ele te diz.

@rodriguesabner

R

Imports corrigidos de 1.4 para 1.5

// 1.4
//import static org.bytedeco.javacpp.opencv_imgcodecs.imencode;
//import org.bytedeco.javacpp.opencv_imgproc;
//import static org.bytedeco.javacpp.opencv_imgproc.COLOR_BGRA2GRAY;
//import static org.bytedeco.javacpp.opencv_imgproc.cvtColor;
//import static org.bytedeco.javacpp.opencv_imgproc.rectangle;

//import org.bytedeco.javacpp.BytePointer;
//import org.bytedeco.javacpp.opencv_core;
//import org.bytedeco.javacpp.opencv_face;
//import org.bytedeco.javacpp.opencv_objdetect;
//import org.bytedeco.javacpp.opencv_videoio;
//import org.bytedeco.javacv.FrameGrabber.Exception;
//import org.bytedeco.javacv.Java2DFrameConverter;
//import org.bytedeco.javacv.OpenCVFrameConverter;
//import org.bytedeco.javacv.OpenCVFrameGrabber;

//1.5     
import static org.bytedeco.opencv.global.opencv_imgcodecs.imencode;
import static org.bytedeco.opencv.global.opencv_imgproc.resize;
import static org.bytedeco.opencv.global.opencv_imgproc.COLOR_BGRA2GRAY;
import static org.bytedeco.opencv.global.opencv_imgproc.cvtColor;
import static org.bytedeco.opencv.global.opencv_imgproc.rectangle;

import org.bytedeco.javacpp.BytePointer;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.bytedeco.javacv.OpenCVFrameConverter;
import org.bytedeco.javacv.OpenCVFrameGrabber;
import org.bytedeco.opencv.opencv_core.Mat;
import org.bytedeco.opencv.opencv_core.Rect;
import org.bytedeco.opencv.opencv_core.RectVector;
import org.bytedeco.opencv.opencv_core.Scalar;
import org.bytedeco.opencv.opencv_core.Size;
import org.bytedeco.opencv.opencv_objdetect.CascadeClassifier;
import org.bytedeco.opencv.opencv_videoio.VideoCapture;
R

Olá boa noite

Cara com a versão 1.5 depois que corrigi os imports deu tudo Ok ,blz

rodriguesabner

Funcionou tudo certinho?

R

Opa Abner boa noite, sim tudo certo inclusive a duvida que me bateu era o delay mais agora ta mais rápido ( tem sempre um delay mais ta mais rápido ) inclusive a questão era ver a diferença entre o OpenCVFrameGrabber e o VideoCapture mais praticamente não da pra perceber diferenças.

rodriguesabner

Entendi, boa noite Lira! Cara, geralmente o que causa lentidão é essa linha:

if (g.drawImage(buff, 0, 0, 310, 400, 0, 0, buff.getWidth(), buff.getHeight(), null)) {
   ....
}

310, 400 é o tamanho do componente, se você deixa-lo muito grande, a qualidade vai aumentar e isso pode causar uma certa lentidão.

Mas fico feliz por ter conseguido!!

R

Cara agradeço você por ter compartilhado seu aprendizado, tempo, projeto… me ajudou muito havia um tempo que eu procurava por um substituto do CanvasFrame até cheguei a fazer algo mais não estava legal agora vou aos poucos, esta classe é de detecção, agora vou evoluindo até chegar ao reconhecimento.

Um Abraço.

rodriguesabner

Mas o projeto já tem o reconhecimento também!

R

Sim, correto sei que tem mais eu sou novato!

Quero neste primeiro momento dividir , fazer a

  1. Detecção
  2. Treinamento
  3. Reconhecimento
  4. Juntar tudo como vc fez

depois quero ver como usar duas cameras…, gravar video…

R

Já vi em Lojas aquele mosaico com imagens de quatro câmeras… quero ver se faço aquilo

rodriguesabner

Ahhhhh, entendi! Olha, eu estou fazendo o JavaDoc do projeto, talvez eu possa fazer as classes separadas, tem bastante gente perdida.

Sobre as imagens das cameras, não tem muita dificuldade. Você pode fazer uma classe para mostrar a imagem da câmera (o VideoCapture por exemplo), ai cria um JFrame com os JLabels necessários (cada JLabel vai receber uma imagem de câmera), e conforme o usuário for clicando, ele vai preenchendo a JLabel com a imagem, falando assim parece ser um pouco difícil, mas até que é simples

Criado 13 de junho de 2019
Ultima resposta 13 de jun. de 2019
Respostas 11
Participantes 3