百度人脸识别应用(四)

184 阅读2分钟

「这是我参与11月更文挑战的第 8 天,活动详情查看:2021最后一次更文挑战

1、前言

​ 在前几次的分享中,我们说到了人脸识别、人脸库管理、批量同步人脸数据这几个功能,本次我们介绍下人脸检测功能的使用。人脸检测主要是为了检测照片中是否存在真实的人脸,并获取一些人脸附加数据,那么接口返回的信息主要有:1)照片中人脸的位置信息;2)人脸的关键点信息(即人脸特征坐标)3)人脸的年龄、性别等信息;4)照片中的人脸是否存在遮挡、置信度等。那么下面就来详细介绍下,实际开发应用以及遇到的一些问题。

2、人脸检测

1、首先当用户进行人脸识别后,会上传一张人脸照片,我们会先把照片存入服务器临时文件夹,然后加入到当前任务队列中,消费者依次去调用人脸检测接口。然后我们再根据返回信息,决定用户能否正常建档。判断的依据主要有:1)人脸各部分遮挡的概率;2)人脸模糊程度;3)真实人脸置信度;下面我们就结合代码详细说明下:
人脸检测代码:
/**
	 * 百度API 人脸检测
	 * */
	public MessageModel imageDetect(String cert_id) {
		try {
			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			Date dayStart=new Date();    

			AipFace client = createClient();
			if (client == null) {
				messageModel.setErrorCode(messageModel.constErrorCode);
				messageModel.setErrMsg("创建人脸检测API失败");
				return messageModel;
			}
	    // 传入可选参数调用接口
	    HashMap<String, String> options = new HashMap<String, String>();
	    options.put("max_face_num", "10");
	    options.put("face_fields", "age,beauty,expression,gender,glasses,race,qualities");
	    
		 Properties properties = ResourceUtil.getResourceProperties();
		 // 参数为本地图片路径
         String path=properties.getProperty("common.photopath")+"temp/" + cert_id + ".jpg";
         JSONObject res = client.detect(path, options);
         getMillSecond(dayStart,end);
         messageModel= getDetectResult(res);
	    if (messageModel.constOKCode.equals(messageModel.getErrorCode())) {//验证通过  
	    	//把图片从临时文件夹已到正式文件夹并删除临时文件夹文件
	    	MessageModel msgModelMove =moveTotherFolders(cert_id);
	    	if (msgModelMove.constErrorCode.equals(msgModelMove.getErrorCode())) {
	    		RedisUtil.setStringEx("face_v_"+cert_id, RedisUtil.timeOutSeconds, msgModelMove.getErrMsg());
			}
	    	else {
		        RedisUtil.setStringEx("face_v_"+cert_id, RedisUtil.timeOutSeconds, "ok");
			}
			//将人脸信息加入到人脸库中 2021-10-13 10:29 
			MessageModel resMsg = faceDetectBaiDu.faceGroupComponent.addUser(cert_id, msgModelMove.getMsg());
			if (StringUtils.isNotBlank(resMsg.getErrorCode())) {
				//人脸注册失败 -> 将face_group_id重置为空
				Map<String, Object> paramMap = new HashMap<String, Object>(); 
		        paramMap.put("certId", cert_id);
		        paramMap.put("faceGroupId", StringUtils.EMPTY);
		        paramMap.put("faceUid", StringUtils.EMPTY);
		        paramMap.put("face_add_time", new Date());
				faceDetectBaiDu.faceGroupMapper.updatePhotoInfoFaceGroupId(paramMap);
				return resMsg;
			}
		}
	    else{//验证失败并删除临时文件夹文件
	    	RedisUtil.setStringEx("face_v_"+cert_id, RedisUtil.timeOutSeconds, messageModel.getErrMsg());
	    }
	    //从临时文件夹中删除图片
	 	File tempFile = new File(path);
    	  if (tempFile.exists()) {
				FileUtils.forceDelete(tempFile);
			}
	    System.out.println(res.toString(2));
		} catch (Exception e) {
			Log4jUtil.logError.error("人脸检测失败:"+e);
			 RedisUtil.setStringEx("face_v_"+cert_id, RedisUtil.timeOutSeconds, "人脸检测失败");
		}
	   return messageModel;
	}
消费线程:

	private static class MQQueueValidateRunnable implements Runnable {
		
		public void run() {
			while (true) {
                 try {
                	 
                		 Properties properties = ResourceUtil.getResourceProperties();
                		 String qpsServerName = properties.getProperty("face.qpsServerName");
                		 String threadCount = RedisUtil.getHashMap("qps_cert_num", qpsServerName);
                		 Log4jUtil.logInfo.info("qps_cert_num:"+threadCount);
                		 if (threadCount == null) {
                			 threadCount="1";
						}
                    	 if (threadPoolExecutor == null) {
                    		 threadPoolExecutor =new ThreadPoolExecutor(20, 20, 1, TimeUnit.DAYS, queue);
     					 }
                    	 for(int i=0;i<Integer.valueOf(threadCount);i++)
                    	 {
                    		 if (threadPoolExecutor.getActiveCount()<Integer.valueOf(threadCount)) { 
                    		   String certID = RedisUtil.blpopList(mq_cert_validate_list);
       						   SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
       						  //System.out.println(df.format(new Date())+"     "+certID);
       						   Log4jUtil.logInfo.info(df.format(new Date())+"   qpsServerName:  "+qpsServerName+"  threadCount:  "+threadCount+",  cert_id   "+certID);
       						   if (RedisUtil.errFlag.equals(certID)) {//出现异常错误
       							 continue;
       						   }
       						   if (certID != null) { 
       							 MQCertValidateRunnable poolRunnable = new MQCertValidateRunnable(certID.toLowerCase());
       							threadPoolExecutor.execute(poolRunnable);   
       						  }
							}
    						 
                    	 }
    					Thread.sleep(2100); 
				} catch (Exception e) { 
					Log4jUtil.logError.error("实现Runnable接口的类 身份证照验证队列执行错误:" + e); 
				}
				
			}
		}