人臉評分微信接口,獲取微信圖片地址,curl請求face++接口。解析json數據,計算顏值。返回用戶。
顏值匹配版,請到騰訊微校上體驗。http://weixiao.qq.com
<?php /** * 人臉識別測顏值、測臉齡、測相似度微信接口 * @Created by MOS.Ving. * @Author: MOS.Ving * @Mail [email protected] * @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; } ?>
演示圖