基于百度人脸识别的小区人脸门禁系统

又是一年毕业季,自己转眼间也毕业一年了!!!前段时间帮学妹指导了一个小区人脸识别门禁系统,整个的实现思路在此记录下,感兴趣的可以参考一下。

整个项目沟通后情况如下:

需求功能:

  1. 人脸录入
  2. 人脸更新
  3. 人脸删除
  4. 人脸搜索
  5. 数据备份,数据恢复
  6. 人脸登录
  7. 登录统计
  8. 管理员系统登录
  9. 小区管理

所用技术:按客户掌握的技能采用java、servlet、vue、jquery、js、ajax、boostrap、css、人脸图像处理部分主要采用百度api。

工期:2个星期。

整个项目最终效果:

https://img-blog.csdnimg.cn/20200530113040385.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0MDQyNDE3,size_16,color_FFFFFF,t_70

https://img-blog.csdnimg.cn/20200530110950898.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0MDQyNDE3,size_16,color_FFFFFF,t_70

 

  • 登录模块的实现思路

(一)代码实现

1、用户请求程序登录入口login.html页面;

2、采集摄像头实时人脸数据,每个1秒钟截取摄像头视频一帧画面,将人脸图片数据转换成base64格式发送给后台控制器;

3、控制器接收前台传入的人脸数据,调用具体的人脸搜索服务;

4、后台拼装参数请求百度api接口;

5、后台获取百度api接口响应数据;

6、后台判断该用户人脸数据是否存在远程人脸库且相似度超过80%,则继续查询本地该用户保存的社区信息和用户基本信息并返回,同时记录用户登录记录,最后提示用户登录成功。反之则返回空的用户信息用户登录失败;

 

 
 

 

 

 

(二)代码实现

//截取图片并请求后台隔

package com.face.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

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 com.face.opj.Face;
import com.face.opj.FaceAndGroup;
import com.face.opj.Groups;
import com.face.opj.MsgSearch;
import com.face.opj.ResultObj;
import com.face.service.FaceInfoCrud;
import com.face.service.FaceSearch;
import com.face.service.GroupsInfoCrud;
import com.face.service.LoginInfoCrud;
import com.google.gson.Gson;

import sun.misc.BASE64Decoder;


@WebServlet("/Login")
public class Login extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8;");
        PrintWriter out = response.getWriter();

        String b64 = request.getParameter("saveImg");
        BASE64Decoder decoder = new BASE64Decoder();    
        byte[] b = decoder.decodeBuffer(b64); 

        Gson gson = new Gson();
        FaceInfoCrud fc = new FaceInfoCrud();
        GroupsInfoCrud gc = new GroupsInfoCrud();
        LoginInfoCrud lc = new LoginInfoCrud();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        
        ResultObj ro = new ResultObj("500", "操作失败", null);
        Map result = new HashMap<String, Object>();
        result.put("groupName", "noInfo");
        result.put("name", "noInfo");
        result.put("tel", "noInfo");
        result.put("addr", "noInfo");

        //调用百度人脸接口查询
        if(b64!=null) {
            
            MsgSearch msgs = FaceSearch.Search(b);

            if(msgs.error_code == 0) {
                String userId = msgs.ShowSearched().user_id;
                String groupId = msgs.ShowSearched().group_id;

                ArrayList<FaceAndGroup> list2 = fc.selectOne(userId);
                String groupName = "";
                if(list2.size() > 0) {
                    if(null != list2.get(0).ext3) {
                        ArrayList<Groups> list1 = gc.selectOne(list2.get(0).ext3);
                        groupName = list1.get(0).name;
                    }
                    result.put("groupName", groupName);
                    result.put("name", list2.get(0).name);
                    result.put("tel", list2.get(0).tel);
                    result.put("addr", list2.get(0).ext2);
                    result.put("role", list2.get(0).role);

                    ro.code = "200";
                    ro.msg = "操作成功";
                    ro.obj = result;
                    
                    lc.insert(groupName,list2.get(0).name, list2.get(0).tel,sf.format(new Date()));
                }else{
                    ro.code = "500";
                    ro.msg = "没有在本地人脸库查到数据";
                    ro.obj = result;
                }
            }else {
                ro.code = "500";
                ro.msg = "请求远程人脸库失败";
                ro.obj = result;
            }
        }else {
            ro.code = "500";
            ro.msg = "人脸参数为空";
            ro.obj = result;
        }
        
        out.print(gson.toJson(ro));
        out.close();
    }
}
 

二、小区信息管理模块

添加小区:

1、管理员通过访问admin.html管理页面;

2、管理员输入相应的小区信息,并点击保存;

3、后台获取输入的小区信息并保存到数据库;

4、后台返回操作成功信息;


5、前台刷新小区信息;

删除小区:

  1. 查询该小区的所有用户;
  2. 删除小区信息;
  3. 删除该小区所有用户的本地人脸照片;
  4. 删除该小区所有用户的本地数据;
  5. 删除该小区所有用户的远程数据;

 

查询所有小区:

  1. 用户输入或者不输入小区信息后点击查询按钮;
  2. 后台获取查询参数;
  3. 后台查询小区信息并返回;

 

更新小区:

  1. 用户输入小区更改后的信息;
  2. 后台获取参数并保存;

package com.face.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

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 com.face.opj.FaceAndGroup;
import com.face.opj.Groups;
import com.face.opj.Msg;
import com.face.opj.ResultObj;
import com.face.service.AddGroup;
import com.face.service.DeleteGroup;
import com.face.service.FaceInfoCrud;
import com.face.service.GroupsInfoCrud;
import com.face.utils.FileUtil;
import com.face.utils.GsonUtils;
import com.google.gson.Gson;

@WebServlet("/GroupOperation")
public class GroupOperation extends HttpServlet {

    private static final long serialVersionUID = 1L;

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8;");
        String Operation = request.getParameter("Operation");
        String id = request.getParameter("id");
        String name = request.getParameter("name");
        
        Gson gson = new Gson();
        
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        
        ResultObj ro = new ResultObj("500", "操作失败", null);
        
        AddGroup ag = new AddGroup();
        DeleteGroup dg = new DeleteGroup();
        FaceInfoCrud fc = new FaceInfoCrud();
        GroupsInfoCrud gc = new GroupsInfoCrud();
        if("delete".equals(Operation)) {
            ArrayList<FaceAndGroup> list = fc.selectByGroupId(id);
            int isSuccess = gc.delete(id);
            if(isSuccess == 1) {
                String path = "";
                for(FaceAndGroup fg:list) {
                    path = request.getServletContext().getRealPath("")+fg.getUrl();
                    FileUtil.deletePic(path);
                    fc.delete(fg.getTel());
                }
                ro.setCode("200");
                ro.setMsg("删除小区成功!");
                
                // 远程用户组在人脸搜索时有数量限制,因此用户的小区信息只保存在本地 默认一个用户组user
//                Msg msg = GsonUtils.fromJson(dg.deleteGroup(id), Msg.class);
//                if(msg.error_code == 0) {
//                    ro.setCode("200");
//                    ro.setMsg("删除小区成功!");
//                }else {
//                    ro.setCode("500");
//                    ro.setMsg("远程删除小区失败!");
//                }
            }else {
                ro.setCode("500");
                ro.setMsg("本地删除小区失败!");
            }
        }else if("add".equals(Operation)) {
            boolean exist = gc.exist(id);
            if(exist) {
                ro.setCode("500");
                ro.setMsg("小区编号已存在!");
            }else {
                int isSuccess = gc.insert(id, name, sf.format(new Date()));
                if(isSuccess == 1) {
                    ro.setCode("200");
                    ro.setMsg("小区添加成功!");
                    
                    // 远程用户组在人脸搜索时有数量限制,因此用户的小区信息只保存在本地 默认一个用户组user
//                    Msg msg = GsonUtils.fromJson(ag.addGroup(id), Msg.class);
//                    if(msg.error_code == 0) {
//                        ro.setCode("200");
//                        ro.setMsg("小区添加成功!");
//                    }else {
//                        ro.setCode("500");
//                        ro.setMsg("远程添加小区失败!");
//                    }
                }else {
                    ro.setCode("500");
                    ro.setMsg("本地添加小区失败!");
                }
            }
        }else if("selectAll".equals(Operation)) {
            Map data = new HashMap<String, Object>();
            ArrayList<Groups> list = gc.selectAll();
            data.put("groups", list);
            ro.setCode("200");
            ro.setMsg("查询成功!");
            ro.setObj(data);
        }else if("update".equals(Operation)) {
            int result = gc.update(name, sf.format(new Date()), id);
            ro.setCode("200");
            ro.setMsg("查询成功!");
        }
        
        
        PrintWriter out = response.getWriter();
        out.print(gson.toJson(ro));
        out.close();
    }
    
}

 

三、用户信息管理模块

添加用户:

  1. 用户输入注册信息并请求后台;
  2. 后台获取注册信息;
  3. 判断该用户是否已存在;
  4. 存在着立即返回;
  5. 不存在则注册人脸到百度人脸库;
  6. 保存用户照片到本地;
  7. 保存用户信息到数据库;
  8. 返回注册成功信息;

 

删除用户:

  1. 管理员删除指定用户;
  2. 后台删除该用户基本信息;
  3. 删除改用户保存的人脸照片;
  4. 删除远程人脸库该用户的信息;
  5. 返回操作成功信息;

 

查询用户:

  1. 管理员输入查询参数;
  2. 后台后去查询参数并查询数据库;
  3. 后台返回查询结果;

package com.face.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

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 com.face.opj.Face;
import com.face.opj.FaceAndGroup;
import com.face.opj.Msg;
import com.face.opj.ResultObj;
import com.face.service.FaceDelete;
import com.face.service.FaceInfoCrud;
import com.face.utils.FileUtil;
import com.face.utils.GsonUtils;
import com.google.gson.Gson;

@WebServlet("/UserOperation")
public class UserOperation extends HttpServlet {

    private static final long serialVersionUID = 1L;

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8;");
        String Operation = request.getParameter("Operation");
        String tel = request.getParameter("tel");
        String token = request.getParameter("token");
        String groupId = request.getParameter("groupId");
        String url = request.getParameter("url");
        Gson gson = new Gson();
        ResultObj ro = new ResultObj("500", "操作失败", null);
        FaceInfoCrud fc = new FaceInfoCrud();
        
        if("delete".equals(Operation)) {
            String path = request.getServletContext().getRealPath("")+url;
            System.out.println(path);
            int isSuccess = fc.delete(tel);
            if(isSuccess == 1) {
                FileUtil.deletePic(path);
                Msg msg = GsonUtils.fromJson(FaceDelete.delete(tel,groupId,token), Msg.class);
                if(msg.error_code == 0) {
                    ro.setCode("200");
                    ro.setMsg("删除用户成功!");
                }else {
                    ro.setCode("500");
                    ro.setMsg("远程删除用户失败!");
                }
            }else {
                ro.setCode("500");
                ro.setMsg("本地删除用户失败!");
            }
        }else if("selectOne".equals(Operation)) {
            Map data = new HashMap<String, Object>();
            ArrayList<FaceAndGroup> list = fc.selectOne(tel);
            data.put("users", list);
            ro.setCode("200");
            ro.setMsg("查询所有用户成功!");
            ro.setObj(data);
        }else if("selectAll".equals(Operation)) {
            Map data = new HashMap<String, Object>();
            ArrayList<FaceAndGroup> list = fc.selectAll();
            data.put("users", list);
            ro.setCode("200");
            ro.setMsg("查询所有用户成功!");
            ro.setObj(data);
        }
        
        
        PrintWriter out = response.getWriter();
        out.print(gson.toJson(ro));
        out.close();
    }
    
}
 

四、登录统计模块

折线图的渲染:

1、前台发送登录统计请求;

2、后台统计某日期的6个时间段24小时的登录次数;

3、前台接收后台响应数据;

4、echarts根据响应数据渲染折线图,实现登录数据的可视化;

 

登录日志详情:

  1. 前台发送查询日志详情请求;
  2. 后台接收查询参数;
  3. 后台查询日志信息并返回到前台;

package com.face.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

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 com.face.opj.FaceAndGroup;
import com.face.opj.Groups;
import com.face.opj.Logs;
import com.face.opj.Msg;
import com.face.opj.ResultObj;
import com.face.service.AddGroup;
import com.face.service.DeleteGroup;
import com.face.service.FaceInfoCrud;
import com.face.service.GroupsInfoCrud;
import com.face.service.LoginInfoCrud;
import com.face.utils.FileUtil;
import com.face.utils.GsonUtils;
import com.google.gson.Gson;

@WebServlet("/LogsOperation")
public class LogsOperation extends HttpServlet {

    private static final long serialVersionUID = 1L;

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8;");
        String Operation = request.getParameter("Operation");
        String date = request.getParameter("date");
        String xiaoqu = request.getParameter("xiaoqu");
        Gson gson = new Gson();
        
        ResultObj ro = new ResultObj("500", "操作失败", null);
        
        LoginInfoCrud lc = new LoginInfoCrud();
        if("tongji".equals(Operation)) {
            Map m = lc.loginStatistics(date,xiaoqu);
            ro.setCode("200");
            ro.setMsg("统计成功!");
            ro.setObj(m);    
        }else if("add".equals(Operation)) {
            
        }else if("select".equals(Operation)) {
            Map m = new HashMap<String, Object>();
            ArrayList<Logs> list = lc.select(date,xiaoqu);
            m.put("logs", list);
            ro.setCode("200");
            ro.setMsg("统计成功!");
            ro.setObj(m);    
        }
        
        
        PrintWriter out = response.getWriter();
        out.print(gson.toJson(ro));
        out.close();
    }
    
}
 

 

五、数据备份模块

1、前台发送数据备份请求;

2、后台接收请求;

3、后台读取所有用户照片信息;

4、后台读取数据库人脸信息;

5、后台生成压缩包,并写入上述文件;

6、返回改压缩包url地址;

package com.face.servlet;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

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 com.face.utils.FileToZip;

@WebServlet("/BackUps")
public class BackUps extends HttpServlet {
    private static final long serialVersionUID = 1L;
       
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8;");
        
        String path = request.getServletContext().getRealPath("");
        System.out.println(request.getServletContext().getRealPath(""));
        
        Date date = new Date();
        String downloadFilePath = path+"backups/"+date.getTime()+".zip";
        String downoladDbPath = path+"backups/dbdata"+date.getTime()+".txt";
        String downloadAllPicPath = path+"photo/";
         
        List<File> allFile = new ArrayList<File>();
        allFile = FileToZip.getPics(downloadAllPicPath);
        allFile.add(FileToZip.getDbContent(downoladDbPath));
        
        File zipFile = new File(downloadFilePath);
        FileToZip.toZip(allFile, zipFile);
        
        PrintWriter out = response.getWriter();
        out.print("{\"url\":\""+"http://"+request.getHeader("host")+request.getContextPath()+"/backups/"+date.getTime()+".zip"+"\"}");
        out.close();
    }

}
 

 

需要完整代码可发邮件至[email protected]

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章