web人脸识别(二)
现在做个入职员工人脸录入demo:
前端代码:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>信息录入</title> <meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1,user-scalable=no"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <script src="../js/face/jquery.min.js"></script> </head> <body> <div class="mui-content"> <div class="demo-frame"> <div class="demo-container"> <center><input type="button" title="开启摄像头" value="开启摄像头" onclick="getMedia()" /><button id="snap" onclick="takePhoto()" style="margin-left: 20px;">开始拍照</button></center> <br /> <video id="video" width="200" height="150" autoplay="autoplay"></video> <canvas id="canvas" width="200" height="150"></canvas> <div class="mui-input-group"> <div class="mui-input-row"> <label>姓名:</label> <input id="xm" type="text" class="mui-input-clear" placeholder="请输入姓名"> <button onclick="check()" style="margin-left: 10px;">查询</button> </div> <div class="mui-input-row"> 身份证:<input id="cardNo" type="text" class="mui-input-clear" placeholder="请输入身份证"> </div> <br /><br /> <div class="mui-input-row"> <center><button onclick="Submit()">提 交</button></center> </div> </div> </div> </div> </div> <script> //获得video摄像头区域 let video = document.getElementById("video"); // getMedia(); function getMedia() { let constraints = { video: { 200, height: 150 }, audio: true }; let promise = navigator.mediaDevices.getUserMedia(constraints); promise.then(function(MediaStream) { video.srcObject = MediaStream; video.play(); }).catch(function(PermissionDeniedError) { console.log(PermissionDeniedError); }) } function takePhoto() { //获得Canvas对象 let canvas = document.getElementById("canvas"); let ctx = canvas.getContext('2d'); ctx.drawImage(video, 0, 0, 110, 150); // ctx.drawImage(video, 0, 0, 200, 150); } function check() { var xm = $("#xm").val(); var dataJson = "{'xm' : '" + xm + "'}"; console.log("dataJson:" + dataJson); $.ajax({ url: 'http://192.168.11.60:81/ArcSoftFace.asmx/getEmployee', type: 'post', dataType: 'json', contentType: 'application/json;charset=utf-8', data: dataJson, success: function(data) { var msg = JSON.stringify(data); console.log("data:" + msg); // alert(msg); }, error: function(XMLHttpRequest, textStatus, errorThrown) { console.log("status:" + XMLHttpRequest.status); console.log("readyState:" + XMLHttpRequest.readyState); console.log("textStatus:" + textStatus); } }) } function Submit() { var dataJson = "{'base64Str' : '" + img.substr(img.indexOf(',') + 1) + "',}"; console.log("dataJson:" + dataJson); $.ajax({ url: 'http://192.168.11.60:81/ArcSoftFace.asmx/addFeture', type: 'post', dataType: 'json', contentType: 'application/json;charset=utf-8', data: dataJson, success: function(data) { var msg = JSON.stringify(data); alert(msg[0]); }, error: function(XMLHttpRequest, textStatus, errorThrown) { console.log("status:" + XMLHttpRequest.status); console.log("readyState:" + XMLHttpRequest.readyState); console.log("textStatus:" + textStatus); } }); } </script> </body> </html>
后端代码:
后端我这里用的是webServices,开放给前端JS 的 Ajax调用的时候记得在代码开头加:[System.Web.Script.Services.ScriptService] ,不然前端JS会一直显示跨域调用不了
#region 人脸特征录入 [WebMethod] public string addFeture(string xm, string idCard, string base64Str) { string msg = ""; msg = Add_Update_Feature(xm, base64Str, idCard);//获取人脸特征 return msg; } /// <summary> /// 添加、修改人脸特征 /// </summary> /// <param name="xm">姓名</param> /// <param name="base64Str">base64图片字符串</param> /// <param name="idCard">身份证</param> /// <returns></returns> private string Add_Update_Feature(string xm, string base64Str, string idCard) { string msg = ""; string url = Server.MapPath("PhotoTemp\"); string imgUrl = url + idCard + ".jpg";//以身份证号命名图片 byte[] imageBytes = Convert.FromBase64String(base64Str); //读入MemoryStream对象 MemoryStream memoryStream = new MemoryStream(imageBytes, 0, imageBytes.Length); memoryStream.Write(imageBytes, 0, imageBytes.Length); //转成图片 Image image = Image.FromStream(memoryStream); ASF_SingleFaceInfo singleFaceInfo = new ASF_SingleFaceInfo(); if (image == null) { msg = ""; } IntPtr intPtr_feature = FaceUtil.ExtractFeature(pImageEngine, image, out singleFaceInfo); ASF_FaceFeature asfFeature = MemoryUtil.PtrToStructure<ASF_FaceFeature>(intPtr_feature); byte[] feature = new byte[asfFeature.featureSize]; MemoryUtil.Copy(asfFeature.feature, feature, 0, asfFeature.featureSize); #region 保存人脸特征 string query_sql = string.Format("select * from Employee where IdCard='{0}'", idCard); DataTable query_dt = sqlHelper.ExecuteDataTable(query_sql); if (query_dt != null && query_dt.Rows.Count > 0) { //更新人脸特征 using (SqlConnection conn = new SqlConnection(connectionString)) { String sql = "update Employee set Feature=@feature where IdCard=@idCard"; SqlCommand cmd = new SqlCommand(sql, conn); cmd.Parameters.Add("@feature", DbType.Binary).Value = feature; cmd.Parameters.Add("@idCard", DbType.String).Value = idCard; conn.Open(); try { int update_count = cmd.ExecuteNonQuery(); if (update_count > 0) { msg = "更新成功"; } } catch (Exception ex) { msg = ex.Message; } } } else { //录入员工信息 using (SqlConnection conn = new SqlConnection(connectionString)) { String sql = "insert into Employee([Name],IdCard,Feature,FaceInfo,FaceImg) values(@name,@idCard,@feature,@faceInfo,@faceImg)"; SqlCommand cmd = new SqlCommand(sql, conn); cmd.Parameters.Add("@name", DbType.String).Value = xm; cmd.Parameters.Add("@idCard", DbType.String).Value = idCard; cmd.Parameters.Add("@feature", DbType.Binary).Value = feature; cmd.Parameters.Add("@faceInfo", DbType.String).Value = imgUrl; cmd.Parameters.Add("@faceImg", DbType.String).Value = "data:image/jpg;base64," + base64Str; conn.Open(); try { int add_count = cmd.ExecuteNonQuery(); if (add_count > 0) { msg = "新增成功"; } } catch (Exception ex) { msg = ex.Message; } } } #endregion #region 保存人脸图片 //图片名称 if (!Directory.Exists(url)) Directory.CreateDirectory(url); image.Save(imgUrl);// 将图片存到本地 #endregion if (image != null) { image.Dispose(); } return msg; } #endregion
注意点:人脸特征码数据库字段是Feature varbinary(Max) 其实不用Max的,因为当时做的时候不知道只有1032byte。
下期更新读取数据库的人脸特征码来识别人脸。