当Newifi遇到微信公众号(5)——人脸识别之相似脸
当Newifi遇到微信公众号(5)——人脸识别之相似脸:
前篇博文我们讲到在newifi上进行公众号开发初步实现了人脸识别功能,本文将继续说一说在人脸识别的基础上基于公众号实现两张照片的面部相似度检测。发挥想象,一切皆有可能。。。
本文依然展示通过使用第三方人脸识别接口(FACE++)实现公众号的人脸识别的相似度分析功能:
1、首先你需要Newifi智能路由器一台,并接入互联网(经过之前的努力,服务器插件、花生壳插件以及微信公众号平台都已经搭建好了等);
2、总结本功能涉及到的公众号接口依然只有两种:文本和图片,主要流程是:
接收文本消息->回复文本消息->接收图片事件->回复文本消息->接收图片事件->回复文本消息:
公众号回复文本消息结构和图片消息结构我们在上篇已经有阐述,此处就不在赘述(可以参考微信公众号开发文档)
事件处理分支还是如此,不同事件调用不同函数处理:
public function responseMsg()
{
$postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; //获取事件类型
if (!empty($postStr)){
$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
$RX_TYPE = trim($postObj->MsgType);
switch($RX_TYPE) //针对不同事件,调用相应函数处理
{
case "text":
$resultStr = $this->handleText($postObj); //文本事件处理
break;
case "image":
$resultStr = $this->handleImage($postObj); //图片事件处理
break;
default:
$resultStr = "Unknow msg type: ".$RX_TYPE;
break;
}
echo $resultStr;
}
文本事件处理:
public function handleText($postObj)
{
$fromUsername = $postObj->FromUserName;
$toUsername = $postObj->ToUserName;
$keyword = trim($postObj->Content);
$time = time();
$textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[%s]]></MsgType>
<Content><![CDATA[%s]]></Content>
<FuncFlag>0</FuncFlag>
</xml>";
if(!empty( $keyword ))
{
if( $keyword == "相似脸" ){ //判断关键字
$msgType = "text"; //回复文本消息
$contentStr = "小主,来两张美照,Try一下吧!!!"; //回复文本消息内容
$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
echo $resultStr;
}
}
}
图片事件处理:
public function handleImage($postObj)
{
$fromUsername = $postObj->FromUserName;
$toUsername = $postObj->ToUserName;
$picUrl = $postObj->PicUrl;
$time = $postObj->CreateTime
$faceNum = "0"; //初始化照片计数
if ($faceNum == 0) {
$faceNum = "1"; //增加照片计数
$contentStr = "请再发送一张照片。。。"; //回复文本消息内容
$str=file_get_contents("http://www.gongkong-maker.com/wx_face.php?pic=$picUrl&num=1&en=1"); //上传第一张照片(num=1)
}else if ($faceNum == 1) {
$faceNum = "0"; //初始化照片计数
$str=file_get_contents("http://www.gongkong-maker.com/wx_face.php?pic=$picUrl&num=2&en=1"); //上传第一张照片(num=2),引入FACE++人脸识别接口,获取面部识别结果
$contentStr = $str;
}
$resultStr = $this->responseText($postObj, $contentStr); //调用文本消息回复函数responseText()
return $resultStr;
}
public function responseText($object, $content, $flag=0)
{
$textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[%s]]></Content>
<FuncFlag>%d</FuncFlag>
</xml>";
$resultStr = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time(), $content, $flag); //回复面部识别结果
return $resultStr;
}
引入FACE++人脸识别接口(FACE++接口是可以分析同一张照片上的两个面部的相似度的,但是本文阐述的是微信端用户上传的是两张独立的照片,所以就涉及到图片的合成,即将用户上传的两张照片合并成包含两个面部的一张照片然后调用FACE++进行分析):
wx_face.php(外行人写的代码全靠Google,PHP几乎零基础,莫见笑):
<?PHP
header("Content-Type: text/html; charset=UTF-8");
$picUrl = $_GET[pic]; //获取用户上传图片链接
$facePath = dirname(__file__); //获取当前目录,用于存储照片
$facen = $_GET[en]; //调用照片合成使能
$faceNum = "1"; //初始化照片数
if ($facen == 1) {
if ($faceNum == 1) {
exec("curl -o $facePath/wx_pic/face1.jpg $picUrl "); //由于平台搭建在路由器上(基于openwrt),此处就直接调用系统curl命令获取照片了
}else if ($faceNum == 2) {
exec("curl -o $facePath/wx_pic/face2.jpg $picUrl "); //获取第二张照片
require_once 'wx_face2.php'; //调用图片合成处理脚本
}
}
echo app(); //调用app函数获取回复内容
function app();
{
require_once 'wx_face_sdk.php'; //引入FACE++sdk
$picUrl = "http://www.gongkong-maker.com/face.jpg";
$facepp = new Facepp();
#detect image by url
$params = array('url'=>$picUrl);
$response = $facepp->execute('/detection/detect',$params); //通过FACE++sdk获得面部识别结果,获取两个face_id
if($response['http_code']==200){ //对返回结果数据处理
#json decode
$data = json_decode($response['body'],1);
$face = $data['face'];
$size = sizeof($face);
$response = $facepp->execute('/recognition/compare',array('face_id1'=>$face[0]['face_id'],'face_id2'=>$face[1]['face_id'])); //通过FACE++sdk的两个face_id的比较接口,获得面部识别结果
$result = json_decode($response['body'],1)['component_similarity']; //对返回结果数据处理
$maxNum = ceil(max($result));
if ($maxNum >= "80") {
$maxDes = "几乎一样/::O";
}else {
$maxDes = "大同小异/::D";
}
$maxPart_tmp = array_keys($result,$maxNum)[0];
if ($maxPart_tmp == "eye") {
$maxPart = "眼睛";
}else if ($maxPart_tmp == "eyebrow") {
$maxPart = "眉毛";
}else if ($maxPart_tmp == "mouth") {
$maxPart = "嘴巴";
}else {
$maxPart = "鼻子";
}
$similarity = ceil(json_decode($response['body'],1)['similarity']);
if ($similarity < "30") {
$describe = "(看起来不太像/:,@P)";
}else if ($similarity >= "80") {
$describe = "(就没见过这么像的/::O)";
}else {
$describe = "(大同小异/::D)";
}
print_r("最相似的部位:".$maxPart."(相似度:".$maxNum."%,".$maxDes.")"."\n"."相似度:".$similarity."%".$describe);
}
}
?>
wx_face_sdk.php(与上篇相同,此处不再展示):
wx_face2.php(照片合成脚本,外行人写的代码全靠Google,PHP几乎零基础,莫见笑):
<?PHP
ini_set('memory_limit','32M'); //照片大小限制
$src1 = ImageCreateFromJPEG('wx_pic/face1.jpg'); //调用ImageCreateFromJPEG()函数获取第一张图片参数
$size1 = getimagesize('wx_pic/face1.jpg');
$width1 = $size1[0];
$height1 = $size1[1];
$src2 = ImageCreateFromJPEG('wx_pic/face2.jpg'); //调用ImageCreateFromJPEG()函数获取第二张图片参数
$size2 = getimagesize('wx_pic/face2.jpg');
$width2 = $size2[0];
$height2 = $size2[1];
$x = "200"; //设置合成图片参数
$y = "200";
$dst = imagecreatetruecolor($x,$y);
imagecopyresized($dst,$src1,0,0,0,0,$x,$y,$width1,$height1); //调用imagecopyresized()函数压缩图片
imagejpeg($dst,'wx_pic/face11.jpg');
imagecopyresized($dst,$src2,0,0,0,0,$x,$y,$width2,$height2); //调用imagecopyresized()函数压缩图片
imagejpeg($dst,'wx_pic/face22.jpg');
$target = 'wx_pic/emp.jpg'; //白色空白背景图片
$target_img = ImageCreateFromJPEG($target);
$imgs1 = ImageCreateFromJPEG('wx_pic/face11.jpg');
$imgs2 = ImageCreateFromJPEG('wx_pic/face22.jpg');
imagecopy ($target_img,$imgs1,0,0,0,0,$x,$y);
imagecopy ($target_img,$imgs2,200,0,0,0,$x,$y); //调用imagecopy()函数合成图片
imagejpeg($target_img,'face.jpg'); //调用imagejpeg()函数保存图片
?>
3、我的公众号:我的Zone(chen244970717)



还没有人抢沙发呢~