Baidu.php 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. <?php
  2. namespace app\expand\controller;
  3. use app\common\service\HelperService;
  4. use think\Cache;
  5. use think\Validate;
  6. /**
  7. * 百度相关接口
  8. * Class Baidu
  9. * @package app\expand\controller
  10. */
  11. class Baidu extends BaseAuth
  12. {
  13. private $_baseUrl = 'https://aip.baidubce.com';
  14. private $_baiDuAccount = null;
  15. public function __construct(){
  16. parent::__construct();
  17. $this->_baiDuAccount = $this->getKey($this->_apiCode);
  18. //验证是否具有访问这个接口的权限
  19. if(!isset($this->_baiDuAccount['baiDu_face_key'])
  20. || !isset($this->_baiDuAccount['baiDu_face_secret'])){
  21. HelperService::returnJson(['code'=>400,'msg'=>'baidu interface unauthorized access','data'=>[]]);
  22. }
  23. }
  24. /**
  25. * 获取百度人脸识别的token并且缓存一个月
  26. * @param bool $force
  27. * @return mixed
  28. */
  29. private function getBaiduToken($force=false){
  30. $key = $this->_baiDuAccount['baiDu_face_key'];
  31. $secret = $this->_baiDuAccount['baiDu_face_secret'];
  32. $baiDuKey = Cache::get("baiDuKey_$key");
  33. if(!empty($baiDuKey) && $force==false){
  34. return $baiDuKey;
  35. }
  36. $url = $this->_baseUrl."/oauth/2.0/token?grant_type=client_credentials&client_id=$key&client_secret=$secret&";
  37. $res = HelperService::httpPost($url,'',true);
  38. $resultArr = @json_decode($res,true);
  39. if(isset($resultArr['error'])){
  40. HelperService::returnJson([
  41. 'code'=>400,
  42. 'msg'=>"baidu err msg",
  43. 'data'=>$res
  44. ]);
  45. }
  46. Cache::set("baiDuKey_$key",$resultArr['access_token'],$resultArr['expires_in']);
  47. return $resultArr['access_token'];
  48. }
  49. /**
  50. * 请求百度人脸识别匹配人脸接口
  51. */
  52. public function match(){
  53. $params = $this->_params;
  54. $rule = [
  55. 'old_image|原始图片'=>'require',
  56. 'old_image_type|原始图片类型'=>'require',
  57. 'now_image|现在的图片'=>'require',
  58. 'now_image_type|现在的图片类型'=>'require',
  59. ];
  60. $validate = new Validate($rule);
  61. if(!$validate->check($params)){
  62. HelperService::returnJson(['code'=>400,'msg'=>$validate->getError(),'data'=>$params]);
  63. }
  64. $imageType = ['URL','FACE_TOKEN','BASE64'];
  65. if(!in_array($params['old_image_type'],$imageType)
  66. || !in_array($params['now_image_type'],$imageType)){
  67. HelperService::returnJson(['code'=>400,'msg'=>'image_type value is error','data'=>[]]);
  68. }
  69. $matchImage = [
  70. [
  71. 'image'=>"{$params['old_image']}",
  72. 'image_type'=>"{$params['old_image_type']}",
  73. "face_type"=>"LIVE",
  74. "quality_control"=>"NORMAL",
  75. "liveness_control"=>"NORMAL"
  76. ],[
  77. 'image'=>"{$params['now_image']}",
  78. 'image_type'=>"{$params['now_image_type']}",
  79. "face_type"=>"LIVE",
  80. "quality_control"=>"NORMAL",
  81. "liveness_control"=>"NORMAL"
  82. ]
  83. ];
  84. $token = $this->getBaiduToken();
  85. //重试2次
  86. $times = 2;
  87. requestMatch:
  88. $url = $this->_baseUrl.'/rest/2.0/face/v3/match?access_token='.$token;
  89. $res = HelperService::httpPost($url,json_encode($matchImage),true);
  90. $resultArr = @json_decode($res,true);
  91. if(isset($resultArr['error_code']) && $resultArr['error_code'] == 110 && $times>0){
  92. $token = $this->getBaiduToken(true);
  93. $times--;
  94. goto requestMatch;
  95. }
  96. if(isset($resultArr['error_code']) && $resultArr['error_code'] == 222209){
  97. $data = $this->register("{$params['now_image']}", "{$params['now_image_type']}");
  98. HelperService::returnJson(['code'=>201,'msg'=>"success",'data'=>$data]);
  99. }
  100. if(stripos($res,'cheek ') >0){
  101. HelperService::returnJson(['code'=>400,'msg'=>'请检查脸颊是否被遮挡或光线太弱!','data'=>$res]);
  102. }
  103. if(stripos($res,'eye ') >0){
  104. HelperService::returnJson(['code'=>400,'msg'=>'请检查眼睛是否被遮挡或闭眼!','data'=>$res]);
  105. }
  106. if(stripos($res,'face ') >0){
  107. HelperService::returnJson(['code'=>400,'msg'=>'请检查脸部是否被遮挡或光线太弱!','data'=>$res]);
  108. }
  109. if(stripos($res,'pic ') >0){
  110. HelperService::returnJson(['code'=>400,'msg'=>'请检查图片是否完整或不是脸部图片!','data'=>$res]);
  111. }
  112. if(!isset($resultArr['result']['score'])){
  113. HelperService::returnJson(['code'=>400,'msg'=>'验证失败','data'=>$res]);
  114. }
  115. HelperService::returnJson(['code'=>200,'msg'=>'success','data'=>['score'=>strval(round("{$resultArr['result']['score']}",2)),'res'=>$resultArr['result']['face_list']]]);
  116. }
  117. /**
  118. * 注册人脸
  119. * @param type $img
  120. * @param type $type
  121. * @param type $group_id
  122. */
  123. private function register($img,$type,$group_id="default",$userId=null){
  124. $userId = empty($userId)?$userId:uniqid();
  125. $token = $this->getBaiduToken(true);
  126. //重试2次
  127. $times = 2;
  128. requestRegister:
  129. $url = $this->_baseUrl.'/rest/2.0/face/v3/faceset/user/add?access_token='.$token;
  130. \think\Log::record("requestRegister:".$url."==>".$times);
  131. $res = HelperService::httpPost($url,json_encode([
  132. "image"=>$img,
  133. 'image_type'=>$type,
  134. "group_id"=>$group_id,
  135. "user_id"=> $userId,
  136. ]),true);
  137. $resultArr = @json_decode($res,true);
  138. if(isset($resultArr['error_code']) && $resultArr['error_code'] == 110 && $times>0){
  139. $token = $this->getBaiduToken(true);
  140. $times--;
  141. goto requestRegister;
  142. }
  143. if(empty($resultArr) || $resultArr['error_code']>0){
  144. HelperService::returnJson(['code'=>400,'msg'=>'注册人脸失败','data'=>$res]);
  145. }
  146. return ['res'=>$resultArr,'face_token'=>"{$resultArr['result']['face_token']}"];
  147. }
  148. /**
  149. * 人脸活体检测接口
  150. */
  151. public function detect(){
  152. $params = $this->_params;
  153. $rule = [
  154. 'image|原始图片'=>'require|url',
  155. ];
  156. $validate = new Validate($rule);
  157. if(!$validate->check($params)){
  158. HelperService::returnJson(['code'=>400,'msg'=>$validate->getError(),'data'=>[]]);
  159. }
  160. $detectImage = [
  161. 'image'=>"{$params['image']}",
  162. 'image_type'=>'URL',
  163. 'face_field'=>'quality'
  164. ];
  165. $token = $this->getBaiduToken();
  166. //重试2次
  167. $times = 2;
  168. requestDetect:
  169. $url = $this->_baseUrl.'/rest/2.0/face/v3/faceverify?access_token='.$token;
  170. $res = HelperService::httpPost($url,json_encode([$detectImage]),true);
  171. $resultArr = @json_decode($res,true);
  172. if(isset($resultArr['error_code']) && $resultArr['error_code'] == 110 && $times>0){
  173. $token = $this->getBaiduToken(true);
  174. $times--;
  175. goto requestDetect;
  176. }
  177. if(!isset($resultArr['error_msg']) || $resultArr['error_msg']!="SUCCESS" ){
  178. HelperService::returnJson(['code'=>400,'msg'=>'人脸活体检测失败','data'=>$res]);
  179. }
  180. if(!isset($resultArr['result']['face_liveness']) || round("{$resultArr['result']['face_liveness']}",2)< 0.97){
  181. HelperService::returnJson(['code'=>400,'msg'=>'请采集活体人脸照片','data'=>$resultArr,'liveness'=>round("{$resultArr['result']['face_liveness']}",2)]);
  182. }
  183. if(!isset($resultArr['result']['face_list'][0]['quality']['completeness']) || $resultArr['result']['face_list'][0]['quality']['completeness']<1){
  184. HelperService::returnJson(['code'=>400,'msg'=>'照片脸部不完整','data'=>$resultArr,'completeness'=>$resultArr['result']['face_list'][0]['quality']['completeness']]);
  185. }
  186. if(!isset($resultArr['result']['face_list'][0]['quality']['illumination']) || $resultArr['result']['face_list'][0]['quality']['illumination']<80){
  187. HelperService::returnJson(['code'=>400,'msg'=>'照片不够清晰度','data'=>$resultArr,'illumination'=>$resultArr['result']['face_list'][0]['quality']['illumination']]);
  188. }
  189. HelperService::returnJson(['code'=>200,'msg'=>'success','data'=>['res'=>$resultArr,'face_token'=>"{$resultArr['result']['face_list'][0]['face_token']}"]]);
  190. }
  191. }