原理比较简单: 1.利用au3抓取摄像头并拍照,存储在本地。 2.利用au3的post功能将本地照片以base64编码方式上传php服务器。3.php端根据接收到的图片编码,调用百度AI开放平台进行人脸识别。
一些准备工作:
1.1需要自行搭建本地php服务器(假设ip地址为192.168.1.30),可以网上下载phpstudy进行一键安装
1.2下载百度AI人脸识别php包(https://ai.baidu.com/sdk#bfr)
1.3将php包放入新建的aiface文件夹内,将index_au3.php文件放入aiface文件夹
1.4将aiface文件夹放入PHP服务器的web根目录
2.1需要申请注册百度开发者账号(https://login.bce.baidu.com)
2.2选择人脸识别–应用列表–创建应用–(获得AppID API Key Secret Key)
2.3创建后选择该应用进入后–新建用户组:free_face ,本例的用户组名为free_face
2.4修改index_au3.php文件内的AppID API Key Secret Key配置信息
[code]const APP_ID = ‘15462718’;//你的 App ID
const API_KEY = ‘W7Pr4cjQdYLRzsEntHeBFXF4’;//你的 Api Key
const SECRET_KEY = ‘GLh84ZjMczUtaeoDEvS93dpDzSQQzxrp’;//你的 Secret Key[/code]
camera.au3
$WM_CAP_START = 0x400$WM_CAP_UNICODE_START = $WM_CAP_START +100$WM_CAP_PAL_SAVEA = $WM_CAP_START + 81$WM_CAP_PAL_SAVEW = $WM_CAP_UNICODE_START + 81$WM_CAP_UNICODE_END = $WM_CAP_PAL_SAVEW$WM_CAP_ABORT = $WM_CAP_START + 69$WM_CAP_DLG_VIDEOCOMPRESSION = $WM_CAP_START + 46$WM_CAP_DLG_VIDEODISPLAY = $WM_CAP_START + 43$WM_CAP_DLG_VIDEOFORMAT = $WM_CAP_START + 41$WM_CAP_DLG_VIDEOSOURCE = $WM_CAP_START + 42$WM_CAP_DRIVER_CONNECT = $WM_CAP_START + 10$WM_CAP_DRIVER_DISCONNECT = $WM_CAP_START + 11$WM_CAP_DRIVER_GET_CAPS = $WM_CAP_START + 14$WM_CAP_DRIVER_GET_NAMEA = $WM_CAP_START + 12$WM_CAP_DRIVER_GET_NAMEW = $WM_CAP_UNICODE_START + 12$WM_CAP_DRIVER_GET_VERSIONA = $WM_CAP_START + 13$WM_CAP_DRIVER_GET_VERSIONW = $WM_CAP_UNICODE_START + 13$WM_CAP_EDIT_COPY = $WM_CAP_START + 30$WM_CAP_END = $WM_CAP_UNICODE_END$WM_CAP_FILE_ALLOCATE = $WM_CAP_START + 22$WM_CAP_FILE_GET_CAPTURE_FILEA = $WM_CAP_START + 21$WM_CAP_FILE_GET_CAPTURE_FILEW = $WM_CAP_UNICODE_START + 21$WM_CAP_FILE_SAVEASA = $WM_CAP_START + 23$WM_CAP_FILE_SAVEASW = $WM_CAP_UNICODE_START + 23$WM_CAP_FILE_SAVEDIBA = $WM_CAP_START + 25$WM_CAP_FILE_SAVEDIBW = $WM_CAP_UNICODE_START + 25$WM_CAP_FILE_SET_CAPTURE_FILEA = $WM_CAP_START + 20$WM_CAP_FILE_SET_CAPTURE_FILEW = $WM_CAP_UNICODE_START + 20$WM_CAP_FILE_SET_INFOCHUNK = $WM_CAP_START + 24$WM_CAP_GET_AUDIOFORMAT = $WM_CAP_START + 36$WM_CAP_GET_CAPSTREAMPTR = $WM_CAP_START + 1$WM_CAP_GET_MCI_DEVICEA = $WM_CAP_START + 67$WM_CAP_GET_MCI_DEVICEW = $WM_CAP_UNICODE_START + 67$WM_CAP_GET_SEQUENCE_SETUP = $WM_CAP_START + 65$WM_CAP_GET_STATUS = $WM_CAP_START + 54$WM_CAP_GET_USER_DATA = $WM_CAP_START + 8$WM_CAP_GET_VIDEOFORMAT = $WM_CAP_START + 44$WM_CAP_GRAB_FRAME = $WM_CAP_START + 60$WM_CAP_GRAB_FRAME_NOSTOP = $WM_CAP_START + 61$WM_CAP_PAL_AUTOCREATE = $WM_CAP_START + 83$WM_CAP_PAL_MANUALCREATE = $WM_CAP_START + 84$WM_CAP_PAL_OPENA = $WM_CAP_START + 80$WM_CAP_PAL_OPENW = $WM_CAP_UNICODE_START + 80$WM_CAP_PAL_PASTE = $WM_CAP_START + 82$WM_CAP_SEQUENCE = $WM_CAP_START + 62$WM_CAP_SEQUENCE_NOFILE = $WM_CAP_START + 63$WM_CAP_SET_AUDIOFORMAT = $WM_CAP_START + 35$WM_CAP_SET_CALLBACK_CAPCONTROL = $WM_CAP_START + 85$WM_CAP_SET_CALLBACK_ERRORA = $WM_CAP_START + 2$WM_CAP_SET_CALLBACK_ERRORW = $WM_CAP_UNICODE_START + 2$WM_CAP_SET_CALLBACK_FRAME = $WM_CAP_START + 5$WM_CAP_SET_CALLBACK_STATUSA = $WM_CAP_START + 3$WM_CAP_SET_CALLBACK_STATUSW = $WM_CAP_UNICODE_START + 3$WM_CAP_SET_CALLBACK_VIDEOSTREAM = $WM_CAP_START + 6$WM_CAP_SET_CALLBACK_WAVESTREAM = $WM_CAP_START + 7$WM_CAP_SET_CALLBACK_YIELD = $WM_CAP_START + 4$WM_CAP_SET_MCI_DEVICEA = $WM_CAP_START + 66$WM_CAP_SET_MCI_DEVICEW = $WM_CAP_UNICODE_START + 66$WM_CAP_SET_OVERLAY = $WM_CAP_START + 51$WM_CAP_SET_PREVIEW = $WM_CAP_START + 50$WM_CAP_SET_PREVIEWRATE = $WM_CAP_START + 52$WM_CAP_SET_SCALE = $WM_CAP_START + 53$WM_CAP_SET_SCROLL = $WM_CAP_START + 55$WM_CAP_SET_SEQUENCE_SETUP = $WM_CAP_START + 64$WM_CAP_SET_USER_DATA = $WM_CAP_START + 9$WM_CAP_SET_VIDEOFORMAT = $WM_CAP_START + 45$WM_CAP_SINGLE_FRAME = $WM_CAP_START + 72$WM_CAP_SINGLE_FRAME_CLOSE = $WM_CAP_START + 71$WM_CAP_SINGLE_FRAME_OPEN = $WM_CAP_START + 70$WM_CAP_STOP = $WM_CAP_START + 68<h1>include <GUIConstants.au3></h1><h1>include <WindowsConstants.au3></h1><h1>include <MsgBoxConstants.au3></h1>$avi = DllOpen("avicap32.dll")$user = DllOpen("user32.dll")$snapfile = @ScriptDir & "\scrshot.bmp"$Main = GUICreate("Camera",450,270)$take_photo = GUICtrlCreateButton("拍摄照片", 340, 42, 90, 50)GUICtrlSetFont($take_photo, 11, "", "", "") ;font size$close_photo = GUICtrlCreateButton("关闭", 340, 100, 90, 50)GUICtrlSetFont($take_photo, 11, "", "", "") ;font size$cap = DllCall($avi, "int", "capCreateCaptureWindow", "str", "cap", "int", BitOR($WS_CHILD,$WS_VISIBLE), "int", 15, "int", 15, "int", 320, "int", 240, "hwnd", $Main, "int", 1)DllCall($user, "int", "SendMessage", "hWnd", $cap[0], "int", $WM_CAP_DRIVER_CONNECT, "int", 0, "int", 0)DllCall($user, "int", "SendMessage", "hWnd", $cap[0], "int", $WM_CAP_SET_SCALE, "int", 1, "int", 0)DllCall($user, "int", "SendMessage", "hWnd", $cap[0], "int", $WM_CAP_SET_OVERLAY, "int", 1, "int", 0)DllCall($user, "int", "SendMessage", "hWnd", $cap[0], "int", $WM_CAP_SET_PREVIEW, "int", 1, "int", 0)DllCall($user, "int", "SendMessage", "hWnd", $cap[0], "int", $WM_CAP_SET_PREVIEWRATE, "int", 1, "int", 0)GUISetState(@SW_SHOW)HotKeySet("{INSERT}", "SnapShot"); 按Insert键截图While 1$msg = GUIGetMsg()If $msg = $GUI_EVENT_CLOSE Then;DllCall($user, "int", "SendMessage", "hWnd", $cap[0], "int", $WM_CAP_SET_CALLBACK_FRAME, "int", 0, "int", 0)DllCall($user, "int", "SendMessage", "hWnd", $cap[0], "int", $WM_CAP_END, "int", 0, "int", 0)DllCall($user, "int", "SendMessage", "hWnd", $cap[0], "int", $WM_CAP_DRIVER_DISCONNECT, "int", 0, "int", 0);DllClose($avi)DllClose($user)ExitEndIf<pre><code> SelectCase $msg = $take_photoSnapShot()If FileExists($snapfile) Then</code></pre>;FileDelete("c:\a.txt");MsgBox(0, "成功", "截图成功!");==================base64编码$objStream = ObjCreate("ADODB.Stream")$objStream.Type = 1$objStream.Open$objStream.LoadFromFile($snapfile)$objXMLDoc = ObjCreate("Msxml2.DOMDocument")$objDocElem = $objXMLDoc.CreateElement("base64")$objDocElem.dataType = "bin.base64"$objDocElem.nodeTypedValue = $objStream.Read$sBase64String = $objDocElem.text$objStream.Close;$fRead ='data:image/bmp;base64,'&$sBase64String$fRead =$sBase64String;============以下是发送post数据,并检测登录是否成功================;$LoginPage = 'http://192.168.1.30/aiface/index.php'$PostPage = 'http://192.168.1.30/aiface/index_au3.php'Global $xmlhttp, $sValue$xmlhttp = ObjCreate("MSXML2.XMLHTTP.3.0");$xmlhttp.open("GET", $LoginPage, False);$xmlhttp.send();$sValue = BinaryToString($xmlhttp.responseBody, 4);$Formhash = StringRegExp($sValue, 'name="formhash" value="(.*?)\"', 3)If @error = 0 Then$xmlhttp.open("POST", $PostPage, False)$xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');$xmlhttp.send('loginfield=username&username=' & $UserName & '&password=' & $password & '&questionid=0&answer='); $xmlhttp.send('file=' & $fRead )$xmlhttp.send('file=' & $fRead )$sValue = BinaryToString($xmlhttp.responseBody, 4); If StringInStr($sValue, '1') ThenMsgBox(0, "", $sValue); Else; MsgBox(0, "", "登录失败!"); EndIfEndIf$xmlhttp.abort()ElseEndIf<pre><code> EndSelectSleep(1)</code></pre>WendFunc SnapShot()DllCall($user, "int", "SendMessage", "hWnd", $cap[0], "int", $WM_CAP_GRAB_FRAME_NOSTOP, "int", 0, "int", 0)DllCall($user, "int", "SendMessage", "hWnd", $cap[0], "int", $WM_CAP_FILE_SAVEDIBA, "int", 0, "str", $snapfile)EndFunc
index_au3.php
<?php//index_au3.phpheader("Content-type:text/html;charset=utf-8");const APP_ID = '15452718';//你的 App IDconst API_KEY = 'W7Pr4cjQdYLRzsEntHeBFXF4';//你的 Api Keyconst SECRET_KEY = 'GLh84ZjMczUtaeoDEvS93dpDzSQQzxrp';//你的 Secret Keyif(isset($_POST['file'])){// echo $_POST['file'];echo aiface_reg($_POST['file']);}?><?phpfunction aiface_reg($img_base64,$imageType='BASE64',$groupId='free_face',$score='85'){// 根据图片地址 及相似度评分,返回该图片在 用户组的 useridrequire('AipFace.php');// 你的 APPID AK SK https://ai.baidu.com/docs#/Face-PHP-SDK/top$client = new AipFace(APP_ID, API_KEY, SECRET_KEY);$img_dir='';//这里不用进行转码//第一步,对图片进行编码/*$base64_image = '';$image_info = getimagesize($img_dir);$image_data = fread(fopen($img_dir, 'r'), filesize($img_dir));$base64_image = chunk_split(base64_encode($image_data));$image = preg_replace('/\r|\n/', '', $base64_image);// 一定要用正则式把换行去掉,百度不支持换行 此处是base64编码的字符串*/$image=$img_base64;//直接赋值base64编码//第二步,检测图片是否是人脸// [1]调用人脸检测//$client->detect(base64EncodeImage($image), $imageType);// [2]如果有可选参数$options = array();$options["face_field"] = "age";$options["max_face_num"] = 1;$options["face_type"] = "LIVE";// 带参数调用人脸检测$res = $client->detect($image, $imageType, $options);// Array ( [error_code] => 0 [error_msg] => SUCCESS [log_id] => 3.045692791634E+17 [timestamp] => 1547916339 [cached] => 0 [result] => Array ( [face_num] => 1 [face_list] => Array ( [0] => Array ( [face_token] => 34f3873bbe3548e80c73d8bcdd0f6055 [location] => Array ( [left] => 155.68 [top] => 157.22 [width] => 193 [height] => 183 [rotation] => 0 ) [face_probability] => 1 [angle] => Array ( [yaw] => -8.48 [pitch] => 4.46 [roll] => -0.22 ) [age] => 26 ) ) ) )//$dat=json_decode($res,true);/*$dat =$res;echo $dat['error_msg'];echo '<br>';echo $dat['result']['face_list'][0]['face_probability'];//人脸置信度,范围【0~1】,代表这是一张人脸的概率,0最小、1最大。echo '<br>';echo $dat['result']['face_list'][0]['face_token'];echo '<br>';echo $dat['result']['face_list'][0]['age'];echo '<br>---------------<br>';*///马化腾的 face_token=34f3873bbe3548e80c73d8bcdd0f6055// 马化腾1的 face_token=77d98a34dccd5a9734ee50c24e72fea5if($res['error_msg']<>'SUCCESS'){$result=array('code' => 0,'msg' => 'no face 未检测到人脸','data' => 'error');echo json_encode($result);die;}//第三步, 判断人脸库是否存在该人,不存在则创建//人脸库//$imageType = "BASE64";$groupIdList =$groupId;// 只用一个组// 调用人脸搜索$res2=$client->search($image, $imageType, $groupIdList);/*// 如果有可选参数$options = array();$options["quality_control"] = "NONE";//图片质量控制 NONE: 不进行控制 LOW:较低的质量要求 NORMAL: 一般的质量要求 HIGH: 较高的质量要求 默认 NONE$options["liveness_control"] = "NONE";//活体检测控制 NONE: 不进行控制 LOW:较低的活体要求(高通过率 低攻击拒绝率) NORMAL: 一般的活体要求(平衡的攻击拒绝率, 通过率) HIGH: 较高的活体要求(高攻击拒绝率 低通过率) 默认NONE$options["user_id"] = "233451";//当需要对特定用户进行比对时,指定user_id进行比对。即人脸认证功能。$options["max_user_num"] = 3;//查找后返回的用户数量。返回相似度最高的几个用户,默认为1,最多返回20个。// 带参数调用人脸搜索$client->search($image, $imageType, $groupIdList, $options);*///var_dump($res2);//array(6) { ["error_code"]=> int(222207) ["error_msg"]=> string(23) "match user is not found" ["log_id"]=> float(3.0459287972622E+17) ["timestamp"]=> int(1547972622) ["cached"]=> int(0) ["result"]=> NULL }//array(6) { ["error_code"]=> int(0) ["error_msg"]=> string(7) "SUCCESS" ["log_id"]=> float(3.0548687972859E+17) ["timestamp"]=> int(1547972859) ["cached"]=> int(0) ["result"]=> array(2) { ["face_token"]=> string(32) "34f3873bbe3548e80c73d8bcdd0f6055" ["user_list"]=> array(1) { [0]=> array(4) { ["group_id"]=> string(9) "free_face" ["user_id"]=> string(15) "201901201624_ma" ["user_info"]=> string(0) "" ["score"]=> int(100) } } } }/*echo $res2['error_msg'];echo '<br>';echo $res2['result']['face_token'];echo '<br>';echo $res2['result']['user_list'][0]['group_id'];echo '<br>';echo $res2['result']['user_list'][0]['user_id'];echo '<br>';echo '得分:'.$res2['result']['user_list'][0]['score'];// 只要图库存在图片都会返回成功,利用得分判断是否同一人*/$score=$res2['result']['user_list'][0]['score'];if($res2['error_msg']=='SUCCESS' && $res2['result']['user_list'][0]['score']>88){$result=array('code' => 1,'msg' => 'face exists 人脸库已存在','data' => $res2['result']['user_list'][0]['user_id'],'score' => $score);echo json_encode($result);die;//die('匹配到人脸数据库,任务结束');}//第四步,执行新增//$image = "取决于image_type参数,传入BASE64字符串或URL字符串或FACE_TOKEN字符串";$userId = date("YmdHis").'_la';//echo '<br>'.$userId.'<br>';// 调用人脸注册$res3=$client->addUser($image, $imageType, $groupId, $userId);/*// 如果有可选参数$options = array();$options["user_info"] = "user's info";$options["quality_control"] = "NORMAL";$options["liveness_control"] = "LOW";// 带参数调用人脸注册$client->addUser($image, $imageType, $groupId, $userId, $options);*///var_dump($res3);//array(6) { ["error_code"]=> int(222018) ["error_msg"]=> string(27) "param[user_id] format error" ["log_id"]=> float(3.0459287975839E+17) ["timestamp"]=> int(1547975838) ["cached"]=> int(0) ["result"]=> NULL }//array(6) { ["error_code"]=> int(0) ["error_msg"]=> string(7) "SUCCESS" ["log_id"]=> float(3.0456927976109E+17) ["timestamp"]=> int(1547976108) ["cached"]=> int(0) ["result"]=> array(2) { ["face_token"]=> string(32) "d364574400ab59b7f13d87941d6b90e6" ["location"]=> array(5) { ["left"]=> float(222.6) ["top"]=> float(121.96) ["width"]=> int(137) ["height"]=> int(112) ["rotation"]=> int(-2) } } }/*echo $res3['error_msg'];echo '<br>';echo $res3['result']['face_token'];echo '<br>';*/if($res3['error_msg']=='SUCCESS'){$result=array('code' => 2,'msg' => 'register successed 已添加到人脸库','data' => $userId,'score' => $score);echo json_encode($result);}else{$result=array('code' => 3,'msg' => 'register failed 添加人脸库失败','data' => 'error');echo json_encode($result);}}//函数结束?>
index_au3.php 返回的是json信息(json里面的score是招牌与人脸库里对比最接近的得分,分数越高越表名是同一个人!分数太低可能导致不同的人被识别成同一个人,我用的是88分以上为同一人)
发表评论