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);
}