javacv 人脸追踪_javacv 340使用 人脸检测例子【转载】

这篇博客介绍了如何在Java环境下使用OpenCV 3.4.0进行人脸和人眼的检测。通过CascadeClassifier加载模型文件,分别检测人脸和人眼,当两者同时存在时确认为人脸目标,从而提高识别准确性。文章包含详细的步骤,从安装OpenCV到编写Java代码实现视频流中的人脸检测,并展示了如何将识别到的人脸截图保存。
摘要由CSDN通过智能技术生成

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

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

版权声明:本文为博主原创文章,转载请附上博文链接!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值