当前位置: 移动技术网 > IT编程>开发语言>PHP > 人脸识别测颜值、测脸龄、测相似度微信接口

人脸识别测颜值、测脸龄、测相似度微信接口

2017年12月12日  | 移动技术网IT编程  | 我要评论

人脸评分微信接口,获取微信图片地址,curl请求face++接口。解析json数据,计算颜值。返回用户。

颜值匹配版,请到腾讯微校上体验。

<?php
/**
 * 人脸识别测颜值、测脸龄、测相似度微信接口
 * @created by mos.ving.
 * @author: mos.ving
 * @mail 904679843@qq.com
 * @date: 2016-01-31
 */
 
define("token", 'weixin'); //设置token
 
//face++ 参数 自行到face++官网注册并创建应用
define("api_key", "api_key=填在这里"); //你的face++应用 api_key
define("api_secret", "&api_secret=这里也要填");//你的face++应用 api_secret
define("attribute", "&attribute=glass,pose,gender,age,race,smiling");//需要返回的内容的参数
 
define("detect_url", "http://apicn.faceplusplus.com/v2/detection/detect?");//检测给定图片(image)中的所有人脸(face)的位置和相应的面部属性api地址
define("landmark_url", "http://api.faceplusplus.com/detection/landmark?");//检测给定人脸(face)相应的面部轮廓,五官等关键点的位置,包括25点和83点两种模式api地址
define("compare_url", "https://apicn.faceplusplus.com/v2/recognition/compare?");//计算两个face的相似性以及五官相似度api地址
 
define("type","&type=83p");//83点模式
 
 
define("message_url", "");//放回图文消息被点击需要跳转的地址,不需要跳转可不填
 
$wechatobj = new wechatcallbackapitest();
if($_get['echostr']){
  $wechatobj->valid();
}else{
  $wechatobj->responsemsg();
}
 
class wechatcallbackapitest{
  public function valid(){
    $echostr = $_get["echostr"];
    //valid signature , option
    if($this->checksignature()){
      echo $echostr;
      exit;
    }
  }
 
  public function responsemsg(){
    //get post data, may be due to the different environments
    $poststr = $globals["http_raw_post_data"];
 
    //extract post data
    if (!empty($poststr)){
        /* libxml_disable_entity_loader is to prevent xml external entity injection,
          the best way is to check the validity of xml by yourself */
        libxml_disable_entity_loader(true);
        $postobj   = simplexml_load_string($poststr, 'simplexmlelement', libxml_nocdata);
        $fromusername = $postobj->fromusername;
        $tousername  = $postobj->tousername;
        $keyword   = trim($postobj->content);
        $imgurl    = $postobj->picurl;
        $event    = $postobj->event;
        $eventkey   = $postobj->eventkey;
        $msgtype   = $postobj->msgtype;
        $time     = time();
 
        $itemtpl = "<item>
           <title><![cdata[%s]]></title>
           <description><![cdata[%s]]></description>
           <picurl><![cdata[%s]]></picurl>
           <url><![cdata[%s]]></url>
           </item>";
 
        if($msgtype == "image"){
          $item_str = sprintf($itemtpl, "颜值报告单", face($imgurl), $imgurl, message_url);
 
          $xmltpl = "<xml>
           <tousername><![cdata[%s]]></tousername>
           <fromusername><![cdata[%s]]></fromusername>
           <createtime>%s</createtime>
           <msgtype><![cdata[news]]></msgtype>
           <articlecount>%s</articlecount>
           <articles>$item_str</articles>
           </xml>";
          $resultstr = sprintf($xmltpl, $fromusername, $tousername, $time, 1);
          echo $resultstr;
        }
        
    }else {
      echo "";
      exit;
    }
  }
     
  private function checksignature(){
    // you must define token by yourself
    if (!defined("token")){
      throw new exception('token is not defined!');
    }
     
    $signature = $_get["signature"];
    $timestamp = $_get["timestamp"];
    $nonce = $_get["nonce"];
         
    $token = token;
    $tmparr = array($token, $timestamp, $nonce);
    // use sort_string rule
    sort($tmparr, sort_string);
    $tmpstr = implode( $tmparr );
    $tmpstr = sha1( $tmpstr );
     
    if( $tmpstr == $signature ){
      return true;
    }else{
      return false;
    }
  }
 
}
 
// 调用人脸识别的api返回识别结果
function face($imgurl){
  // face++ 链接 
  $jsonstr  =curl_get_contents(detect_url.api_key.api_secret."&url=".$imgurl.attribute);
  $replydic = json_decode($jsonstr,true);
  $facearray = $replydic['face'];
   
  $resultstr = "";
     
  for ($i= 0;$i< count($facearray); $i++){
     
    $resultstr .= "<----第".($i+1)."张脸---->\n";
 
    $tempface  = $facearray[$i];
    $faceid   = $tempface['face_id'];
 
    $tempattr = $tempface['attribute'];
    // 年龄:包含年龄分析结果
    // value的值为一个非负整数表示估计的年龄, range表示估计年龄的正负区间
    $tempage = $tempattr['age'];
    // 性别:包含性别分析结果
    // value的值为male/female, confidence表示置信度
    $tempgenger = $tempattr['gender'];
    // 种族:包含人种分析结果
    // value的值为asian/white/black, confidence表示置信度
    $temprace = $tempattr['race'];
    // 微笑:包含微笑程度分析结果
    //value的值为0-100的实数,越大表示微笑程度越高
    $tempsmiling = $tempattr['smiling'];
    
    // 返回性别
    $sex=$tempgenger['value'];
    if($sex === "male") {
      $resultstr .= "性别:男\n";
    } else if($sex === "female") {
      $resultstr .= "性别:女\n";
    }
 
    //返回年龄
    $maxage = $tempage['value'] + ($tempage['range'])/2;
    $age=ceil($maxage);
    $resultstr .= "年龄:".$age."岁左右吧~ \n";
 
    //返回种族
    if($temprace['value'] === "asian") {
      $resultstr .= "肤色:很健康哦~\n";
    }
    else if($temprace['value'] === "white") {
      $resultstr .= "肤色:皮肤好白哟!^ 3^\n";
    }
    else if($temprace['value'] === "black") {
      $resultstr .= " 肤色:你有点黑?!!!\n";
    }
 
    //返回微笑度
    $smiling = intval($tempsmiling['value']);
    $smile = round($tempsmiling['value'],3);
    $resultstr .= "微笑:".$smile."%\n";
 
    if($count<3){
      //计算颜值
      $yanzhi=getyanzhi($faceid,$smiling);
      $resultstr .= "外貌协会专家评分:".$yanzhi."分\n\n";
      $resultstr .= "\xe2\x9c\xa8小编想说:\n";
      switch ($yanzhi){
        case $yanzhi>94:
          $resultstr .="这颜值,爆表了!\n";
          break;
        case $yanzhi>87:
          $resultstr .="你这么好看,咋不上天呢!\n";
          break;
        case $yanzhi>82:
          $resultstr .="百看不厌,继续加油!\n";
          break;
        case $yanzhi>72:
          $resultstr .="还好,还能看!\n";
          break;
        case $yanzhi>67:
          $resultstr .="哎,只是丑的不明显!\n";
          break;
        case $yanzhi>62:
          $resultstr .="如果有钱,可以去整整!\n";
          break;
        default:
          $resultstr .="让我静静,你家没镜子么?\n";
      }
    }
 
  //图片中两个人时,计算相似度
  if(count($facearray) === 2){ 
    // 获取face_id 
    $tempface1 = $facearray[0]; 
    $tempid1 = $tempface1['face_id']; 
    $tempface2 = $facearray[1]; 
    $tempid2 = $tempface2['face_id']; 
 
    // face++ 链接 
    $jsonstr1 = curl_get_contents(compare_url.api_key.api_secret."&face_id2=".$tempid2 ."&face_id1=".$tempid1);  
    $replydic1 = json_decode($jsonstr1,true); 
 
    //取出相似程度 
    $tempresult = $replydic1['similarity']; 
     
    $tempsimilarity = $replydic1['component_similarity']; 
    $tempeye = $tempsimilarity['eye']; 
    $tempeyebrow = $tempsimilarity['eyebrow']; 
    $tempmouth = $tempsimilarity['mouth']; 
    $tempnose = $tempsimilarity['nose']; 
 
    $resultstr .= "<----相似分析---->\n"; 
    $resultstr .= "眼睛:".round($tempeye,3)."%\n"; 
    $resultstr .= "眉毛:".round($tempeyebrow,3)."%\n"; 
    $resultstr .= "嘴巴:".round($tempmouth,3)."%\n"; 
    $resultstr .= "鼻子:".round($tempnose,3)."%\n"; 
     
    $resultstr .= "\n<----匹配结果---->\n两人相似程度:".round($tempresult,3)."%\n"; 
 
    if($tempresult>70){
      $resultstr .="哇塞!绝对的夫妻相了!\n";
    }elseif ($tempresult>50){
      $resultstr .="哎哟,长得挺像!你们快点在一起吧!\n";
    }else{
      $resultstr .="0.0 长得不太一样哦。\n";
    }
   
  } 
 
  //如果没有检测到人脸
  if($resultstr === ""){
    $resultstr = "对不起,俺没有识别出来,请换张正脸照试试=.=";
  }
 
 return $resultstr;
}
 
 
//颜值算法
function getyanzhi($faceid,$smiling){
  $t1=microtime(1);
  $jsonstr = curl_get_contents(landmark_url.api_key.api_secret."&face_id=".$faceid.type);
  $t2=microtime(1);
  if(($t2-$t1)>1.5){
    return 75.632;
  }
 
  if ($jsonstr!=false) {
    $replydic = json_decode($jsonstr,true);
 
    $result = $replydic['result'];
    $landmarkarry = $result[0];
    $landmark =$landmarkarry['landmark'];
 
    $right_eyebrow_left_corner =$landmark['right_eyebrow_left_corner'];
    $left_eyebrow_right_corner =$landmark['left_eyebrow_right_corner'];
 
    $left_eye_left_corner    =$landmark['left_eye_left_corner'];
    $left_eye_right_corner   =$landmark['left_eye_right_corner'];
 
    $mouth_left_corner     =$landmark['mouth_left_corner'];
    $mouth_right_corner     =$landmark['mouth_right_corner'];
 
    $nose_left         =$landmark['nose_left'];
    $nose_right         =$landmark['nose_right'];
    $nose_contour_lower_middle =$landmark['nose_contour_lower_middle'];
 
    $right_eye_left_corner   =$landmark['right_eye_left_corner'];
    $right_eye_right_corner   =$landmark['right_eye_right_corner'];
 
    $contour_left1       =$landmark['contour_left1'];
    $contour_right1       =$landmark['contour_right1'];
    $contour_chin        =$landmark['contour_chin'];
    $contour_left6       =$landmark['contour_left6'];
    $contour_right6       =$landmark['contour_right6'];
 
    //计算两眉头间的距离
    $c1=distance($left_eyebrow_right_corner['x'],$left_eyebrow_right_corner['y'],$right_eyebrow_left_corner['x'],$right_eyebrow_left_corner['y']);
 
    //眉毛之间的中点坐标;
    $c1_x=($right_eyebrow_left_corner['x']-$left_eyebrow_right_corner['x'])/2+$left_eyebrow_right_corner['x'];
    $c1_y=($right_eyebrow_left_corner['y']-$left_eyebrow_right_corner['y'])/2+$left_eyebrow_right_corner['y'];
 
    //眉毛中点到鼻子最低处的距离
    $c2 = distance($nose_contour_lower_middle['x'],$nose_contour_lower_middle['y'],$c1_x,$c1_y);
 
    //眼角之间的距离
    $c3 = distance($left_eye_right_corner['x'],$left_eye_right_corner['y'],$right_eye_left_corner['x'],$right_eye_left_corner['y']);
 
    //鼻子的宽度
    $c4 = distance($nose_left['x'],$nose_left['y'],$nose_right['x'],$nose_right['y']);
 
    //脸的宽度
    $c5 = distance($contour_left1['x'],$contour_left1['y'],$contour_right1['x'],$contour_right1['y']);
 
    //下巴到鼻子下方的高度
    $c6 = distance($contour_chin['x'],$contour_chin['y'],$nose_contour_lower_middle['x'],$nose_contour_lower_middle['y']);
 
    //眼睛的大小
    $c7_left = distance($left_eye_left_corner['x'],$left_eye_left_corner['y'],$left_eye_right_corner['x'],$left_eye_right_corner['y']);
    $c7_right = distance($right_eye_left_corner['x'],$right_eye_left_corner['y'],$right_eye_right_corner['x'],$right_eye_right_corner['y']);
 
    //嘴巴的大小
    $c8 = distance($mouth_left_corner['x'],$mouth_left_corner['y'],$mouth_right_corner['x'],$mouth_right_corner['y']);
 
    //嘴巴处的face大小
    $c9 = distance($contour_left6['x'],$contour_left6['y'],$contour_right6['x'],$contour_right6['y']);
 
    /* 开始计算步骤 */
    $yourmark = 100;
    $mustm = 0;
 
    //眼角距离为脸宽的1/5,
    $mustm += abs(($c3/$c5)*100 - 25);
 
    //鼻子宽度为脸宽的1/5
    $mustm += abs(($c4/$c5)*100 - 25);
 
    //眼睛的宽度,应为同一水平脸部宽度的!/5
    $eyepj = ($c7_left+$c7_right)/2;
    $mustm += abs($eyepj/$c5*100 - 25);
 
    //理想嘴巴宽度应为同一脸部宽度的1/2
    $mustm += abs(($c8/$c9)*100 - 50);
 
 
    //下巴到鼻子下方的高度 == 眉毛中点到鼻子最低处的距离
    $mustm += abs($c6 - $c2);
 
    return round($yourmark-$mustm+$smiling/10,3);
  }else{
    return 60;
  }
 
}
 
//两点之间的距离
function distance($px1,$py1,$px2,$py2){
  return sqrt(abs(pow($px2 - $px1,2)) + abs(pow($py2 - $py1,2)));
}
 
 
function curl_get_contents($url) {
  $ch = curl_init();
  curl_setopt( $ch , curlopt_url,$url);
  curl_setopt( $ch , curlopt_returntransfer,1);
  curl_setopt( $ch , curlopt_timeout,1);
  curl_setopt( $ch , curlopt_connecttimeout,1.5);
  $result = curl_exec($ch);
  return $result;
}
 
?>

演示图

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网