JAVA实现人脸识别,活体检测之百度API

版权声明:本文为博主原创文章,转载请附上原文链接,谢谢! https://blog.csdn.net/qq_21454973/article/details/80617889

-----------------------8/16更新---------------------------

有人问源码:

链接:https://pan.baidu.com/s/1WP37IBacu6VZwtNOUDbSYg 密码:vdzm

在这

--------------------------------------------------

吃水不忘挖井人,挖井人博客在此:挖井人一挖井人二

然后是官方的使用说明文档:地址

以上,感谢。

首先引入jar:

maven:

    <dependency>
        <groupId>com.baidu.aip</groupId>
        <artifactId>java-sdk</artifactId>
        <version>4.3.2</version>
    </dependency>

然后获取所需的AppID、APIKey、SecretKey:

进入百度云,创建应用:

创建完成之后可看见如下:

获取AppID、APIKey、SecretKey后,导入一下代码:

public class FaceSpot {
	private static final String AppID = "";
	private static final String APIKey = "";
	private static final String SecretKey = "";

	static AipFace client = null;
	static {
		client = new AipFace(AppID, APIKey, SecretKey);
		// 可选:设置网络连接参数
		client.setConnectionTimeoutInMillis(2000);
		client.setSocketTimeoutInMillis(60000);
	}

	public static void main(String[] args) throws IOException {
		 String filePath = "F:/3.jpg";
		 byte[] imgData = FileToByte(new File(filePath));
		 
		 System.out.println(detectFace(imgData,"1"));
//		String filePath1 = "F:/3.jpg";
//		String filePath2 = "F:/7.jpg";
//		byte[] imgData1 = FileUtil.readFileByBytes(filePath1);
//		byte[] imgData2 = FileUtil.readFileByBytes(filePath2);
//		System.out.println(faceverify(imgData1));
	}

	/**
	 * 人脸检测
	 * 
	 * @return
	 * @throws IOException
	 */
	public static String detectFace(File file, String max_face_num) {
		try {
			return detectFace(FileToByte(file), max_face_num);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 人脸检测
	 * 
	 * @return
	 * @throws IOException
	 */
	public static String detectFace(byte[] arg0, String max_face_num) {
		try {

			HashMap<String, String> options = new HashMap<String, String>();
			options.put("face_field", "age,beauty,expression,faceshape,gender,glasses,race,qualities");
			options.put("max_face_num", "2");
			options.put("face_type", "LIVE");

			// 图片数据
			String imgStr = Base64Util.encode(arg0);
			String imageType = "BASE64";
			JSONObject res = client.detect(imgStr, imageType, options);
			System.out.println(res.toString(2));
			return res.toString();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
    /**
     * 人脸比对
     * @param file1
     * @param file2
     * @return
     */
	public static String matchFace(File file1, File file2) {
		try {
			return matchFace(FileToByte(file1), FileToByte(file2));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 人脸比对
	 * 
	 * @param arg0
	 *            人脸1
	 * @param arg1
	 *            人脸2
	 * @return
	 */
	public static String matchFace(byte[] arg0, byte[] arg1) {
		String imgStr1 = Base64Util.encode(arg0);
		String imgStr2 = Base64Util.encode(arg1);
		MatchRequest req1 = new MatchRequest(imgStr1, "BASE64");
		MatchRequest req2 = new MatchRequest(imgStr2, "BASE64");
		ArrayList<MatchRequest> requests = new ArrayList<MatchRequest>();
		requests.add(req1);
		requests.add(req2);
		JSONObject res = client.match(requests);
		return res.toString();
	}
    
	/**
	 * 人脸搜索
	 * @param file
	 * @param groupIdList
	 * @param userId
	 * @return
	 */
	public static String searchFace(File file, String groupIdList, String userId) {
		try {
			return searchFace(FileToByte(file), groupIdList, userId);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 人脸搜索
	 * 
	 * @param arg0
	 * @param groupIdList
	 * @return
	 */
	public static String searchFace(byte[] arg0, String groupIdList, String userId) {
		String imgStr = Base64Util.encode(arg0);
		String imageType = "BASE64";
		HashMap<String, String> options = new HashMap<String, String>();
		options.put("quality_control", "NORMAL");
		options.put("liveness_control", "LOW");
		if (userId != null) {
			options.put("user_id", userId);
		}
		options.put("max_user_num", "1");
		JSONObject res = client.search(imgStr, imageType, groupIdList, options);
		return res.toString(2);
	}
    /**
     * 增加用户
     * @param file
     * @param userInfo
     * @param userId
     * @param groupId
     * @return
     */
	public static String addUser(File file, String userInfo, String userId, String groupId) {
		try {
			return addUser(FileToByte(file), userInfo, userId, groupId);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 增加用户
	 * 
	 * @param arg0
	 * @param userInfo
	 * @param userId
	 * @param groupId
	 * @return
	 */
	public static String addUser(byte[] arg0, String userInfo, String userId, String groupId) {
		String imgStr = Base64Util.encode(arg0);
		String imageType = "BASE64";
		HashMap<String, String> options = new HashMap<String, String>();
		options.put("user_info", userInfo);
		options.put("quality_control", "NORMAL");
		options.put("liveness_control", "LOW");

		JSONObject res = client.addUser(imgStr, imageType, groupId, userId, options);
		return res.toString(2);
	}

	public static String updateUser(File file, String userInfo, String userId, String groupId) {
		try {
			return updateUser(FileToByte(file), userInfo, userId, groupId);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 更新用户
	 * 
	 * @param arg0
	 * @param userInfo
	 * @param userId
	 * @param groupId
	 * @return
	 */
	public static String updateUser(byte[] arg0, String userInfo, String userId, String groupId) {
		String imgStr = Base64Util.encode(arg0);
		String imageType = "BASE64";
		HashMap<String, String> options = new HashMap<String, String>();
		if (userInfo != null) {
			options.put("user_info", userInfo);
		}
		options.put("quality_control", "NORMAL");
		options.put("liveness_control", "LOW");

		JSONObject res = client.updateUser(imgStr, imageType, groupId, userId, options);
		return res.toString(2);
	}
    /**
     * 删除用户人脸信息
     * @param userId
     * @param groupId
     * @param faceToken
     * @return
     */
	public static String deleteUserFace(String userId, String groupId, String faceToken) {
		HashMap<String, String> options = new HashMap<String, String>();
		// 人脸删除
		JSONObject res = client.faceDelete(userId, groupId, faceToken, options);
		return res.toString();
	}
    /**
     * 查询用户信息
     * @param userId
     * @param groupId
     * @return
     */
	public static String searchUserInfo(String userId, String groupId) {
		HashMap<String, String> options = new HashMap<String, String>();
		// 用户信息查询
		JSONObject res = client.getUser(userId, groupId, options);
		return res.toString(2);
	}
    /**
     * 获取用户人脸列表
     * @param userId
     * @param groupId
     * @return
     */
	public static String getUserFaceList(String userId, String groupId) {
		HashMap<String, String> options = new HashMap<String, String>();
		// 获取用户人脸列表
		JSONObject res = client.faceGetlist(userId, groupId, options);
		return res.toString(2);
	}
    /**
     * 获取一组用户
     * @param groupId
     * @param returnNum
     * @return
     */
	public static String getGroupUsers(String groupId, String returnNum) {
		HashMap<String, String> options = new HashMap<String, String>();
		options.put("start", "0");
		if (returnNum != null) {
			options.put("length", returnNum);
		}
		// 获取用户列表
		JSONObject res = client.getGroupUsers(groupId, options);
		return res.toString(2);
	}
    /**
     * 组用户复制
     * @param userId
     * @param srcGroupId
     * @param dstGroupId
     * @return
     */
	public static String userCopy(String userId, String srcGroupId, String dstGroupId) {
		HashMap<String, String> options = new HashMap<String, String>();
		options.put("src_group_id", srcGroupId);
		options.put("dst_group_id", dstGroupId);
		// 复制用户
		JSONObject res = client.userCopy(userId, options);
		return res.toString(2);
	}
    /**
     * 删除用户
     * @param userId
     * @param groupId
     * @return
     */
	public static String deleteUser(String userId, String groupId) {
		HashMap<String, String> options = new HashMap<String, String>();
		// 人脸删除
		JSONObject res = client.deleteUser(groupId, userId, options);
		return res.toString();
	}
    /**
     * 增加组信息
     * @param groupId
     * @return
     */
	public static String addGroup(String groupId) {
		HashMap<String, String> options = new HashMap<String, String>();
		// 创建用户组
		JSONObject res = client.groupAdd(groupId, options);
		return res.toString();
	}
    /**
     * 删除
     * @param groupId
     * @return
     */
	public static String deleteGroup(String groupId) {
		HashMap<String, String> options = new HashMap<String, String>();
		// 创建用户组
		JSONObject res = client.groupDelete(groupId, options);
		return res.toString();
	}
    /**
     * 获取组列表
     * @param length
     * @return
     */
	public static String getGroupList(String length) {
		HashMap<String, String> options = new HashMap<String, String>();
		options.put("start", "0");
		options.put("length", length);
		// 组列表查询
		JSONObject res = client.getGroupList(options);
		return res.toString();
	}
	/**
	 * 活体检测
	 * @param arg0
	 * @return
	 */
	public static String faceverify(byte[] arg0){
		String imgStr = Base64Util.encode(arg0);
        String imageType = "BASE64";
        FaceVerifyRequest req = new FaceVerifyRequest(imgStr, imageType);
        ArrayList<FaceVerifyRequest> list = new ArrayList<FaceVerifyRequest>();
        list.add(req);
        JSONObject res = client.faceverify(list);
        return res.toString();
	}

	private static byte[] FileToByte(File file) throws IOException {
		// 将数据转为流
		InputStream content = new FileInputStream(file);
		ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
		byte[] buff = new byte[100];
		int rc = 0;
		while ((rc = content.read(buff, 0, 100)) > 0) {
			swapStream.write(buff, 0, rc);
		}
		// 获得二进制数组
		return swapStream.toByteArray();
	}

}

填入自己的AppID, APIKey, SecretKey;

函数的参数可自行根据官方文档自己改一改,文件读取那边提供一下小帅的FileUtil并且处理好了异常:

public class FileUtil {

    /**
     * 根据文件路径读取byte[] 数组
     */
    public static byte[] readFileByBytes(String filePath) throws IOException {
        File file = new File(filePath);
        if (!file.exists()) {
            throw new FileNotFoundException(filePath);
        } else {
            ByteArrayOutputStream bos = new ByteArrayOutputStream((int) file.length());
            BufferedInputStream in = null;

            try {
                in = new BufferedInputStream(new FileInputStream(file));
                short bufSize = 1024;
                byte[] buffer = new byte[bufSize];
                int len1;
                while (-1 != (len1 = in.read(buffer, 0, bufSize))) {
                    bos.write(buffer, 0, len1);
                }

                byte[] var7 = bos.toByteArray();
                return var7;
            } finally {
                try {
                    if (in != null) {
                        in.close();
                    }
                } catch (IOException var14) {
                    var14.printStackTrace();
                }

                bos.close();
            }
        }
    }
}

然后就是测试啦,测试的话,随便百度了一张美女的照片,然后看返回:

{
  "timestamp": 1528422299,
  "result": {
    "face_list": [{
      "expression": {
        "probability": 0.9997190833,
        "type": "smile"
      },
      "face_probability": 1,
      "glasses": {
        "probability": 0.9999995232,
        "type": "none"
      },
      "location": {
        "height": 102,
        "rotation": -2,
        "width": 109,
        "left": 102.9398575,
        "top": 56.39219284
      },
      "age": 19,
      "gender": {
        "probability": 0.9999992847,
        "type": "female"
      },
      "face_shape": {
        "probability": 0.7517765164,
        "type": "heart"
      },
      "face_token": "706eaee3240ef0cc679ab209b1b71e0d",
      "beauty": 69.47167206,
      "race": {
        "probability": 0.9999864101,
        "type": "yellow"
      },
      "angle": {
        "yaw": -2.858289719,
        "roll": -2.302281618,
        "pitch": 9.867022514
      }
    }],
    "face_num": 1
  },
  "cached": 0,
  "error_code": 0,
  "log_id": 3671200838,
  "error_msg": "SUCCESS"
}

嗯,确实是美女,

"beauty": 69.47167206

好,然后通过浏览器开启摄像头来实时的试下,先上效果图:

好,大家不用在意这些细节,比如颜值啥的。。

我觉得颜值这项可能是假的,因为我做搞怪的表情时分数反而高一些??????????

上代码吧。。

首先是Controller:

@Controller
@RequestMapping(value = "/faceRecognition")
public class faceRecognitionController {

	 /**
	 * 人脸检测测试页面
	 * @return
	 * @throws Exception  
	 */
    @RequestMapping(value = "/test.do")
    public ModelAndView queryVoi() throws Exception {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("/artificialIntelligence/faceRecognition/test");
        return modelAndView;
    }
	
    /**
   	 * 请求人脸检测
   	 * @return
   	 * @throws Exception  
   	 */
	@RequestMapping(value = "/save.do")
	@ResponseBody
	public Map<String, Object> queryService(@RequestParam("the_file") MultipartFile file) {
		Map<String, Object> modelMap = new HashMap<String, Object>();
		try {
			//将数据转为流
			InputStream content = file.getInputStream();
			ByteArrayOutputStream swapStream = new ByteArrayOutputStream();  
	        byte[] buff = new byte[100];  
	        int rc = 0;  
	        while ((rc = content.read(buff, 0, 100)) > 0) {  
	            swapStream.write(buff, 0, rc);  
	        }  
	        //获得二进制数组
	        byte[] in2b = swapStream.toByteArray(); 
	        //调用人脸检测的方法
	        String  str = FaceSpot.detectFace(in2b,""+1);
	        JSONObject job = new JSONObject(FaceSpot.faceverify(in2b));
			 System.out.println(job.toString());
			 JSONObject testData = job.getJSONObject("result");
			 //System.out.println(testData.get("face_liveness"));
	        
	        JSON json = JSON.parseObject(str);
            FaceV3DetectBean bean = JSON.toJavaObject(json, FaceV3DetectBean.class);
            JSONArray arr = new JSONArray();
            
	     	 for(int i=0;i<bean.getResult().getFace_list().size();i++){
			        JSONObject jsonObject = new JSONObject();
			    	//获取年龄
			        int ageOne = bean.getResult().getFace_list().get(i).getAge();
			     	//处理年龄
			        String age =String.valueOf(new BigDecimal(ageOne).setScale(0, BigDecimal.ROUND_HALF_UP));
			        jsonObject.put("age", age);
					
					//获取美丑打分
			        Double beautyOne = (Double) bean.getResult().getFace_list().get(i).getBeauty();
					//处理美丑打分
			     	String beauty =String.valueOf(new BigDecimal(beautyOne).setScale(0, BigDecimal.ROUND_HALF_UP));
			     	jsonObject.put("beauty", beauty);
					
					//获取性别  male(男)、female(女)
					String gender = (String) bean.getResult().getFace_list().get(i).getGender().getType();
					jsonObject.put("gender", gender);
					
					//获取是否带眼睛 0-无眼镜,1-普通眼镜,2-墨镜
					String glasses =  bean.getResult().getFace_list().get(i).getGlasses().getType();
					jsonObject.put("glasses", String.valueOf(glasses));
					
					//获取是否微笑,0,不笑;1,微笑;2,大笑
					String expression =  bean.getResult().getFace_list().get(i).getExpression().getType();
					jsonObject.put("expression", String.valueOf(expression));
					arr.put(jsonObject);
			 }
			modelMap.put("strjson", arr.toString());
			modelMap.put("face_liveness", testData.get("face_liveness"));
			modelMap.put("success", true);
		} catch (Exception e) {
			e.printStackTrace();
			modelMap.put("success", false);
			modelMap.put("data", e.getMessage());
		}
		return modelMap;
	}
	
	
}

用的是fastjson,自行加jar包。

然后是jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">	
<title>人脸检测</title>
<script src="js/jquery-2.1.1.js" type="text/javascript" charset="utf-8"></script>
<script>

	//判断浏览器是否支持HTML5 Canvas
	window.onload = function () {
		try {
		//动态创建一个canvas元 ,并获取他2Dcontext。如果出现异常则表示不支持 document.createElement("canvas").getContext("2d");
		 document.getElementById("support").innerHTML = "浏览器支持HTML5 CANVAS";
		}
		catch (e) {
		 document.getElementByIdx("support").innerHTML = "浏览器不支持HTML5 CANVAS";
		}
	};
	
	//这段代 主要是获取摄像头的视频流并显示在Video 签中
	window.addEventListener("DOMContentLoaded", function () {
		var canvas = document.getElementById("canvas"),
		context = canvas.getContext("2d"),
		video = document.getElementById("video"),
		videoObj = { "video": true },
		errBack = function (error) {
			console.log("Video capture error: ", error.code);
		};
		//拍照按钮
// 		$("#snap").click(function () {
// 			context.drawImage(video, 0, 0, 330, 250);
// 			})
		//拍照每秒一次
		setInterval(function(){
			context.drawImage(video, 0, 0, 330, 250)
			CatchCode();
		},1000);
		//navigator.getUserMedia这个写法在Opera中好像是navigator.getUserMedianow
		//更新兼容火狐浏览器
		if (navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia) {
			    navigator.getUserMedia=navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
			    navigator.getUserMedia(videoObj, function (stream) {
				video.srcObject  = stream;
				video.play();
				}, errBack);
		}
	
	}, false);
	
	function dataURItoBlob(base64Data) {
		var byteString;
		if (base64Data.split(',')[0].indexOf('base64') >= 0)
		byteString = atob(base64Data.split(',')[1]);
		else
		byteString = unescape(base64Data.split(',')[1]);
		var mimeString = base64Data.split(',')[0].split(':')[1].split(';')[0];
		var ia = new Uint8Array(byteString.length);
		for (var i = 0; i < byteString.length; i++) {
		ia[i] = byteString.charCodeAt(i);
		}
		return new Blob([ia], {type:mimeString});
	}
	
	//上传服务器
	function CatchCode() {
		var canvans = document.getElementById("canvas");
		//获取浏览器页面的画布对象
		//以下开始编 数据
		var imageBase64 = canvans.toDataURL();
		var blob = dataURItoBlob(imageBase64);  // 上一步中的函数
		var fd = new FormData(document.forms[0]);
		fd.append("the_file", blob, 'image.png');
		//将图像转换为base64数据
		$.ajax({
	   		type:"POST",
	   		url:"faceRecognition/save.do",
	   		processData: false,     // 必须
	      	contentType: false,     // 必须
	      	data:fd,
	    	datatype: "json",
	   		success:function(data){
		   		var mes = eval(data);
		   		//alert(mes.success);
		   		//var jsonObj =   $.parseJSON(mes.strjson); 
		   		//alert(jsonObj[0].age);
		   		if (mes.success) {
 		   			//alert(mes.strjson);
		   			var jsonObj =  $.parseJSON(mes.strjson); 
		   			//alert(jsonObj);
		   			var age = jsonObj[0].age;
 		   			
		   			var beauty = jsonObj[0].beauty;
		   			var gendergender = jsonObj[0].gender;
		   			var glasses = jsonObj[0].glasses;
		   			var expression = jsonObj[0].expression
		   			
		   			$("#age").html(age);
		   			$("#beauty").html(beauty);
		   			$("#faceverify").html(mes.face_liveness);
		   			
		   			if(gendergender == 'male'){
		   				$("#gendergender").html("男");
		   			}else{
		   				$("#gendergender").html("女");
		   			}
		   			
		   			if(glasses == 'none'){
		   				$("#glasses").html("未戴眼镜");
		   			}else if(glasses == 'common'){
		   				$("#glasses").html("戴了普通眼镜");
		   			}else{
		   				$("#glasses").html("戴了墨镜");
		   			}
					
		   			if(expression == 'none'){
		   				$("#expression").html("不笑");
		   			}else if(expression == 'smile'){
		   				$("#expression").html("微笑");
		   			}else{
		   				$("#expression").html("大笑");
		   			}
		   		}
	   		},
	   		error: function(){
	    		//请求出错处理
	    		alert("出情况了");
	    		}         
	  		});
	}
</script>
<style> 
.div-a{ float:left;width:60%;height:60%;border:1px solid #F00} 
.div-b{ float:left;width:39%;height:60%;border:1px solid #000} 
span{ font-size:25px }
</style> 
</head> 
<body> 
	<!-- 左边区域 -->
	<div class="div-a" id="contentHolder">
			<video id="video" width="100%" height="60%" autoplay></video>
			<canvas style="" hidden="hidden"  id="canvas" width="520" height="250"></canvas>
	</div> 
	<!-- 右边区域 -->
	<div class="div-b" >
			<!-- 测试按钮 -->
<!-- 		<input type="button" id="snap" style="width:100px;height:35px;" value="拍 照" /> -->
<!-- 		<input type="button" onclick="CatchCode();" style="width:100px;height:35px;" value="上传服务器" /> -->
		
		<h1>人脸检测实时数据</h1>
		<span>年龄:</span><span id="age"></span><br/>
		<span>颜值:</span><span id="beauty" ></span><br/>
		<span>性别:</span><span id="gendergender"></span><br/>
		<span>是否戴眼镜:</span><span id="glasses"></span><br/>
		<span>表情:</span><span id="expression"></span><br/>
		<span>活体分数:</span><span id="faceverify"></span><br/>
	</div> 
		
	</body>
</html>

这个貌似只支持火狐??我用其他浏览器摄像头并未开启,有哪位大神知道代码还请告诉在下,谢谢指教。

这边有个活体指数,我测试了下,貌似还挺准,我首先百度了一张胡歌的照片放在摄像头上,emmmm.....颜值80,但是活体指数就很低,然后本人上,活体指数一直在0.95之上浮动,还是可靠的。

好,告辞!

猜你喜欢

转载自blog.csdn.net/qq_21454973/article/details/80617889