基於百度人臉識別的小區人臉門禁系統

又是一年畢業季,自己轉眼間也畢業一年了!!!前段時間幫學妹指導了一個小區人臉識別門禁系統,整個的實現思路在此記錄下,感興趣的可以參考一下。

整個項目溝通後情況如下:

需求功能:

  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]

 

 

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