Javacv Detectar face em Jpanel

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();
                    }
                }
            }
        }
    }	
}
1 curtida

Vamos ver o que ele te diz.

@rodriguesabner

1 curtida

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;

Olá boa noite

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

Funcionou tudo certinho?

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.

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!!

1 curtida

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.

1 curtida

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

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…

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

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