• javacv 340使用 人脸检测例子【转载】


    Java下使用opencv进行人脸检测

    工作需要,研究下人脸识别,发现opencv比较常用,尽管能检测人脸,但识别率不高,多数是用来获取摄像头的视频流的,提取里面的视频帧,实现人脸识别时通常会和其他框架搭配使用,比如face_recognition、SeetaFace Engine、Facenet。不过这里先简单介绍下opencv在java下的使用(网上大多都是C++的demo,这里是使用其java接口,还提供了python的接口)。

    这里简单说下opencv(版本为340)的安装

        window下直接运行opencv-3.4.0-vc14_vc15.exe即可,java下用到的只有里面的opencv-340.jar和opencv_java340.dll,官网下载或者直接下载java部分。
       1、 将buildjavaopencv-340.jar导入到项目中,
       2、 根据操作系统版本,将buildjavax64opencv_java340.dll放在%JAVA_HONE%in下(这里只要放在System.getProperty("java.library.path")下目录即可)。
       3、 在代码中使用System.loadLibrary(Core.NATIVE_LIBRARY_NAME);加载。

    在sourcesdata下都是模型文件,opencv使用这些xml建模(CascadeClassifier)分析人脸,这里只用到haar下的正脸和人眼模型文件。

    下面的demo修改自网上的例子,原为单独检测人脸,发现会将只有鼻子的部分也识别为人脸,所以修改为使用两个CascadeClassifier同时检测人脸和人眼,同时存在才确认为人脸目标,提高准确率,不过识别的时间较原来的长。
    Demo

    package opencv;

    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;

    public class MyDemo extends JPanel {
        private BufferedImage mImg;

        /**
         * 转换图像
         * @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");
            }

        }

    }
    ---------------------
    作者:Cceking
    来源:CSDN
    原文:https://blog.csdn.net/cceking/article/details/80868314
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    First duplicate value
    SQL学习笔记day1
    Find closest value in BST
    BST construction
    Closest sum_pair
    滑动窗口 sliding window
    设计模式(3)观察者模式
    设计模式(1)装饰模式总结
    深刻探讨public class=new class();
    与时间赛跑,我的2012
  • 原文地址:https://www.cnblogs.com/jerrybaby/p/10406952.html
Copyright © 2020-2023  润新知