Web前端+Java实现人脸识别登录

原文地址:https://blog.csdn.net/youth_shouting/article/details/88804324

使用前端页面+java后台实现人脸登录,人脸的图像对比是调用的百度接口(百度AI开放平台)。
一、实现思路
a.前端页面调用设备摄像头获取实时图片数据。
b.通过Ajax将图片数据提交后台处理,并返回处理后的数据。
c.后台使用java调用接口进行图片的对比。
d.最后将返回的结果进行分析后返回前端页面。
二、准备工作
a.编辑器:Myeclipse写jiava代码、WebStorm写前端页面(编辑器随便什么都可以的)。
b.jar包

å¨è¿éæå¥å¾çæè¿°

c.百度AI接口
三、前端页面
a.需要使用到两个标签,一个是<video>一个是<canvas>,这两个标签,video是将摄像头获取到的数据呈现成视频,canvas是画布,将视频中的画面换成图片。
b.将获取到的图片数据通过Ajax请求的方式作为数据传到java后台。
c.前端代码

<div id="face-box">
    <video id="video"></video>
    <canvas id="canvas" style="display: none;"></canvas>
</div>

d.js代码
GetFace.js打开摄像头和获取图片

/*
在用getUserMediaToPhoto之前要写两个回调函数,一个success 一个 error
格式:
 function success(stream){
 }
//失败回调函数
function error(error) {
}
*/
//成功回调函数
var video = document.getElementById("video");
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var mediaStreamTrack=null;
function success(stream){
    //兼容webkit核心浏览器
    // var CompatibleURL = window.URL || window.webkitURL;
    //将视频流转化为video的源
    mediaStreamTrack=stream;
    try {
        // video.src = CompatibleURL.createObjectURL(stream);
        video.srcObject=stream;
    }catch (e) {
        console.log("访问用户媒体设备失败:",error.name,error.message);
    }

    video.play();//播放视频

    //将视频绘制到canvas上
}
//错误回调函数
function error(error) {
    console.log('访问用户媒体失败:',error.name,error.message);
}
function getUserMediaToPhoto(constraints,success,error) {
    if(navigator.mediaDevices.getUserMedia){
        //最新标准API
        navigator.mediaDevices.getUserMedia(constraints).then(success).catch(error);
    }else if (navigator.webkitGetUserMedia) {
        //webkit核心浏览器
        navigator.webkitGetUserMedia(constraints,success,error);
    }else if(navigator.mozGetUserMedia){
        //firefox浏览器
        navigator.mozGetUserMedia(constraints,success,error);
    }else if(navigator.getUserMedia){
        //旧版API
        navigator.getUserMedia(constraints,success,error);
    }
}

function getFace() {
        context.drawImage(video,0,0,300,150);
        this.img=canvas.toDataURL('image/jpg')
       //获取完整的base64编码
        this.img=img.split(',')[1];
        return this.img;
}
function openUserMedia() {
    if(navigator.mediaDevices.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.getUserMedia){
        getUserMediaToPhoto({video:{width:480,height:320,facingMode: "user"}},success,error);
    }else{
        alert('你的浏览器不支持访问用户媒体设备');
    }
}
function  offUserMedia() {
    if(mediaStreamTrack!=null)
    mediaStreamTrack.getTracks()[0].stop();
}

FaceLoginAjax.js数据提交

function Facelogin() {
    setTimeout(function () {
        img = getFace();
        $.ajax({
            type:"post",
            url:"http://localhost:8080/DDserver/LoginServlet",
            data:{
                "imgpath":img,
                "imgType":"BASE64"
            },
            success:function (data) {
                var obj= new Function("return"+data)();
                var result=obj.result;
                var error_msg=obj.error_msg;
                if("SUCCESS"===error_msg){
                    sessionStorage.setItem("account",result.user_id);
                    location.href="Main.html";
                }
                else{
                    Facelogin();
                }
            },
            error:function () {
                alert("连接服务器失败")
            },
            async:true
        })
    },500);
}

四、后台Java
a.在Myeclipse中新建一个web项目,并导入上面的jar包,然后在src文件夹下创建一个facelogin的包

å¨è¿éæå¥å¾çæè¿°

这是里面的结构,代码如下
AiFaceObject.java
这个类是使用单例模式创建一个AipFace对象,因为我们后面会一直使用这个对象,而这个对象的创建会得到一个SDK,这个SDK的有效期好像是一个月。所以我们没必要一直创建对象来获取这个SDK,就使用单例模式创建最好。

package cn.ddserver.facelogin;

import com.baidu.aip.face.AipFace;

public class AiFaceObject {
		 //设置APPID/AK/SK
	    public static final String APP_ID = "你的APP_ID";
	    public static final String API_KEY = "你的..";
	    public static final String SECRET_KEY = "你的..";
	    //这上面的东西在你申请百度接口的时候 都会给的
	    
	    //创建一个aipface对象
	    private static AipFace client = new AipFace(APP_ID, API_KEY, SECRET_KEY);
	    //创建单例的原因是避免多次获取sdk
	    public static AipFace getClient(){
	    	client.setConnectionTimeoutInMillis(2000);
	    	client.setSocketTimeoutInMillis(60000);
	    	return client;
	    }
	    
}

FaceComparison.java
这个类是实现两张人脸照片的比较,返回比较后的字符串结果

package cn.ddserver.facelogin;

import java.util.ArrayList;

import org.json.JSONObject;

import com.baidu.aip.face.AipFace;
import com.baidu.aip.face.MatchRequest;

import cn.ddserver.entity.Image;

public class FaceComparison {
	
	public static String Facecomparison(AipFace client,Image imageU,Image imageC){
		
		MatchRequest req1 = new MatchRequest(imageU.getImage(), imageU.getImageType());
	    MatchRequest req2 = new MatchRequest(imageC.getImage(), imageC.getImageType());
	    ArrayList<MatchRequest> requests = new ArrayList<MatchRequest>();
	    requests.add(req1);
	    requests.add(req2);
	    JSONObject res = client.match(requests);
		return res.toString(2);
		
	}

}

FaceDetection.java
这个类是人脸的检测,因为在获取人脸照片的时候如果没有人脸的照片是不合格的,如果保存了这样的数据,后面进行人脸比较的时候,肯定是比对不成功的

package cn.ddserver.facelogin;

import java.util.HashMap;

import org.json.JSONObject;

import com.baidu.aip.face.AipFace;

import cn.ddserver.entity.Image;


public class FaceDetection {//人脸检测的类

	public static String Facedetection(AipFace client,Image image){
		HashMap<String, String> options= new HashMap<String, String>();
		options.put("face_field", "age");//返回的人脸信息
		options.put("max_face_num", "1");//最大人脸识别数1
		options.put("face_type", "LIVE");//照骗类型 生活照
		JSONObject res=client.detect(image.getImage(), image.getImageType(), options);
		return res.toString(2);
	}

}

FaceRegistration.java
这个类是进行人脸的注册,就是在百度的人脸库里面注册你的用户人脸库,可以不使用。你可以使用两张图片进行比较。但是这里为了方便,使用这个库和前端上传的图片进行匹配得到匹配成功的图片ID实现登录。

package cn.ddserver.facelogin;

import java.util.HashMap;

import org.json.JSONObject;

import com.baidu.aip.face.AipFace;

import cn.ddserver.entity.Image;

public class FaceRegistration {
	
	public static String Faceregistrtion(AipFace client,String groupId,String userId,Image image){
		 // 传入可选参数调用接口
	    HashMap<String, String> options = new HashMap<String, String>();
	    options.put("user_info", "user's info");
	    options.put("quality_control", "NORMAL");
	    options.put("liveness_control", "LOW");
	    // 人脸注册
	    JSONObject res = client.addUser(image.getImage(), image.getImageType(), groupId, userId, options);
	    
		return res.toString(2);
	}
	
}

FaceUser.java

package cn.ddserver.facelogin;

import java.util.HashMap;

import org.json.JSONObject;

import com.baidu.aip.face.AipFace;

import cn.ddserver.entity.Image;

public class FaceUser {

	public static String Faceuser(AipFace client,Image imageU){
		// 传入可选参数调用接口
	    HashMap<String, String> options = new HashMap<String, String>();
	    options.put("quality_control", "NORMAL");
	    options.put("liveness_control", "LOW");
	    options.put("max_user_num", "1");
	    
	   
	    String groupIdList = "你的人脸库名称";
	    
	    // 人脸搜索
	    JSONObject res = client.search(imageU.getImage(), imageU.getImageType(), groupIdList, options);
	    return res.toString(2);
	}
}

b.上面已经完成了访问百度接口,调用函数将参数传入就可以得到相应的结果字符串。后面要做的就是将这些字符串进行分析。分析数据的类

å¨è¿éæå¥å¾çæè¿°

这里根据个人的需求而定。
五、登录使用的Servlet
LoginServlet.java

package cn.ddserver.servlet;

import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.json.simple.JSONObject;

import cn.ddserver.entity.AccountIfo;
import cn.ddserver.entity.Image;
import cn.ddserver.entity.SerquestIfo;
import cn.ddserver.faceuntils.DetectionFace;
import cn.ddserver.faceuntils.UserFace;
import cn.ddserver.untils.Dbutil;
import net.sf.json.JSONArray;

/**
 * Servlet implementation class LoginServlet
 */
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public LoginServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
    @SuppressWarnings("unchecked")
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setCharacterEncoding("utf-8");
		response.setHeader("Access-Control-Allow-Origin", "*");
		response.setHeader("Access-Control-Allow-Methods", "*");
		response.setHeader("Access-Control-Max-Age", "3600");
		response.setHeader("Access-Control-Allow-Headers", "Content-Type, x-requested-with, X-Custom-Header, HaiYi-Access-Token");
		/*
		 * 验证登录
		 */
		//从数据库查询数据
		JSONObject resjson= new JSONObject();
		AccountIfo user= new AccountIfo();
		SerquestIfo reques=new SerquestIfo();//请求对象
		Image imageU=new Image();
		//将账号密码放入 账户信息 对象
		user.setDd_account(request.getParameter("account"));
		user.setDd_password(request.getParameter("password"));
		imageU.setImage(request.getParameter("imgpath"));
		imageU.setImageType(request.getParameter("imgType"));
		reques.setPage(request.getParameter("page"));
		reques.setUser(user);
		reques.setImageU(imageU);
		 if("2".equals(reques.getPage())){//人脸登录
			JSONObject json=Faclogin(reques.getImageU());
			if("SUCCESS".equals(json.get("error_msg"))){
				resjson.put("error_msg", "SUCCESS");
				resjson.put("result", json);
			}else{
				resjson.put("error_msg", "error");
				resjson.put("result", "null");
			}
			
		}
		else if("3".equals(reques.getPage())){//注册
			
		}
		else{
			JSONObject json=Paslogin(reques.getUser());
			if("SUCCESS".equals(json.get("error_msg"))){
				resjson.put("error_msg", "SUCCESS");
				resjson.put("result", json);
			}
			else{
				resjson.put("error_msg", "error");
				resjson.put("result", "null");
			}
		}
		response.getWriter().print(resjson);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

	@SuppressWarnings("unchecked")
	public static JSONObject Paslogin(AccountIfo user){//密码登录
		Connection conn=Dbutil.getConnection("com.mysql.jdbc.Driver", "jdbc:mysql://localhost/ddserver", "root", "");
		String sql="select account from UserIfo where account=? and password=?";
		String param[] = new String[2];
		JSONObject json=new JSONObject();
		param[0]=user.getDd_account();
		param[1]=user.getDd_password();
		ResultSet res=Dbutil.executQuery(conn, sql, param);
		json.put("error_msg", "error");
		try {
			while(res.next()){
				json.put("error_msg", "SUCCESS");
				json.put("user_id",user.getDd_account());
				break;
			}
			
		} catch (Exception e) {
			// TODO: handle exception
			json.put("error_msg", "error");
		}
		
		return json;
	}

	@SuppressWarnings("unchecked")
	public static JSONObject Faclogin(Image imageU){//人脸登录
		 JSONObject json=new JSONObject();
		 json.put("error_msg", "error");
		if(imageU!=null){
			JSONObject dfjson=DetectionFace.Detection(imageU);//合格照片检查
			if("SUCCESS".equals(dfjson.get("error_msg"))){
				JSONObject uf=UserFace.User(imageU);//提交
				if("SUCCESS".equals(uf.get("error_msg").toString())){//查询出结果
					Double score=new Double(uf.get("score").toString());
					if(score>70){
						json.put("error_msg", "SUCCESS");
						json.put("user_id", uf.get("user_id").toString());
					}
					else {
						//
					}
				}else{
					//
				}
			}
			else{
				json.put("face_num", "人脸不合格");
			}
		}
		return json;
	}
}

这样一个简单的人脸登录就完成啦。自己项目的一个简单效果

å¨è¿éæå¥å¾çæè¿°

猜你喜欢

转载自blog.csdn.net/qq_19734597/article/details/89556590