基于HTML5 的人脸识别活体认证的如何实现方法

如果这世上真有奇迹,那只是努力的另一个名字。人生从来没有真正的绝境。无论遭受多少艰辛,无论经历多少苦难,只要一个人的心中还怀着一粒信念的种子,那么总有一天,他就能走出困境,让生命重新开花结果。

近几年,人脸识别技术在身份认证领域的应用已经有了较多应用,例如:支付宝、招行的取款、养老金领取等方面,但在杜绝假冒、认证安全性等方面,目前还是一个比较需要进一步解决的课题,特别是在移动端的活体认证技术方面。

本文介绍了在HTML5 环境下可以采用clmtrackr.js 检测工具,结合人脸模型,实现人脸的跟踪检测。同时采用动作识别实现活体认证。

但本方案只能够在Firefox 或者Chrome中使用。并且只适合研究学习,实际场景中不太理想,需要进一步优化才能够应用。

如果有人有相关的技术,可以推荐介绍给我。

JavaScript Code复制内容到剪贴板
  1. <!DOCTYPEhtml>
  2. <!--
  3. Ideallytheseelementsaren'tcreateduntilit'sconfirmedthatthe
  4. clientsupportsvideo/camera,butforthesakeofillustratingthe
  5. elementsinvolved,theyarecreatedwithmarkup(notJavaScript)
  6. -->
  7. <html>
  8. <metacharset="GBK">
  9. <style>
  10. #container{
  11. position:relative;
  12. }
  13. #canvas{
  14. position:absolute;
  15. left:0;
  16. top:0;
  17. }
  18. </style>
  19. <scriptsrc="utils.js"></script>
  20. <scriptsrc="clmtrackr.js"></script>
  21. <scriptsrc="./models/model_pca_20_svm.js"></script>
  22. <scriptsrc="numeric.js"></script>
  23. <scriptsrc="ccv.js"></script>
  24. <audioid="media">
  25. 你的浏览器不支持audio标签。
  26. </audio>
  27. <divid="container">
  28. <videoid="video"width="600"height="400"autoplay>
  29. 您的浏览器不支持video标签
  30. </video>
  31. <canvasid="canvas"width="600"height="400"></canvas>
  32. </div>
  33. <buttonid="snap">SnapPhoto</button>
  34. <buttonid="start">Start</button>
  35. <buttonid="showposition">显示</button>
  36. <buttonid="hideposition">不显示</button>
  37. <br/>
  38. <buttonid="mouse">张嘴验证</button>
  39. <buttonid="head">摇头验证</button>
  40. <buttonid="eye">眨眼验证</button>
  41. <divid="tip">
  42. </div>
  43. <divid="result">
  44. </div>
  45. <divid="msg">
  46. </div>
  47. <divid="positions">
  48. </div>
  49. <script>
  50. varshowpos=false;
  51. //Puteventlistenersintoplace
  52. //window.addEventListener("DOMContentLoaded",function(){
  53. //Grabelements,createsettings,etc.
  54. varcanvas=document.getElementById("canvas"),
  55. context=canvas.getContext("2d"),
  56. video=document.getElementById("video"),
  57. videoObj={"video":true},
  58. errBack=function(error){
  59. if(error.PERMISSION_DENIED){
  60. jAlert('用户拒绝了浏览器请求媒体的权限','提示');
  61. }elseif(error.NOT_SUPPORTED_ERROR){
  62. jAlert('对不起,您的浏览器不支持拍照功能,请使用其他浏览器','提示');
  63. }elseif(error.MANDATORY_UNSATISFIED_ERROR){
  64. jAlert('指定的媒体类型未接收到媒体流','提示');
  65. }else{
  66. jAlert('系统未能获取到摄像头,请确保摄像头已正确安装。或尝试刷新页面,重试','提示');
  67. }
  68. };
  69. //Putvideolistenersintoplace
  70. if(navigator.getUserMedia){//Standard
  71. navigator.getUserMedia(videoObj,function(stream){
  72. video.src=stream;
  73. video.play();
  74. },errBack);
  75. }elseif(navigator.webkitGetUserMedia){//WebKit-prefixed
  76. try{
  77. navigator.webkitGetUserMedia(videoObj,function(stream){
  78. video.src=window.webkitURL.createObjectURL(stream);
  79. video.play();
  80. },errBack);
  81. }catch(error){
  82. alert(error);
  83. }
  84. }
  85. elseif(navigator.mozGetUserMedia){//Firefox-prefixed
  86. navigator.mozGetUserMedia(videoObj,function(stream){
  87. video.src=window.URL.createObjectURL(stream);
  88. video.play();
  89. },errBack);
  90. }
  91. //Triggerphototake
  92. document.getElementById("snap").addEventListener("click",function(){
  93. context.drawImage(video,0,0,600,400);
  94. });
  95. document.getElementById("start").addEventListener("click",function(){
  96. startTrack();
  97. });
  98. document.getElementById("showposition").addEventListener("click",function(){
  99. showpos=true;
  100. });
  101. document.getElementById("hideposition").addEventListener("click",function(){
  102. showpos=false;
  103. });
  104. document.getElementById("mouse").addEventListener("click",function(){
  105. alive_mouse();
  106. });
  107. document.getElementById("head").addEventListener("click",function(){
  108. alive_head();
  109. });
  110. document.getElementById("eye").addEventListener("click",function(){
  111. alive_eye();
  112. });
  113. //},false);
  114. </script>
  115. <script>
  116. //////////////////////////////////////////////////////////////////////////////
  117. //活体
  118. varlast_time=0;//时间因素
  119. varlast_nose_left=0;
  120. varlast_nose_top=0;
  121. //张嘴动作
  122. varis_mouse_ok=false;
  123. varis_alive_mouse=false;
  124. varlast_dis_eye_norse=0;
  125. varlast_dis_mouse=0;
  126. functionalive_mouse(){
  127. varmedia=document.getElementById("media");
  128. media.src="mp3/alive_mouse.mp3";
  129. media.play();
  130. document.getElementById("tip").innerHTML="请张合嘴巴";
  131. document.getElementById('result').innerHTML="";
  132. is_mouse_ok=false;
  133. last_dis_mouse=0;
  134. last_time=0;
  135. last_dis_eye_norse=100000000;
  136. is_alive_head=false;
  137. is_alive_mouse=true;
  138. is_alive_eye=false;
  139. }
  140. //摇头动作
  141. varis_head_ok=false;
  142. varis_alive_head=false;
  143. varlast_dis_left_right=100000000;
  144. functionalive_head(){
  145. varmedia=document.getElementById("media");
  146. media.src="mp3/alive_head.mp3";
  147. media.play();
  148. document.getElementById("tip").innerHTML="请在水平方向左右摇头";
  149. document.getElementById('result').innerHTML="";
  150. is_head_ok=false;
  151. last_dis_left_right=100000000;
  152. last_time=0;
  153. is_alive_head=true;
  154. is_alive_mouse=false;
  155. is_alive_eye=false;
  156. }
  157. //眨眼动作
  158. varis_alive_eye=false;
  159. varis_eye_ok=false;
  160. functionalive_eye(){
  161. varmedia=document.getElementById("media");
  162. media.src="mp3/alive_eye.mp3";
  163. media.play();
  164. document.getElementById("tip").innerHTML="请眨眼";
  165. document.getElementById('result').innerHTML="";
  166. is_eye_ok=false;
  167. last_dis_eye_norse=100000000;
  168. last_nose_left=0;
  169. last_nose_top=0;
  170. last_time=0;
  171. is_alive_head=false;
  172. is_alive_mouse=false;
  173. is_alive_eye=true;
  174. }
  175. functionstartTrack(){
  176. varvideoInput=document.getElementById('video');
  177. varctracker=newclm.tracker();
  178. ctracker.init(pModel);
  179. ctracker.start(videoInput);
  180. varcanvasInput=document.getElementById('canvas');
  181. varcc=canvasInput.getContext('2d');
  182. cc.lineWidth=3;
  183. functiondrawLoop(){
  184. //requestAnimationFrame(drawLoop);
  185. cc.clearRect(0,0,canvasInput.width,canvasInput.height);
  186. //ctracker.draw(canvasInput);
  187. varpositions=ctracker.getCurrentPosition();
  188. if(showpos&&positions){
  189. for(varp=0;p<positions.length;p++){
  190. positionString+="featurepoint"+p+":["+positions[p][0].toFixed(2)+","+positions[p][1].toFixed(2)+"]<br/>";
  191. }
  192. document.getElementById('positions').innerHTML=positionString;
  193. }
  194. if(positions){
  195. for(varp=0;p<71;p++){
  196. cc.beginPath();
  197. cc.arc(positions[p][0].toFixed(2),positions[p][1].toFixed(2),2,0,Math.PI*2,true);
  198. cc.closePath();
  199. cc.fillStyle='#00FF00';
  200. cc.fill();
  201. }
  202. //cc.strokeStyle='red';
  203. //0-14轮廓
  204. //7下吧,最下
  205. //2最左边
  206. //12最右边
  207. //15-22眉毛
  208. //23-27左眼睛五个点
  209. //27左眼中间
  210. //63-66左眼四个点
  211. //28-32右眼睛五个点
  212. //67-70右眼四个点
  213. //33-43鼻子
  214. //62鼻中间
  215. //44-61嘴巴
  216. //47嘴巴上
  217. //53嘴巴下
  218. ///////////////////////////////////////////////////////////////////////////////////////////////
  219. //左眼中间
  220. for(varp=27;p<=27;p++){
  221. cc.beginPath();
  222. cc.arc(positions[p][0].toFixed(2),positions[p][1].toFixed(2),2,0,Math.PI*2,true);
  223. cc.closePath();
  224. cc.fillStyle='red';
  225. cc.fill();
  226. }
  227. //鼻子中间
  228. for(varp=62;p<=62;p++){
  229. cc.beginPath();
  230. cc.arc(positions[p][0].toFixed(2),positions[p][1].toFixed(2),2,0,Math.PI*2,true);
  231. cc.closePath();
  232. cc.fillStyle='red';
  233. cc.fill();
  234. }
  235. //嘴巴上
  236. for(varp=57;p<=57;p++){
  237. cc.beginPath();
  238. cc.arc(positions[p][0].toFixed(2),positions[p][1].toFixed(2),2,0,Math.PI*2,true);
  239. cc.closePath();
  240. cc.fillStyle='red';
  241. cc.fill();
  242. }
  243. //嘴巴下
  244. for(varp=60;p<=60;p++){
  245. cc.beginPath();
  246. cc.arc(positions[p][0].toFixed(2),positions[p][1].toFixed(2),2,0,Math.PI*2,true);
  247. cc.closePath();
  248. cc.fillStyle='red';
  249. cc.fill();
  250. }
  251. //////////////////////////////////////
  252. //head
  253. if(is_alive_head==true){
  254. if(last_time==0||(newDate().getTime()-last_time>500&&newDate().getTime()-last_time<10000)){
  255. varxdiff_left=positions[62][0]-positions[2][0];
  256. varydiff_left=positions[62][1]-positions[2][1];
  257. vardis_left=Math.pow((xdiff_left*xdiff_left+ydiff_left*ydiff_left),0.5);
  258. varxdiff_right=positions[12][0]-positions[62][0];
  259. varydiff_right=positions[12][1]-positions[62][1];
  260. vardis_right=Math.pow((xdiff_right*xdiff_right+ydiff_right*ydiff_right),0.5);
  261. varxdiff_side=positions[12][0]-positions[2][0];
  262. varydiff_side=positions[12][1]-positions[2][1];
  263. vardis_side=Math.pow((xdiff_side*xdiff_side+ydiff_side*ydiff_side),0.5);
  264. vardis_left_right=dis_left-dis_right;
  265. document.getElementById('result').innerHTML=dis_left_right;
  266. if(last_dis_left_right>0&&dis_left_right>dis_side/3){
  267. document.getElementById('result').innerHTML="通过";
  268. is_head_ok=true;
  269. is_alive_head=false;
  270. }
  271. last_dis_left_right=dis_left_right;
  272. last_time=newDate().getTime();
  273. }
  274. }
  275. /////////////////////////////////////
  276. //mouse
  277. if(is_alive_mouse==true){
  278. if(last_time==0||(newDate().getTime()-last_time>500&&newDate().getTime()-last_time<10000)){
  279. //研究和鼻子距离
  280. varxdiff=positions[62][0]-positions[27][0];
  281. varydiff=positions[62][1]-positions[27][1];
  282. vardis_eye_norse=Math.pow((xdiff*xdiff+ydiff*ydiff),0.5);
  283. //上嘴唇和下嘴唇距离
  284. varxdiff_mouse=positions[53][0]-positions[47][0];
  285. varydiff_mouse=positions[53][1]-positions[47][1];
  286. vardis_mouse=Math.pow((xdiff_mouse*xdiff_mouse+ydiff_mouse*ydiff_mouse),0.5);
  287. //上次的眼鼻距离和这次的眼鼻距离差
  288. vardn=Math.abs(dis_eye_norse-last_dis_eye_norse);
  289. //上次的嘴距离和本次的嘴距离差
  290. vardm=Math.abs(dis_mouse-last_dis_mouse);
  291. //鼻子的位置确保变化不大
  292. if(last_nose_left>0&&last_nose_top>0
  293. &&Math.abs(positions[62][0]-last_nose_left)<5
  294. &&Math.abs(positions[62][1]-last_nose_top)<5
  295. ){
  296. document.getElementById('msg').innerHTML=dn;
  297. if(last_dis_eye_norse>0&&dn<dis_eye_norse*1/50){
  298. if(last_dis_mouse>0&&dm>dis_mouse/10){
  299. document.getElementById('result').innerHTML="通过";
  300. is_alive_mouse=false;
  301. is_mouse_ok=true;
  302. }
  303. }
  304. }
  305. last_dis_mouse=dis_mouse;
  306. last_dis_eye_norse=dis_eye_norse;
  307. last_time=newDate().getTime();
  308. last_nose_left=positions[62][0];
  309. last_nose_top=positions[62][1];
  310. }
  311. }
  312. /////////////////////////////////////
  313. //eye
  314. if(is_alive_eye==true){
  315. if(last_time==0||(newDate().getTime()-last_time>10)){
  316. varxdiff1=positions[62][0]-positions[27][0];
  317. varydiff1=positions[62][1]-positions[27][1];
  318. vardis_eye_norse1=Math.pow((xdiff1*xdiff1+ydiff1*ydiff1),0.5);
  319. varxdiff2=positions[62][0]-positions[32][0];
  320. varydiff2=positions[62][1]-positions[32][1];
  321. vardis_eye_norse2=Math.pow((xdiff2*xdiff2+ydiff2*ydiff2),0.5);
  322. vardis_eye_norse=(dis_eye_norse1+dis_eye_norse2);
  323. if(last_nose_left>0&&last_nose_top>0
  324. &&Math.abs(positions[62][0]-last_nose_left)<0.5
  325. &&Math.abs(positions[62][1]-last_nose_top)<0.5
  326. ){
  327. document.getElementById('msg').innerHTML=Math.abs(dis_eye_norse-last_dis_eye_norse)-dis_eye_norse*1/20;
  328. if(last_dis_eye_norse>0&&(Math.abs(dis_eye_norse-last_dis_eye_norse)>dis_eye_norse*1/20)){
  329. document.getElementById('result').innerHTML="通过";
  330. is_alive_eye=false;
  331. is_eye_ok=true;
  332. }
  333. }
  334. last_nose_left=positions[62][0];
  335. last_nose_top=positions[62][1];
  336. last_dis_eye_norse=dis_eye_norse;
  337. last_time=newDate().getTime();
  338. }
  339. }
  340. }
  341. requestAnimationFrame(drawLoop);
  342. }
  343. drawLoop();
  344. }
  345. </script>
  346. </html>

以上就是小编为大家带来的基于HTML5 的人脸识别活体认证的实现方法全部内容了,希望大家多多支持~

原文地址:http://www.cnblogs.com/lilies/archive/2016/06/21/5604212.html

您可能有感兴趣的文章
HTML5之高度塌陷问题的如何解决

html5笛卡尔心形曲线的如何实现

如何使用feDisplacementMap+feImage滤镜如何实现水波纹效果(计算动态值)

如何使用canvas对video视频某一刻截图功能

Canvas如何做个雪花屏版404的如何实现