javacv 340使用 人臉檢測例子【轉載】

Java下使用opencv進行人臉檢測java

工做須要,研究下人臉識別,發現opencv比較經常使用,儘管能檢測人臉,但識別率不高,多數是用來獲取攝像頭的視頻流的,提取裏面的視頻幀,實現人臉識別時一般會和其餘框架搭配使用,好比face_recognition、SeetaFace Engine、Facenet。不過這裏先簡單介紹下opencv在java下的使用(網上大多都是C++的demo,這裏是使用其java接口,還提供了python的接口)。python

這裏簡單說下opencv(版本爲340)的安裝框架

    window下直接運行opencv-3.4.0-vc14_vc15.exe便可,java下用到的只有裏面的opencv-340.jar和opencv_java340.dll,官網下載或者直接下載java部分。
   一、 將build\java\opencv-340.jar導入到項目中,
   二、 根據操做系統版本,將build\java\x64\opencv_java340.dll放在%JAVA_HONE%\bin下(這裏只要放在System.getProperty("java.library.path")下目錄便可)。
   三、 在代碼中使用System.loadLibrary(Core.NATIVE_LIBRARY_NAME);加載。dom

在sources\data下都是模型文件,opencv使用這些xml建模(CascadeClassifier)分析人臉,這裏只用到haar下的正臉和人眼模型文件。ide

下面的demo修改自網上的例子,原爲單獨檢測人臉,發現會將只有鼻子的部分也識別爲人臉,因此修改成使用兩個CascadeClassifier同時檢測人臉和人眼,同時存在才確認爲人臉目標,提升準確率,不過識別的時間較原來的長。
Demoui

package opencv;this

import org.opencv.core.*;
import org.opencv.core.Point;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import org.opencv.videoio.VideoCapture;
import org.opencv.videoio.Videoio;操作系統

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Random;.net

public class MyDemo extends JPanel {
    private BufferedImage mImg;code

    /**
     * 轉換圖像
     * @param mat
     * @return
     */
    private BufferedImage mat2BI(Mat mat){
        int dataSize = mat.cols()*mat.rows()*(int)mat.elemSize();
        byte[] data = new byte[dataSize];
        mat.get(0, 0,data);

        int type = mat.channels()==1? BufferedImage.TYPE_BYTE_GRAY:BufferedImage.TYPE_3BYTE_BGR;
        if(type == BufferedImage.TYPE_3BYTE_BGR){
            for(int i=0;i<dataSize;i+=3){
                byte blue=data[i+0];
                data[i+0]=data[i+2];
                data[i+2]=blue;
            }
        }
        BufferedImage image=new BufferedImage(mat.cols(),mat.rows(),type);
        image.getRaster().setDataElements(0, 0, mat.cols(), mat.rows(), data);

        return image;
    }

    @Override
    public void paint(Graphics g){
        if(mImg!=null){
            g.drawImage(mImg, 0, 0, mImg.getWidth(),mImg.getHeight(),this);
        }
    }


    /**
     * opencv實現人臉識別,同時檢測到人臉和人眼時才截圖
     * @param img
     */
    public static Mat detectFace(Mat img) {

        System.out.println("Running DetectFace ... ");
        // 從配置文件lbpcascade_frontalface.xml中建立一我的臉識別器,該文件位於opencv安裝目錄中
        CascadeClassifier faceDetector = new CascadeClassifier("C:\\env\\opencv\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml");
        CascadeClassifier eyeDetector = new CascadeClassifier("C:\\env\\opencv\\opencv\\sources\\data\\haarcascades\\haarcascade_eye.xml");


        // 在圖片中檢測人臉
        MatOfRect faceDetections = new MatOfRect();
        faceDetector.detectMultiScale(img, faceDetections);

        //System.out.println(String.format("Detected %s faces", faceDetections.toArray().length));

        Rect[] rects = faceDetections.toArray();
        Random r = new Random();
        if(rects != null && rects.length >= 1){
            for (Rect rect : rects) {

                //畫矩形
                Imgproc.rectangle(img, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height),
                        new Scalar(0, 0, 255), 2);
//                Imgproc.circle(img, new Point(rect.x + rect.width, rect.y + rect.height), cvRound((rect.width + rect.height) * 0.25),
//                        new Scalar(0, 0, 255), 2);

                //識別人眼
                Mat faceROI = new Mat(img, rect );
                MatOfRect eyesDetections = new MatOfRect();
                eyeDetector.detectMultiScale( faceROI, eyesDetections);
                System.out.println("Running DetectEye ... "+ eyesDetections);

                if( eyesDetections.toArray().length > 1){
                    save(img, rect, "C:\\Users\\TR\\Desktop\\demo\\test\\"+r.nextInt(2000)+".jpg");
                }

            }
        }
        return img;
    }

    /**
     * opencv將人臉進行截圖並保存
     * @param img
     */
    private static void save(Mat img, Rect rect, String outFile){
        Mat sub = img.submat(rect);
        Mat mat = new Mat();
        Size size = new Size(300, 300);
        Imgproc.resize(sub, mat, size);
        Imgcodecs.imwrite(outFile, mat);
    }


    public static void main(String[] args) {
        try{
            //加載opencv庫
            System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

            //獲取攝像頭視頻流
            VideoCapture capture = new VideoCapture(0);
            int height = (int)capture.get(Videoio.CAP_PROP_FRAME_HEIGHT);
            int width = (int)capture.get(Videoio.CAP_PROP_FRAME_WIDTH);
            if(height == 0||width == 0){
                throw new Exception("camera not found!");
            }

            //使用Swing生成GUI
            JFrame frame = new JFrame("camera");
            frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
            MyDemo panel = new MyDemo();
            frame.setContentPane(panel);
            frame.setVisible(true);
            frame.setSize(width+frame.getInsets().left+frame.getInsets().right,
                    height+frame.getInsets().top+frame.getInsets().bottom);

            Mat capImg = new Mat();
            Mat temp=new Mat();
            //Random r = new Random();
            while(frame.isShowing()){
                //獲取視頻幀
                capture.read(capImg);
                //轉換爲灰度圖
                Imgproc.cvtColor(capImg, temp, Imgproc.COLOR_RGB2GRAY);
                //識別人臉
                Mat image = detectFace(capImg);
                //轉爲圖像顯示
                panel.mImg = panel.mat2BI(image);
                panel.repaint();
            }
            capture.release();
            frame.dispose();

        }catch(Exception e){
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            e.printStackTrace(pw);
            System.out.println(sw.toString());
        }
        finally{
            System.out.println("Exit");
        }

    }

相關文章
相關標籤/搜索