package test;
import org.opencv.core.*;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import org.opencv.videoio.VideoCapture;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class t1 {
private static final Logger log= (Logger) LoggerFactory.getLogger(FaceVideoTest.class);
private static int startFrom = 0;
private static int sample=0;
private static String id="";
public static long startTime;
private static final String endImgUrl = "D:\\ImgageLocal";
//下面的三行是openCV的安装路径 以及配置文件的位置
private static final String faceDetectorXML2URL ="D:\\opencv\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml";
private static final String eyeDetectorXML2URL= "D:\\opencv\\opencv\\sources\\data\\haarcascades\\haarcascade_eye.xml";
/*
直方图大小,越大精度越高,运行越慢
*/
private static int Matching_Accuracy=100000;
/*
初始化人脸探测器
*/
private static CascadeClassifier faceDetector;
/*
初始化人眼探测器
*/
private static CascadeClassifier eyeDetector;
private static int i=0;
/*
初始化分类器
*/
static {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
faceDetector=new CascadeClassifier(faceDetectorXML2URL);
eyeDetector=new CascadeClassifier(eyeDetectorXML2URL);
}
public static void main(String[] args)
{
log.info("开始人脸匹配");
long begin=System.currentTimeMillis();
//从摄像头实时人脸识别,识别成功保存图片到本地
try{
//从摄像头获取图片,比较本地图片,进行人脸识别
//getVideoFromCamera(endImgUrl+"2.png");
//人眼识别
// getVideoFromCamera(true);
//人脸识别
// getVideoFromCamera(false);
//搜集人脸图片
CollectImageData("2");
//仅用于强制抛异常,从而关闭GUI界面
Thread.sleep(1000);
int err=1/0;
} catch (Exception e) {
log.info("开始强制关闭"+e.getMessage());
log.info("人脸匹配结束,总耗时:{}ms",(System.currentTimeMillis()-begin));
System.exit(0);
}
}
//搜集需要的人脸,并设置工号
private static void CollectImageData(String id)
{
VideoCapture capture=new VideoCapture(0);
Mat video=new Mat();
int index=0;
if(capture.isOpened()){
while(true){
//匹配成功3次退出
capture.read(video);
detectAndCollect(video,faceDetector,id);
HighGui.imshow("实时人脸识别",video);
index=HighGui.waitKey(100);
if(index==27){
break;
}
}
}else{
log.info("摄像头未开启");
}
HighGui.destroyAllWindows();
capture.release();
return;
}
//采集人脸并保存到本地
private static void detectAndCollect(Mat frame, CascadeClassifier faceCascade, String id)
{
MatOfRect faces=new MatOfRect();
Mat grayFrame=new Mat();
Imgproc.cvtColor(frame,grayFrame,Imgproc.COLOR_BGR2GRAY);
faceCascade.detectMultiScale(grayFrame,faces);
Rect[] facesArray=faces.toArray();
//连续采集50张照片
if(facesArray.length>=1){
if ((sample==0 && System.currentTimeMillis()-startTime>10000 || (sample>0 && sample<50 && System.currentTimeMillis()-startTime>300))){
startTime=System.currentTimeMillis();
sample++;
System.out.println("image:"+sample);
Imgcodecs.imwrite(endImgUrl+"\\face"+"/img."+id+"."+(startFrom+sample)+".jpg",frame.submat(facesArray[0]));
}
}
for (int i=0;i<facesArray.length;i++){
Imgproc.rectangle(frame,facesArray[i].tl(),facesArray[i].br(),new Scalar(0,255,0),2);
}
}
//人脸识别,人眼识别
private static void getVideoFromCamera(boolean iseyes)
{
//如果要从摄像头获取视频,则要在VideoCapture的构造方法颉0
VideoCapture capture=new VideoCapture(0);
Mat video=new Mat();
int index=0;
if(capture.isOpened()){
while (true){
//从摄像头取出图片
capture.read(video);
if(iseyes){
MatOfRect eyeDeteCtions=new MatOfRect();
eyeDetector.detectMultiScale(video,eyeDeteCtions);
for (Rect re:eyeDeteCtions.toArray()){
Imgproc.rectangle(video,new Point(re.x,re.y),new Point(re.x+re.width,re.y+re.height),new Scalar(255,0,0));
}
HighGui.imshow("实时人眼识别",video);
}else {
MatOfRect faceDetections=new MatOfRect();
faceDetector.detectMultiScale(video,faceDetections);
//rect中人脸的范围
Mat face=null;
for(Rect rect : faceDetections.toArray()){
Imgproc.rectangle(video,rect,new Scalar(0,0,255),2);
}
HighGui.imshow("实时人脸识别",video);
}
index= HighGui.waitKey(100);
if(index==27){
break;
}
}
}else{
log.info("摄像头未开启");
}
HighGui.destroyAllWindows();
capture.release();
return;
}
}
第二个程序会识别采集人脸的可信度
package test;
import org.opencv.core.*;
import org.opencv.face.LBPHFaceRecognizer;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import org.opencv.videoio.VideoCapture;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class t2 {
private static final Logger Log= (Logger) LoggerFactory.getLogger(TrainImageCV.class);
//opencv的人脸识别xml文件路径
private static final String faceDetectorXML2URL ="D:\\opencv\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml";
private static final String eyeDetectorXML2URL= "D:\\opencv\\opencv\\sources\\data\\haarcascades\\haarcascade_eye.xml";
static{
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
public static void main(String[] args)throws IOException {
long begin = System.currentTimeMillis();
try{
System.out.println("Welcom to OpenCV" +Core.VERSION);
train("D:\\ImgageLocal\\face","D:/ImgageLocal/model");
Label("D:\\ImgageLocal\\test","D:/ImgageLocal/model");
getVideoFromCamera("D:/ImgageLocal/model");
Thread.sleep(1000);
// int err=1/0;
} catch (Exception e) {
e.printStackTrace();
}
Log.info("开始强制关闭");
Log.info("人脸匹配结束,总耗时:{}ms",(System.currentTimeMillis()-begin));
System.exit(0);
}
//识别摄像头里的人脸标签,并显示
private static void getVideoFromCamera(String saveFolder)
{
LBPHFaceRecognizer faceRecognizer=LBPHFaceRecognizer.create();
faceRecognizer.read(saveFolder+"/face_model.yml");
CascadeClassifier faceCascade=new CascadeClassifier();
faceCascade.load(faceDetectorXML2URL);
//从摄像头获取视频,则要在VideoCapture的构造方法写0
VideoCapture capture=new VideoCapture(0);
//初始化要处理的OpenCV图片
Mat video=new Mat();
int index=0;
if (capture.isOpened()){
while(true){
//从摄像头取出图片
capture.read(video);
//探测人脸
MatOfRect faceDetections=new MatOfRect();
faceCascade.detectMultiScale(video,faceDetections);
Mat grayFrame=new Mat();
//图像灰度化
Imgproc.cvtColor(video,grayFrame,Imgproc.COLOR_BGR2GRAY);
Imgproc.equalizeHist(grayFrame,grayFrame);
//rect中人脸图片的范围
Mat face=null;
int i=0;
for (Rect rect : faceDetections.toArray()) {
int[ ] label = new int[1];
double[ ] confidence =new double[1];
//根据模型预测人脸识别结果
faceRecognizer.predict(grayFrame. submat(rect),label,confidence);
String name = faceRecognizer.getLabelInfo( label[0]);
Scalar color;
if ( confidence[0] < 70) {
color = new Scalar( 153,204,51);
name = name + " " + new DecimalFormat( "#.0").format(confidence[0]);
}else {
name="face";
color=new Scalar(0,0,255);
}
//识别结果打标签
Imgproc.rectangle(video,rect.tl(),rect.br(),color,2);
setLabel(video,name,rect.tl(),color);
}
HighGui.imshow("实时人脸识别",video);
//窗口延迟等待100ms,返回按退出键
index=HighGui.waitKey(100);
//
if (index==27){
HighGui.destroyAllWindows();
capture.release();
break;
}
}
}else {
Log.info("摄像头未开启");
}
return;
}
//打标签
private static void Label(String testFolder, String saveFolder)throws IOException
{
LBPHFaceRecognizer faceRecognizer=LBPHFaceRecognizer.create();
// LBPHFaceRecognizer faceRecognizer=LBPHFaceRecognizer.create();
faceRecognizer.read(saveFolder+"/face_model.yml");
//读取文件于数组中
File[] files =new File(testFolder).listFiles();
CascadeClassifier faceCascade=new CascadeClassifier();
//opencv的模型
faceCascade.load(faceDetectorXML2URL);
for (int index=0;index<files.length;index++){
MatOfRect faces=new MatOfRect();
Mat grayFrame=new Mat();
Mat mat=Imgcodecs.imread(files[index].getCanonicalPath());
Mat gray=new Mat();
//图片预处理
Imgproc.cvtColor(mat,grayFrame,Imgproc.COLOR_BGR2GRAY);
Imgproc.equalizeHist(grayFrame,grayFrame);
//detect faces
faceCascade.detectMultiScale(grayFrame,faces);
Imgproc.equalizeHist(grayFrame,grayFrame);
Rect[] facesArray=faces.toArray();
System.out.println("facesaArray.length======="+facesArray.length);
for (int i=0;i<facesArray.length;i++){
int[] label=new int[1];
double[ ] confidence = new double[1];
faceRecognizer.predict(grayFrame.submat(facesArray[i]),label,confidence);
String name = faceRecognizer.getLabelInfo(label[0]);
System.out.print("测试图片: " + files[index].getCanonicalPath());
System.out.print( ",标签( label) : "+label[0]);
System.out.println( ",置信度(confidence) : " + confidence[0]);
System.out.println( ",name: "+name ) ;
Scalar color;
if(confidence[0]<70){
if (label[0]==0){
color=new Scalar(255,0,0);
}else if (label[0]==1){
color=new Scalar(153,204,51);
}else{
color=new Scalar(0,255,255);
}
name=name+" "+new DecimalFormat("#.0").format(confidence[0]);
}else{
name="face";
color=new Scalar(0,0,255);
}
Imgproc.rectangle(mat,facesArray[i].tl(),facesArray[i].br(),color,2);
setLabel(mat,name,facesArray[i].tl(),color);
Imgcodecs.imwrite(testFolder+"\\"+files[index].getName()+".jpg",mat);
}
}
}
/*
显示识别的人脸标签
*/
private static void setLabel(Mat im, String label, Point or, Scalar color)
{
int fontface=Imgproc.FONT_HERSHEY_SIMPLEX;
double scale=0.8;
int thickness=2;
int[] baseline=new int[1];
Size text = Imgproc.getTextSize(label,fontface,scale,thickness, baseline);
Imgproc.rectangle(im,new Point(or.x, or.y),new Point(or.x + text.width,or.y-text.height-baseline[0]-baseline[0]), color,Core.FILLED);
if (!label.equals("face")){
String[] sp=label.split(" ");
Map<String,Object> map=new HashMap<String,Object>();
}
Imgproc.putText(im,label,new Point(or.x,or.y-baseline[0]),fontface,scale,new Scalar(255,255,255),thickness);
}
/*
*训练模型的方法,传入人脸图片所在的文件夹路径,
* *和模型输出的路径训练结束后模型文件会在模型输出路径里边
*/
private static void train(String imageFolder, String saveFolder) throws IOException
{
LBPHFaceRecognizer faceRecognizer=LBPHFaceRecognizer.create();
CascadeClassifier faceCascade=new CascadeClassifier();
//opencv模型
faceCascade.load(faceDetectorXML2URL);
//读取文件于数组中
File[] files =new File(imageFolder).listFiles();
Map<String,Integer> nameMapId=new HashMap<String,Integer>(10);
//图片集合
List<Mat> images=new ArrayList<Mat>(files.length);
//名称集合
List<String> names=new ArrayList<String>(files.length);
List<Integer> ids=new ArrayList<Integer>(files.length);
for(int index=0;index<files.length;index++){
//解析文件名获取名称
File file = files [index];
String name = file.getName( ).split("\\.")[1];
Integer id = nameMapId.get(name);
if (id==null){
id=names.size();
names.add(name);
nameMapId.put(name,id);
faceRecognizer.setLabelInfo(id,name);
}
Mat mat= Imgcodecs.imread(file.getCanonicalPath());
Mat gray=new Mat();
Imgproc.cvtColor(mat,gray,Imgproc.COLOR_BGR2GRAY);
images.add(gray);
System.out.println("add total"+ images.size());
ids.add(id);
}
int[] idsInt=new int[ids.size()];
for (int i=0;i<idsInt.length;i++){
idsInt[i]=ids.get(i).intValue();
}
//显示标签
MatOfInt labels=new MatOfInt(idsInt);
//调用训练方法
faceRecognizer.train(images,labels);
//输出持久化模型文件。训练一次后就可以一直调用
faceRecognizer.save(saveFolder+"/face_model.yml");
}
}
简单的人脸识别程序结束