Java源码示例:org.opencv.face.BasicFaceRecognizer
示例1
public static boolean updateTrainModel() {
List<Mat> matLists = new ArrayList<Mat>(); // 待训练的人脸图片集合
List<Integer> lableLists = new ArrayList<Integer>(); // 人脸图片对应的标签
String CSVFilePath = "E:\\classchecks\\Test\\2017417\\train\\at.txt";
CSVFileUtils.CSVRead(CSVFilePath, matLists, lableLists);
// opencv 在训练人脸模型时需要确保人脸与标签一一对应
if(matLists.size() == lableLists.size()) {
Mat labels = new Mat(lableLists.size(), 1, CvType.CV_32SC1, new Scalar(0));
for(int i = 0; i < lableLists.size(); i ++) {
labels.put(i, 0, new int[]{lableLists.get(i)});
}
BasicFaceRecognizer faceRecognizer = load("E:\\classchecks\\test.xml");
faceRecognizer.update(matLists, labels);
}
return false;
}
示例2
/**
*
* @Title: reconstructFace
* @Description: 从输入的预处理图像在人脸模型中重构人脸
* @param model 包含预处理的人脸模型
* @param preprocessedFace 输入的预处理过的图像
* @return
* Mat
* @throws
*/
public static Mat reconstructFace(BasicFaceRecognizer model, Mat preprocessedFace){
try {
// 获取每个人脸的特征值
Mat eigenvectors = model.getEigenVectors();
// 获取平均人脸
Mat averageFaceRow = model.getMean();
int faceHeight = preprocessedFace.rows();
// subspaceProject将人脸图像投影到特征空间
Mat projection = subspaceProject(eigenvectors, averageFaceRow, preprocessedFace.reshape(1, 1));
// subspaceReconstruct从特征空间重构图像
Mat reconstructionRow = subspaceReconstruct(eigenvectors, averageFaceRow, projection);
Mat reconstructionMat = reconstructionRow.reshape(1, faceHeight);
Mat reconstructedFace = new Mat(reconstructionMat.size(), CvType.CV_8U);
reconstructionMat.convertTo(reconstructedFace, CvType.CV_8U, 1, 0);
return reconstructedFace;
} catch(CvException e) {
e.printStackTrace();
}
return null;
}
示例3
public static void recognition() {
String modelFilePath = "E:\\classchecks\\2017417\\train\\trainModel-20170418.xml";
BasicFaceRecognizer model = TrainFaces.load(modelFilePath);
Mat waitRecoMat = Imgcodecs.imread("E:\\classchecks\\2017417\\split\\14.jpg");
Mat preProc = PreProcessFace.rawProcessedFace(waitRecoMat);
//Imgproc.resize(preProc, preProc, new Size(92, 112));
Mat reconstructMat = Recognition.reconstructFace(model, preProc);
double similarity = Recognition.getSimilarity(preProc, reconstructMat);
System.out.println("similarity=" + similarity);
int pridictLabel = model.predict_label(preProc);
System.out.println("pridictLabel=" + pridictLabel);
}
示例4
/**
* 以CSV文件提供的人脸图片训练人脸模型并保存模型文件(以XML的形式)
* @param CSVFilePath csv文件存储的绝对路径
* @param trainModellSavePath 训练的模型文件的保存路径
*/
public static boolean trainAndSaveModel(String CSVFilePath, String trainModelSavePath, String facerecAlgorithm) {
if(!new File(CSVFilePath).isFile()) {
return false;
}
// 判断要保存的人脸模型文件是不是一个绝对路径名
File modelFile = new File(trainModelSavePath);
if(!modelFile.isAbsolute()) {
System.out.println("TrainFaces->trainAndSaveModel->trainModelSavePath不是一个绝对路径名");
return false;
}
// 如果trainModelSavePath的上一级文件夹不存在则创建
if(!modelFile.getParentFile().exists()) {
modelFile.getParentFile().mkdirs();
}
List<Mat> matLists = new ArrayList<Mat>(); // 待训练的人脸图片集合
List<Integer> lableLists = new ArrayList<Integer>(); // 人脸图片对应的标签
CSVFileUtils.CSVRead(CSVFilePath, matLists, lableLists);
// opencv 在训练人脸模型时需要确保人脸与标签一一对应
if(matLists.size() == lableLists.size()) {
Mat labels = new Mat(lableLists.size(), 1, CvType.CV_32SC1, new Scalar(0));
for(int i = 0; i < lableLists.size(); i ++) {
labels.put(i, 0, new int[]{lableLists.get(i)});
}
BasicFaceRecognizer faceRecognizer = null;
if("FaceRecognizer.Eigenfaces".equals(facerecAlgorithm)) {
faceRecognizer = Face.createEigenFaceRecognizer();
} else if("FaceRecognizer.Fisherfaces".equals(facerecAlgorithm)) {
faceRecognizer = Face.createFisherFaceRecognizer();
}
faceRecognizer.train(matLists, labels);
faceRecognizer.save(trainModelSavePath);
return true;
}
return false;
}
示例5
/**
* 加载训练的人脸模型并返回BasicFaceRecognizer模型对象
* @param modelFilePath
* @return
*/
public static BasicFaceRecognizer load(String modelFilePath) {
BasicFaceRecognizer model = Face.createEigenFaceRecognizer();
model.load(modelFilePath);
return model;
}
示例6
public static BasicFaceRecognizer learnCollectedFaces(List<Mat> preprocessedFaces, Mat faceLabels) {
BasicFaceRecognizer model = Face.createEigenFaceRecognizer();
model.train(preprocessedFaces, faceLabels);
return model;
}
示例7
@Override
public BasicEntityVo<?> clockin(String jwAccount, String loginAccount, Double lng, Double lat,
CommonsMultipartFile file) {
LOG.info("学生端考勤Service");
LOG.info("ContentType:" + file.getContentType()
+ " Filename:" + file.getOriginalFilename() + " Size:" + file.getSize());
LOG.info("学生上传经纬度:lng=" + lng + " lat:" + lat);
Integer teacherUId = clockinAsStudentMapper.getTeacherIDByStudentClock(jwAccount, 500);
LOG.info("教师UID:" + teacherUId);
SchoolCourseClockModel sccm = basicService.getSchoolCourseClockModelNow();
PointVo gpsPoint = clockinAsStudentMapper.getGPSByTeacherID(teacherUId, sccm);
LOG.info("教师最新考勤记录的GPS坐标:" + gpsPoint);
double stuDistanceTea = PositionUtil.distance(gpsPoint.getLng(), gpsPoint.getLat(), lng, lat);
LOG.info("学生与教师的距离:" + stuDistanceTea);
if(stuDistanceTea > 550) {
return new BasicEntityVo<>(StudentClockInBusinessCode.GPS_DISTANCE_GT_50[0], StudentClockInBusinessCode.GPS_DISTANCE_GT_50[1]);
}
Date date = new Date();
// "yyyy-MM-dd"字符串
String dtSimpleDate = DateUtil.dtSimpleFormat(date);
// "yyyyMMddHHmmss"日期字符串
String longTime = DateUtil.longDate(date);
// 保存文件路径的每个文件夹名称数组,教师上传的图片以每天的日期作为文件夹
String [] pathKey = {ImgStoragePath.STUDENT_CLOCK_IN_IMG_PATH, loginAccount, dtSimpleDate};
// 保存图片的文件夹路径
String dirSavePath = FileUtils.buildFilePath(pathKey);
boolean isSaved = fileSave(file, dirSavePath, longTime);
if(isSaved == false) { // 上传的图片保存失败
return new BasicEntityVo<>(StudentClockInBusinessCode.BUSSINESS_IMAGE_SAVE_FAILED[0], StudentClockInBusinessCode.BUSSINESS_IMAGE_SAVE_FAILED[1]);
}
String absolutePath = FileUtils.buildFilePath(dirSavePath, longTime+".jpg");
Mat imgSrc = Imgcodecs.imread(absolutePath, Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE); // 加载上传的图片
Mat procMat = PreProcessFace.smallProcessedFace(imgSrc);
if(null == procMat) {
return new BasicEntityVo<>(StudentClockInBusinessCode.BUSSINESS_NO_DETECT_FACE[0], StudentClockInBusinessCode.BUSSINESS_NO_DETECT_FACE[1]);
}
String collecteFaceRoute = FileUtils.buildFilePath(ImgStoragePath.PROC_FACE_IMG_SAVE_PATH, loginAccount);
List<Mat> collectedMats = new ArrayList<Mat>();
List<Integer> faceLabels = new ArrayList<Integer>();
CSVFileUtils.loadImage(collecteFaceRoute, collectedMats, faceLabels);
// 将人脸标签放入一个Mat对象,OpenCV提供的人脸识别算法中接收一个存有人脸标签的Mat
Mat labelsMat = new Mat(faceLabels.size(), 1, CvType.CV_32SC1, new Scalar(0));
for(int i = 0; i < faceLabels.size(); i ++) {
labelsMat.put(i, 0, new int[]{faceLabels.get(i)});
}
// 训练人脸模型,这里使用的是特征脸算法
BasicFaceRecognizer faceModel = Recognition.learnCollectedFaces(collectedMats, labelsMat);
Mat reconstructedFace = Recognition.reconstructFace(faceModel, procMat);
double similarity = Recognition.getSimilarity(reconstructedFace, procMat);
LOG.info("similarity = " + similarity);
LOG.info("predict_label: "+faceModel.predict_label(procMat));
if(similarity > 0.13) {
return new BasicEntityVo<>(StudentClockInBusinessCode.FACE_NON_EXISTENT[0],
StudentClockInBusinessCode.FACE_NON_EXISTENT[1]);
}
// 学生自己考勤成功后更新考勤记录
clockinAsStudentMapper.updateStudentClockinRecord(jwAccount);
StudentClockinVo vo = new StudentClockinVo();
vo.setStuName(clockinAsStudentMapper.findStudentName(jwAccount));
vo.setCurTime(DateUtil.hmsFormat(new Date()));
// TODO 更新考勤记录
return new BasicEntityVo<>(StudentClockInBusinessCode.BUSINESS_SUCCESS[0],
StudentClockInBusinessCode.BUSINESS_SUCCESS[1], vo);
}