百度人脸识别java html5

1、前端thymeleaf+h5

index.html    人脸识别+定位,用的百度sdk

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<link rel="shortcut icon" href="farvirate.ico" type="image/x-icon" />
<link type="text/css" rel="stylesheet" th:href="@{/static/html5/font-awesome-4.7.0/css/font-awesome.min.css}" />
<link type="text/css" rel="stylesheet" th:href="@{/static/html5/animate.min.css}" />
<link type="text/css" rel="stylesheet" th:href="@{/static/html5/home.css}" />
<link type="text/css" rel="stylesheet" th:href="@{/static/html5/swiper-3.4.2.min.css}" />
<script type="text/javascript" th:src="@{/static/easyui/jquery.min.js}"></script>
<script type="text/javascript" th:src="@{/static/layer-3.1.1/layer/layer.js}"></script>
<script type="text/javascript" th:src="@{/static/html5/swiper-3.4.2.jquery.min.js}"></script>
<script type="text/javascript" src="https://api.map.baidu.com/api?v=2.0&ak=C93b5178d7a8ebdb830b9b557abce78b"></script>
</head>
<body>
	<canvas width="620px" id="canvas" height="720px" style="display: none;"></canvas>
	<input id="reg_id" type="hidden" th:value="${reg_id}" />
	<div id="allmap" style="display:none;"></div>
	<div class="swiper-container swiper-no-swiping">
		<div class="swiper-wrapper">
			<div class="swiper-slide searchBox">
				<div class="search">
					<div class="sTop">
						<h2>
							<span>在线</span>报到
						</h2>
					</div>
					<i class="fa fa-search sIcon"></i>
					<!-- <input type="text" placeholder="请输入身份证号" /> -->
					<input id="idcard" name="idcard" type="text" placeholder="请输入身份证号" value="">
					<button id="next" onclick="nextSwiper(1);">
						<i class="fa fa-chevron-right"></i>
					</button>
				</div>
			</div>
			<div class="swiper-slide white">
				<div class="infor">
					<div class="header"></div>
					<div class="inforTop clearfix">
						<div class="userImg">
							<img id="admission_photo" th:src="@{/static/html5/images/djz.jpg}" />
						</div>
						<div class="userInfor">
							<h3>
								<i class="fa fa-vcard"></i><span id="name"></span><b id="gender"></b>
							</h3>
							<p class="clearfix">
								<label>学号</label><span id="student_id"></span>
							</p>
							<p>
								<label>专业</label><span id="major_name"></span>
							</p>
							<p>
								<label>班级</label><span id="class_name"></span>
							</p>
						</div>
					</div>
					<div class="inforCon basic">
						<h3>
							<span>基本信息</span>
						</h3>
						<table cellpadding="0" cellspacing="0" width="100%"
							class="inforTable">
							<tr>
								<td>出生日期</td>
								<td><span id="date_birth"></span></td>
								<td>籍贯</td>
								<td><span id="hometown"></span></td>
							</tr>
							<tr>
								<td>身份证号</td>
								<td colspan="3"><span id="id_number"></span></td>
							</tr>
							<tr>
								<td>政治面貌</td>
								<td><span id="political_affiliation">团员</span></td>
								<td>民族</td>
								<td><span id="nation">汉族</span></td>
							</tr>
							<tr>
								<td>家庭地址</td>
								<td colspan="3"><span id="family_address"></span></td>
							</tr>
						</table>
					</div>
				</div>
				<button id="cameraBtn" class="check" onclick="">确认信息并进行身份验证</button>
			</div>
			<div class="swiper-slide">
				<div class="topBg">
					<div class="videoBox">
						<!-- <video id="webcam" class="myVideo"></video> -->
						<video id="webcam" class="myVideo" autoplay playsinline></video>
					</div>
					<div class="borderBox"></div>
					<div class="fgBg"></div>
				</div>
				<div class="bottomBg girl"></div>
				<div id="demo"></div>
				<!-- <button class="check" onclick="getCurLocation()">开始验证</button> -->
				<button class="check" onclick="getFaceImg();">开始验证</button>
			</div>
		</div>
		<!-- 遮罩层DIV -->
	    <div id="overlay" class="overlay"></div>
	    <!-- Loading提示 DIV -->
	    <div id="loadingTip" class="loading-tip">
	        <img th:src="@{/static/html5/images/loading.gif}" />
	    </div>
	</div>
	<script type="text/javascript">
		var studentInfo;
		var index;
		var pos;
		var basePath = '[[${#httpServletRequest.getScheme() + "://" + #httpServletRequest.getServerName() + ":" + #httpServletRequest.getServerPort() + #httpServletRequest.getContextPath()}]]';
		var regEx = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/;
		var swiper = new Swiper('.swiper-container', {
			simulateTouch : false,
			onSlideChangeStart: function(swiper){
				var currentIndex = swiper.clickedIndex
				var activeIndex = swiper.activeIndex;
				if(currentIndex==0 && activeIndex==1){//第一页,滑动到第二页,校验身份证号码
					var result = checkIdCard();
					if(!result){
						layer.msg("请输入正确的身份证号码");
						//alert("请输入正确的身份证号码");
						return;
					}else{
						nextSwiper(activeIndex);
					}
				}
			}
		});
		const video = document.getElementById('webcam');
		const button = document.getElementById('cameraBtn');
		let currentStream;
		button.addEventListener('click', event => {
			nextSwiper(2);
			  var constraints = {
				video: {'facingMode': "user"},
				audio: false
			  };
			  navigator.mediaDevices
				.getUserMedia(constraints)
				.then(stream => {
				  currentStream = stream;
				  video.srcObject = stream;
				  return navigator.mediaDevices.enumerateDevices();
				})
				.catch(error => {
				  console.error(error);
				});
		});

		function checkIdCard(){
			var idcard = $('#idcard').val();//获取用户输入的身份证号码
			var result = regEx.test(idcard);
			return result;
		}
		//填好身份证,点按钮或滑动,滑动到第二个页面
		function nextSwiper(index) {
			//滑动前,获取第二个页面学生信息;
			if (index === 1) {
				var result = checkIdCard();
				if(!result){
					layer.msg("请输入正确的身份证号码");
					//alert("请输入正确的身份证号码");
				}else{
					$.ajax({
						url : basePath + '/h5/getStudentInfo',
						async : false,
						cache : false,
						data : {
							"idcard" : $('#idcard').val()
						},
						error : function(result) {// 请求失败处理函数
							layer.msg(result.msg);
							//alert(result.msg);
						},
						success : function(result) { //请求成功后处理函数
							debugger;
							studentInfo = result;
							swiper.slideTo(index);
							//将获取的学生信息赋值
							if (result.admission_photo) {
								$('#admission_photo').attr("src",basePath + "/uploadImg/admission_photo/"+ result.admission_photo);
							}
							$('#name').html(result.name);
							$('#gender').text(result.gender);
							$('#student_id').html(result.student_id);
							$('#major_name').html(result.major_name);
							$('#class_name').html(result.class_name);
							//基本信息
							$('#date_birth').html(result.date_birth);
							$('#hometown').html(result.hometown);
							$('#id_number').html(result.id_number);
							$('#political_affiliation').html(result.political_affiliation);
							$('#nation').html(result.nation);
							$('#family_address').html(result.family_address);
						}
					})
				}
			} else if (index === 2) {//滑到
				swiper.slideTo(index);
				startFace();
			}
		}

		function startFace() {
			navigator.getUserMedia = navigator.getUserMedia
					|| navigator.webkitGetUserMedia
					|| navigator.mozGetUserMedia;

			if (navigator.getUserMedia) {
				navigator.getUserMedia({
					audio : false,
					video : {
						width : 400,
						height : 400,
						facingMode : "user"
					}
				}, function(stream) {
					debugger;
					var video = document.querySelector('video');
					try {
						video.src = window.URL.createObjectURL(stream);
					} catch (e) {
						console.log(e);
						video.srcObject = stream;         //注意,不同版本video.src和video.srcObject两种
					}
					video.onloadedmetadata = function(e) {
						video.play();
					};

				}, function(err) {
					console.log("The following error occurred: " + err.name);
				});
			} else {
				console.log("getUserMedia not supported");
			}
		}
		//获取视频中人脸,转换成图片,发送后台请求,识别图片
		function getFaceImg() {
			showLoading();
			debugger;
			var video = document.querySelector('video');
			var canvasObj = document.querySelector('canvas')
			var context1 = canvasObj.getContext('2d');
			context1.fillStyle = "#000000";
			context1.fillRect(0, 0, 300, 300);
			context1.drawImage(video, 0, 0, 300, 300);

			var url = canvasObj.toDataURL();  //toDataURL()获取的数据有images前缀,要split取后面一部分传给后台,后台直接用
			var face = url.split(",")[1];
			$('#idcard').val(studentInfo.id_number);
			$.ajax({
		           url: basePath+'/h5/checkFace',
		           type:"POST",
		           async: false,
		           cache: false,
		           data: {"face":face,"idcard":studentInfo.id_number},
		           success: function(data) {
		        	   hideLoading();
		        	   debugger;
		        	   var data = $.parseJSON(data);
		        	   if(data.success){
		        		   registerFun();
		        	   }else{
		        		   var msg = data.msg;
		        		   if('不是待报到学生'==msg){
		        			   //关闭当前人脸识别页面,避免人脸识别百度接口多次调用,产生多次费用
		        			   window.close();
		        		   }else{
		        			   layer.msg(msg);
		        		   }
		        	   }
		           },
		           error:function(msg) {
		           	console.log(msg);
		           }
		       });
		}
		//base64转换为Blob
		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
			});
		}
		var geolocation = new BMap.Geolocation();
		var gc = new BMap.Geocoder(); 
		var map = new BMap.Map("allmap");
		geolocation.getCurrentPosition(function(r) {
			if (this.getStatus() == BMAP_STATUS_SUCCESS) {
				var pt = r.point;  
		        gc.getLocation(pt, function(rs){ 
					var address = rs.addressComponents; 
					var mk = new BMap.Marker(r.point);
					map.addOverlay(mk);
					var latCurrent = r.point.lat;
					var lngCurrent = r.point.lng;
					var myPoint = new BMap.Point(lngCurrent, latCurrent);
					debugger;
					pos = {
								lat : latCurrent,
								lng : lngCurrent,
								nation : address.nation==undefined?null:address.nation,
								province : address.province==undefined?null:address.province,
								city : address.city==undefined?null:address.city,
								district : address.district==undefined?null:address.district,
								street : address.street==undefined?null:address.street,
								streetNumber : address.streetNumber==undefined?null:address.streetNumber,
								adcode : address.adcode==undefined?null:address.adcode,
								address : rs.address==undefined?null:rs.address,
								business : rs.business==undefined?null:rs.business,
						}
		        	});
			} else {
				alert('failed' + this.getStatus());
			}
		}, {
			enableHighAccuracy : true
		})
		function registerFun(){
			var data={};
			data["reg_id"]=$('#reg_id').val();
			data["complete"]="报到成功";
			data["location"]=pos;
			data["step_id"]="4";
			data["school_address"]=null;
			$.ajax({
				url : basePath+'/h5/registe',
				method: "POST",
				dataType: "json",
				contentType: "application/json;charset=utf-8",
				async: false,
				data:JSON.stringify(data),
				error : function(result) {// 请求失败处理函数
					alert(result.msg);
				},
				success : function(result) { //请求成功后处理函数
					debugger;
	                if (result.success) {
	                	window.close();

	                	layer.msg('报到成功', {icon: 1});
	                	//sleep 1秒钟,再关闭,让用户能看到提示消息
	                	var start = (new Date()).getTime();
		               	while ((new Date()).getTime() - start < 1000) {
		               	    continue;
		               	}
		               	window.close();
	                }else {
	                	layer.msg('报到失败', {icon: 1});
	                }
				}
			})
		}
		/**
		 * 显示遮罩层
		 */
		function showOverlay() {
		    // 遮罩层宽高分别为页面内容的宽高
		    $('.overlay').css({'height':$(document).height(),'width':$(document).width()});
		    $('.overlay').show();
		}
		/**
		 * 显示Loading提示
		 */
		function showLoading() {
		    // 先显示遮罩层
		    showOverlay();
		    // Loading提示窗口居中
		    $("#loadingTip").css('top',
		            (getWindowInnerHeight() - $("#loadingTip").height()) / 2 + 'px');
		    $("#loadingTip").css('left',
		            (getWindowInnerWidth() - $("#loadingTip").width()) / 2 + 'px');
		            
		    $("#loadingTip").show();
		    $(document).scroll(function() {
		        return false;
		    });
		}
		/**
		 * 隐藏Loading提示
		 */
		function hideLoading() {
		    $('.overlay').hide();
		    $("#loadingTip").hide();
		    $(document).scroll(function() {
		        return true;
		    });
		}
		//浏览器兼容 取得浏览器可视区高度
		function getWindowInnerHeight() {
		    var winHeight = window.innerHeight
		            || (document.documentElement && document.documentElement.clientHeight)
		            || (document.body && document.body.clientHeight);
		    return winHeight;
		}
		// 浏览器兼容 取得浏览器可视区宽度
		function getWindowInnerWidth() {
		    var winWidth = window.innerWidth
		            || (document.documentElement && document.documentElement.clientWidth)
		            || (document.body && document.body.clientWidth);
		    return winWidth;
		}
	</script>
</body>
</html>

  

后台Controller

     @ResponseBody
	@RequestMapping(value = "/h5/checkFace", method = RequestMethod.POST)
	public Object checkFace(String face, String idcard) {
		try {
			//1.在线活体检测
			boolean isLive = FaceUtil.faceverify(faceProperties.getAipFace(), face);
			if (isLive) {// 检测到是人脸,继续搜索是谁的脸
				// 2.人脸搜索
				org.json.JSONObject res = FaceUtil.search(faceProperties.getAipFace(), face);
				System.out.println(res.toString(2));
				String msg = String.valueOf(res.get("error_msg"));
				if ("SUCCESS".equals(msg)) {
					
					//TODO 3.找到人脸,怕有误差,进一步判断身份证号码
					/*JSONObject result = res.getJSONObject("result");
					JSONArray users = result.getJSONArray("user_list");
					Gson gson = new Gson();
					UserInfo userInfo = gson.fromJson(users.get(0).toString(), UserInfo.class);
					System.out.println(userInfo);
					
					if(idcard.equals(userInfo.getIdcard())){
						return renderSuccess("检测成功");
					}else {
						return renderError("身份证号码不匹配");
					}*/
					
					return renderSuccess("检测成功");
				} else {
					return renderError("没有搜索到匹配的人脸图像");
				}
			} else {
				return renderError("没有检测到有效的人脸图像");
			}
		} catch (JsonSyntaxException e) {
			e.printStackTrace();
			return renderError("检测失败");
		} catch (JSONException e) {
			e.printStackTrace();
			return renderError("检测失败");
		}
	}

  

人脸识别工具类:调用百度接口

public class FaceUtil {

	static BASE64Encoder encoder = new sun.misc.BASE64Encoder();
	static BASE64Decoder decoder = new sun.misc.BASE64Decoder();
	static String imageType = "BASE64";

	/**
	 * 图片路径编码成字符串
	 * @param image
	 * @return
	 */
	public static String getImageBinary(String image) {
		File f = new File(image);
		try {
			BufferedImage bi = ImageIO.read(f);
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			ImageIO.write(bi, "jpg", baos);
			byte[] bytes = baos.toByteArray();

			return encoder.encodeBuffer(bytes).trim();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 查询所有组列表
	 * @param client
	 * @return
	 */
	public static String getGroup(AipFace client) {
		// 传入可选参数调用接口
		try {
			HashMap<String, String> options = new HashMap<String, String>();
			options.put("start", "0");
			options.put("length", "50");
			// 组列表查询
			JSONObject res = client.getGroupList(options);
			String msg = res.getString("error_msg");
			if ("SUCCESS".equals(msg)) {
				JSONObject arr = res.getJSONObject("result");
				JSONArray list = arr.getJSONArray("group_id_list");
				String groupIdList = list.join(",");
				groupIdList = groupIdList.replace("\",\"", ",");
				groupIdList = groupIdList.replace("\"", "");
				System.out.println("获取分组:"+groupIdList);
				return groupIdList;
			}
			return null;
		} catch (JSONException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	/**
	 * 在线活体检测
	 * @param client
	 * @param face
	 * @return
	 */
	public static boolean faceverify(AipFace client,String face) {
    	//在线活体检测
		try {
			FaceVerifyRequest req = new FaceVerifyRequest(face,imageType);
			ArrayList<FaceVerifyRequest> list = new ArrayList<FaceVerifyRequest>();
			list.add(req);
			JSONObject res = client.faceverify(list);
			String msg = String.valueOf(res.get("error_msg"));
			if("SUCCESS".equals(msg)) {
				return true;
			}
			return false;
		} catch (JSONException e) {
			e.printStackTrace();
			return false;
		}
	}
	
	/**
	 * 人脸搜索:在所有分组库中搜索,不存在,返回result为空,存在返回分数最高的排名max_user_num个用户信息
	 * @param client
	 * @param face
	 * @return
	 */
	public static JSONObject search(AipFace client,String face) {
		HashMap<String, String> options = new HashMap<String, String>();
        options.put("max_face_num", "1");
        options.put("match_threshold", "70");
        options.put("quality_control", "NORMAL");
        options.put("liveness_control", "LOW");
        options.put("max_user_num", "1");
        String groupIdList = getGroup(client);
        System.out.println("groupIdList:"+groupIdList);
        // 人脸搜索
        try {
			JSONObject res = client.search(face, imageType, groupIdList, options);
			System.out.println(res.toString(2));
			return res;
		} catch (JSONException e) {
			e.printStackTrace();
			return null;
		}
	}
}

  

要引入maven包:

<dependency>
		    <groupId>com.baidu.aip</groupId>
		    <artifactId>java-sdk</artifactId>
		    <version>4.11.3</version>
		</dependency>
		<dependency>
		  <groupId>org.json</groupId>
		  <artifactId>json</artifactId>
		  <version>20160810</version>
		</dependency>
		<dependency>
		  <groupId>com.google.code.gson</groupId>
		  <artifactId>gson</artifactId>
		  <version>2.8.5</version>
		</dependency>

  swiper  

      simulateTouch : false  禁止滑动,只对PC有用,对移动端无效

 

posted @ 2019-09-23 17:10  点点积累  阅读(1873)  评论(0编辑  收藏  举报