【人脸识别】H5人脸识别实例系列一(人脸检测)
荒墨丶迷失 发布于2017-12-06 16:26 浏览:20568 回复:109
11
收藏

(。・∀・)ノ゙嗨咯,Everyone~ 

今天给大家带来的是 windows平台下,如何通过H5页面实现人脸识别的功能呢,一起探索!

首先能,还是介绍一下百度人脸识别的接口情况吧,详情可见官方文档:http://ai.baidu.com/docs#/Face-API/top

本次系列将会持续更新,人脸检测,人脸对比,人脸查三个方向的实例

好了,回归本贴主题,【H5的人脸检测】

人脸检测的官方描述:

检测请求图片中的人脸,返回人脸位置、72个关键点坐标、及人脸相关属性信息。

检测响应速度,与图片中人脸数量相关,人脸数量较多时响应时间会有些许延长。

典型应用场景:如人脸属性分析,基于人脸关键点的加工分析,人脸营销活动等。

五官位置会标记具体坐标;72个关键点坐标也包含具体坐标,但不包含对应位置的详细位置描述。

总结一句话就是:检测人脸图片,返回各种人脸属性数据。

接下来重点讲解如何实现吧~实现的样式如图(稍微把我给P了一下,哈哈)

注意:此实例并不是最优的一种方式,只是一个基础的实现过程,具体优化需要后续努力~

第一步:以下是一段判断浏览器是否支持HTML5的一个函数方法,便于大家测试。

//判断浏览器是否支持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.getUserMedia(videoObj, function (stream) {
				video.srcObject  = stream;
				video.play();
			}, errBack);
		} else if (navigator.webkitGetUserMedia) {
			navigator.webkitGetUserMedia(videoObj, function (stream) {
				video.src = window.webkitURL.createObjectURL(stream);
				video.play();
			}, errBack);
		}
	
	}, false);

然后就完了?NONO~~以下是重点:

接下来是如何将获取的图片数据传到后台呢?我在用ajax传base64的图片数据的时候,失败过三次

都是因为长度太长,导致后台无法获得正取的图片数据,从而调用API时返回的数据是空。

于是我的解决办法就是用的formData 作为对象传到后台进行解析

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

以上这个方法是一个重点,你在用formData时,需要将base64数据转换为blob写入数据的

如果不清楚可以在本帖中提问。

前端的实现讲完了,ajax提交之后,后台需要如何处理呢?

 /**
   	 * 请求人脸检测
   	 * @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(); 
	        //调用人脸检测的方法
	        Map<String, String>  strmap = FaceDetect.detectby(in2b);
	        //将map数据封装json传到前台
			String strjson = JsonUtil.mapToJson(strmap);
			modelMap.put("strjson", strjson);
			modelMap.put("success", true);
		} catch (Exception e) {
			modelMap.put("success", false);
			modelMap.put("data", e.getMessage());
		}
		return modelMap;
	}

这是JAVA后台接受前台传来的图片数据,用的是SpringMVC框架,重点请看如何将接收的数据转为图片字节数组(因为人脸检测API是需要这个)

最后呢,就说一说人脸检测的API方法如何调用解析吧

 public static Map<String, String> match2(byte[] arg0,byte[] arg1) {
    	Map<String, String> map = new HashMap<String,String>();
        // 请求url
        String url = "https://aip.baidubce.com/rest/2.0/face/v2/match";
        try {
            // 活体检测人脸
            String imgStr = Base64Util.encode(arg0);//
            String imgParam = URLEncoder.encode(imgStr, "UTF-8");

            //身份证人脸          
            String imgStr2 = Base64Util.encode(arg1);
            String imgParam2 = URLEncoder.encode(imgStr2, "UTF-8");

            String param = "images=" + imgParam + "," + imgParam2;

            // 注意这里仅为了简化编码每一次请求都去获取access_token,线上环境access_token有过期时间, 客户端可自行缓存,过期后重新获取。
            String accessToken = "";

            String str = HttpUtil.post(url, accessToken, param);
            System.out.println(str);
            
            JSONObject jsonobject = JSONObject.fromObject(str);
	     	String result = jsonobject.getString("result");
	     	
	     	JSONArray json = JSONArray.fromObject(result); // 首先把字符串转成 JSONArray  对象
	     	 for(int i=0;i<json.size();i++){
			        JSONObject job = json.getJSONObject(i);  // 遍历 jsonarray 数组,把每一个对象转成 json 对象
			    	//获取年龄
			        Double score1 = (Double) job.get("score");
			     	//处理年龄
			        String score =String.valueOf(new BigDecimal(score1).setScale(0, BigDecimal.ROUND_HALF_UP));
					map.put("score", score);
			 }
            return map;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    
    }

由以上代码可以看出,JSON解析过程中,百度返回的其实是一个json数组,我们需要做一定的处理才行,以及得到的数据类型

好啦,今天的分享就到这里了,其实这个只是最初步的搭建H5人脸检测,后续的优化会带来活体检测的质量,以及人脸坐标位置,多人检测等

还有就是人脸系列中的比对,注册,查找等功能

附上源码地址:https://gitee.com/liyingming/faceRecognition

谢谢大家~~

收藏
点赞
11
个赞
共109条回复 最后由吃泡面被开除回复于2018-10-09 16:31
#110吃泡面被开除回复于2018-10-09

调用 v3的api报错   是为什么呢 格式看了一下也是对的

"error_code":222200,"error_msg":"request body should be json format"

0
#109孔老夫子6816回复于2018-09-04

报错:CatchCode is not defined

0
#108打砼回复于2018-09-03

麻烦问一下,你这些参数里面没传入image_type这个字段 你是怎么实现的?按照您这个思路走死胡同里了,  

0
#107荒墨丶迷失回复于2018-08-13
#105 利刃101回复
有个缺陷苹果的手机不能用

有研究苹果的怎么用吗?分享一下

1
#106利刃101回复于2018-08-10
#99 稻秧天尊回复
弱弱的问一句,微信公众号里面也能用吗?

安卓的可以,苹果的你就要改良一下了

0
#105利刃101回复于2018-08-10

有个缺陷苹果的手机不能用

0
#104756665228回复于2018-08-08
#103 利刃101回复
我想说你还是用了API啊用不是纯js还H5识别这是H5识别吗?不太理解你的H5概念和不和我的一样,但是你这个真的不是H5而是调用接口,H5应该只有js和html和css代码吗,是不是有误解啊
展开

H5说法是有些不太准确了。他这就算是HTML+JS(走Java后台 Java后台再走百度AI接口)这样的流程 外加一些额外的js插件

“H5应该只有js和html和css代码吗” 也没错  只是他的JS是走了Java后台

0
#103利刃101回复于2018-08-08

我想说你还是用了API啊用不是纯js还H5识别这是H5识别吗?不太理解你的H5概念和不和我的一样,但是你这个真的不是H5而是调用接口,H5应该只有js和html和css代码吗,是不是有误解啊

0
#102荒墨丶迷失回复于2018-07-06
#101 font_end_john回复
请问微信公众号里面可以做人脸识别吗

你好 也是可以的呢 主要分手机端和PC端这两种情况

1
#101font_end_john回复于2018-07-05

请问微信公众号里面可以做人脸识别吗

0
#100荒墨丶迷失回复于2018-06-19
#99 稻秧天尊回复
弱弱的问一句,微信公众号里面也能用吗?

手机端的实现应该是不一样的  可以研究研究~

1
#99稻秧天尊回复于2018-06-15

弱弱的问一句,微信公众号里面也能用吗?

0
#98百福全a回复于2018-05-25

H5能像原生应用一样控制照片中人脸的清晰程度嘛

0
#97wukunlu7回复于2018-05-21

对于“用ajax传base64的图片数据的时候”,大家还有其他的解决方法吗?

0
#96涉世未深丶回复于2018-05-09
#89 雕栏以流年回复
好的,谢谢大佬,我也去研究研究

研究出来了吗?我也遇到了同样的问题!!!

0
#95荒墨丶迷失回复于2018-05-02
#92 rongsoft回复
请问,有jsp 简洁 版本的么。不是 spring的

我这个是前台页面负责收集 人脸视频流信息 然后用后台java调用识别接口的。

如果你想用存jsp的  可以试着用node.js搭配 H5页面

1
#94荒墨丶迷失回复于2018-05-02
#93 rongsoft回复
result===={"error_code":222001,"error_msg":"param[image_type] is null","log_id":2678981081,"timestamp":1525191151,"cached":0,"result":null} 请问这个什么问题。
展开

这个是百度返回的错误信息,image_type这个参数是空的呢

1
#93rongsoft回复于2018-05-02

result===={"error_code":222001,"error_msg":"param[image_type] is null","log_id":2678981081,"timestamp":1525191151,"cached":0,"result":null}

请问这个什么问题。

0
#92rongsoft回复于2018-05-01

请问,有jsp 简洁 版本的么。不是 spring的

0
#91荒墨丶迷失回复于2018-04-11
#90 leisure1211回复
楼主, 你分享的源码打不开,可以发一份到我邮箱么?谢谢!466435831@qq.com
展开

已发送了  请查收

0
TOP
切换版块