我们所安装的摄像头必须支持`ftp`文件上传功能。然后将ftp地址指向系统`/cronjob/ftp/`目录下对应的门店文件夹内。当我们配置服务器地址的时候会自动生成店铺id多对应的文件夹,然后将生成的图片处理保存到`/public/upload/avatar`目录下。如图所对应的文件名即为所对应的店铺信息:
![](https://box.kancloud.cn/efb9396e7fc1bb4478de76c578a1534b_166x156.png)
下面介绍一下如何针对接入摄像头进行处理:
>[info]系统通过不断地访问cronjob/init.php文件执行以下四个步骤,从而完成摄像头的捕获与处理功能
1.通过`step1.php`文件将摄像头捕捉到的头像信息上传到我们的`/ftp/`所对应的目录下,通过以下代码进行上传:
~~~
file_put_contents($lock_f, date('Y-m-d H:i:s'));
$dir = __DIR__.'/ftp';
$list = glob($dir.'/*');
$exp = ['.','..','.git','.svn','.bash_logout'];
foreach($list as $deep){
$v = substr($deep,strrpos($deep,'/')+1);
//set outer_id
set_face_outer_id($v);
if(!is_dir($deep)) continue;
$li = glob($deep.'/*.jpg');
foreach($li as $file_path){
$vo = substr($file_path,strrpos($file_path,'/')+1);
// echo $file_path."\n".$vo;exit;
if(in_array($vo,$exp)) continue;
//读到对应的文件了。
//必须是图片,其他的不要。
$ext = strtolower(substr($vo,strrpos($vo,'.')+1));
//这不是静态图片的不要
if(!in_array($ext,['jpg','jpeg','png'])) continue;
//找出图片中的人脸图
// $file_path = $dir."/".$v."/".$vo;
file_put_contents(__DIR__.'/lock/1_image',$file_path);
face_avatar($file_path , $v);
}
}
unlink($lock_f);
~~~
2.通过`step2.php`文件设置我们的图片库:
~~~
if($all){
foreach($all as $v){
$face_token = $v['face_token'];
$id = $v['id'];
$flag = false;
$outer_id = $v['outer_id'];
if($v['closed_token']) {
file_put_contents(__DIR__."/lock/step2",$id);
$db->update('face_avatar',['is_mark'=>1,'status'=>2],['id'=>$id]);
continue;
}
$ret = face_api_search($face_token , $outer_id );
if($ret->error_message){
//没找到对应的outer_id,说明从来没有设置过,
//设置一下。同时,这个face_token直接入库吧
if($ret->error_message == "INVALID_OUTER_ID"){
face_set($face_token,$outer_id);
//状态修改为正常的,需要发送给其他接口的
$db->update('face_avatar',['is_mark'=>1,'status'=>1],['id'=>$id]);
}elseif($ret->error_message == 'CONCURRENCY_LIMIT_EXCEEDED'){
file_put_contents(__DIR__."/lock/api_error_CONCURRENCY_LIMIT_EXCEEDED",date('Y-m-d H:i:s'));
continue;
}else{
file_put_contents(__DIR__."/lock/api_error_stopall",var_export($ret,true));
}
continue;
}
//如果已经存在outerid那么,查找相似的人脸吧
if($ret->results){
foreach($ret->results as $v){
//排除本人的face_token
//然后比较最有可能是同一个人的情况
//大于80为疑似同一个人
$ft = $v->face_token;
if(
$ft != $face_token &&
$v->confidence > 80
){
$flag = true;
$current = $ft;
break;
}
}
}
//在人脸接口中找到了疑似同一个人的信息
if($flag === true){
//与当前查找的人的识别码一样的话,状态标识为1,其他的为2,2的数据是需要后面删除的。
if($face_token == $current){
$db->update('face_avatar',['is_mark'=>1,'status'=>1],['id'=>$id]);
}else{
//与数据库中存在的用户是同一个人
$db->update('face_avatar',['closed_token'=>$current,'status'=>2],['id'=>$id]);
}
}else{
//找不到,添加 face
//写入库
$db->update('face_avatar',['is_mark'=>1,'status'=>1],['id'=>$id]);
face_add($outer_id,$face_token);
}
}
}
~~~
3.图片库创建好之后就是对图片库进行处理,清楚无用的图片或者重复的图片信息:
~~~
foreach($all as $v){
$face_token = $v['face_token'];
$avatar = $v['avatar'];
$id = $v['id'];
$closed_token = $v['closed_token'];
$ltime = $v['ltime'];
$sended = $v['sended'];
//存在相关联的字段
//查找这个TOKEN对应的ID,
$one = $db->get('face_avatar',"*",['face_token'=> $closed_token,"is_mark"=>1 ]);
if($one){
$new_id = $one['id'];
//在一定时间时间内,不要重复提醒为新客户
if($one['ltime']+ $check_lastime > time() ){
file_put_contents(__DIR__.'/lock/step3_error2',$tts['ltime']." ".$check_lastime);
}else{
//作为新客户来操作
if( $one['sended'] != 2){
$fg = true;
$db->update("face_avatar",['sended'=>0,"status"=>1,'ltime'=>time()],['id'=>$new_id]);
file_put_contents(__DIR__."/lock/1_update.log",$new_id."--".$v['id']);
}
}
$db->update('face_avatar',['status'=> 3 ],['id'=>$id]);
//已经存在关联的,这个是要删除的。
//@unlink(__DIR__.'/'.$avatar);
}else{
file_put_contents(__DIR__.'/lock/error_step3',1);
}
file_put_contents(__DIR__."/lock/step3_newid.log",$new_id);
//在一定时间内,用户不要再创建新的token.
if( $face_relative_lt + $ltime > time() ){
echo "<br>too many pics- ".$v['avatar']."<br>";
} else{
$rt1 = $db->select('face_avatar_token',"*",[
'avatar_id'=>$id,
'face_token'=>$closed_token,
]);
if(!$rt1){
$db->insert("face_avatar_token",[
'face_token'=>$closed_token,
'avatar_id'=>$id,
'avatar' => $avatar,
'created' => time(),
]);
}
}
}
~~~
4.然后针对本店员工的进出门店进行判断处理客户与服务人员:
~~~
if($all){
foreach ($all as $v) {
$face_token = $v['face_token'];
$id = $v['id'];
$outer_id = set_face_outer_id($v['dir']);
$ret = face_api_search($face_token , $outer_id );
file_put_contents(__DIR__.'/lock/4_ret',var_export($ret,true));
if($ret->error_message){
continue;
}
file_put_contents(__DIR__.'/lock/4_ret_results',var_export($ret->results,true));
if($ret->results){
foreach($ret->results as $v){
//排除本人的face_token
//然后比较最有可能是同一个人的情况
//大于80为疑似同一个人
$ft = $v->face_token;
if(
$ft != $face_token &&
$v->confidence > 80
){
$flag = true;
$current = $ft;
break;
}
}
}
file_put_contents(__DIR__.'/lock/4_ret_current',$current );
if($current){
$db->update('face_exclude',['closed_token'=>$current] , ['id'=>$id] );
}
}
}
~~~
5.有时候我们会针对所捕获的图片进行处理或者图片质量的要求,那么我们可以在`comm.php`文件内设置,具体代码如下,当我们注释的时候代表不进行该处理操作:
~~~
//不清晰的照片不要了。是否模糊
/*if($v->attributes->blur->blurness->value > 2){
echo 'not good qulity<br>';
file_put_contents(__DIR__.'/lock/step1_no_qulity',$v->attributes->blur->blurness->value);
continue;
}
//人脸质量
if($v->attributes->facequality->value < 20){
echo 'not good qulity 2<br>';
file_put_contents(__DIR__.'/lock/step1_no_good',$v->attributes->facequality->value);
continue;
} */
~~~