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、 将build\java\opencv-340.jar导入到项目中,
   2、 根据操作系统版本,将build\java\x64\opencv_java340.dll放在%JAVA_HONE%\bin下(这里只要放在System.getProperty("java.library.path")下目录即可)。
   3、 在代码中使用System.loadLibrary(Core.NATIVE_LIBRARY_NAME);加载。

在sources\data下都是模型文件,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
版权声明:本文为博主原创文章,转载请附上博文链接!

javacv 340使用 人脸检测例子【转载】的更多相关文章

  1. 2、转载一篇,浅析人脸检测之Haar分类器方法

    转载地址http://www.cnblogs.com/ello/archive/2012/04/28/2475419.html 浅析人脸检测之Haar分类器方法  [补充] 这是我时隔差不多两年后, ...

  2. caffe_实战之两个简单的例子(物体分类和人脸检测)

    一.物体分类: 这里使用的是caffe官网中自带的例子,我这里主要是对代码的解释~ 首先导入一些必要的库: import caffe import numpy as np import matplot ...

  3. 【转载】opencv实现人脸检测

    全文转载自CSDN的博客(不知道怎么将CSDN的博客转到博客园,应该没这功能吧,所以直接复制全文了),转载地址如下 http://blog.csdn.net/lsq2902101015/article ...

  4. 使用python实现人脸检测<转载>

    原文地址:https://www.cnblogs.com/vipstone/p/8884991.html =============================================== ...

  5. 基于Haar特征Adaboost人脸检测级联分类

    基于Haar特征Adaboost人脸检测级联分类 基于Haar特征Adaboost人脸检测级联分类,称haar分类器. 通过这个算法的名字,我们能够看到这个算法事实上包括了几个关键点:Haar特征.A ...

  6. Python 3 利用 Dlib 实现摄像头实时人脸检测和平铺显示

    1. 引言 在某些场景下,我们不仅需要进行实时人脸检测追踪,还要进行再加工:这里进行摄像头实时人脸检测,并对于实时检测的人脸进行初步提取: 单个/多个人脸检测,并依次在摄像头窗口,实时平铺显示检测到的 ...

  7. Python 3 利用 Dlib 19.7 进行人脸检测

    0. 引言 / Overview 介绍 Dlib 中基于 HOG,Histogram of Oriented Gradients / 方向梯度直方图 实现 Face Detect / 人脸检测 的两个 ...

  8. 利用html5、websocket和opencv实现人脸检测

    最近学习人脸识别相关的东西,在MFC下使用OpenCV做了一个简单的应用.训练需要较多的数据,windows应用程序终究还是不方便,于是想着做成CS模式:检测识别都放在服务器端,视频获取和显示都放在网 ...

  9. 基于Emgu CV的人脸检测代码

    这个提供的代码例子是Emgu CV提供的源码里面自带的例子,很好用,基本不需要改,代码做的是人脸检测不是人脸识别,这个要分清楚.再就是新版本的Emgu CV可能会遇到系统32位和64位处理方式有区别的 ...

随机推荐

  1. Windows各种各种消息投递函数

    1.SendMessage:发送消息给指定的窗口过程:直到窗口过程处理了消息才返回. 2.PostMessage:将消息放入消息队列(与指定窗口创建的线程相关)中:无需等待消息处理,立即返回.   不 ...

  2. customization arm ubuntu rootfs

    requirment: want to get arm ubuntu rootfs method: base on debootstrap tool, customization full funct ...

  3. jsonp 跨域1

    今天上课学到了jsonp,看了理解,还需要多敲,代码贴出来看看 <!doctype html> <html> <head> <meta charset=&qu ...

  4. Disabling the Windows 8 UAC

    http://www.computerperformance.co.uk/win8/windows8-uac-disable.htm https://msdn.microsoft.com/en-us/ ...

  5. C++内置类型的机器实现

    大多数计算机以2的整数次幂个比特作为块来处理内存,可寻址的最小内存块称为“字节(byte)”,存储的基本单元称为“字(word)”,它通常有几个字节组成. 计算机以比特序列存储数据,即01000101 ...

  6. ThreadPoolTaskExecutor多线程使用,及线程池配置

    1.配置 ThreadPoolTaskExecutor bean <?xml version="1.0" encoding="UTF-8"?> &l ...

  7. 福大软工1816 - 第八次作业(课堂实战)- 项目UML设计

    团队 学号 姓名 本次作业博客链接 031602428 苏路明(组长) https://www.cnblogs.com/Sulumer/p/9822854.html 031602401 陈瀚霖 htt ...

  8. mybatis之sql执行有数据但返回结果为null

    最近在使用mybatis查询数据库时,发现在pl/sql中单独执行sql时结果是有值的,但是在程序中拿到的却是null,相关配置如下: (1) <resultMap type="mon ...

  9. React 源码剖析系列 - 不可思议的 react diff

      简单点的重复利用已有的dom和其他REACT性能快的原理. key的作用和虚拟节点 目前,前端领域中 React 势头正盛,使用者众多却少有能够深入剖析内部实现机制和原理. 本系列文章希望通过剖析 ...

  10. 配置动态加载模块和js分模块打包,生产环境和开发环境公共常量配置

    1. 话不多少 先上代码:  route.js  // 引用模板 分模块编译 const main = r => require.ensure([], () => r(require('. ...