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

这篇文章主要给大家分享的是一段人脸识别测颜值、测脸龄、测相似度微信接口的代码,非常的有意思,有需要的小伙伴可以参考下。

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

颜值匹配版,请到腾讯微校上体验,http://weixiao.qq.com

  1. <?php
  2. /**
  3. * 人脸识别测颜值、测脸龄、测相似度微信接口
  4. * @Created by MOS.Ving.
  5. * @Author: MOS.Ving
  6. * @Mail 904679843@qq.com
  7. * @Date: 2016-01-31
  8. */
  9. define("TOKEN", 'weixin'); //设置token
  10. //FACE++ 参数 自行到face++官网注册并创建应用
  11. define("API_KEY", "api_key=填在这里"); //你的face++应用 api_key
  12. define("API_SECRET", "&api_secret=这里也要填");//你的face++应用 api_secret
  13. define("ATTRIBUTE", "&attribute=glass,pose,gender,age,race,smiling");//需要返回的内容的参数
  14. define("DETECT_URL", "http://apicn.faceplusplus.com/v2/detection/detect?");//检测给定图片(Image)中的所有人脸(Face)的位置和相应的面部属性api地址
  15. define("LANDMARK_URL", "http://api.faceplusplus.com/detection/landmark?");//检测给定人脸(Face)相应的面部轮廓,五官等关键点的位置,包括25点和83点两种模式api地址
  16. define("COMPARE_URL", "https://apicn.faceplusplus.com/v2/recognition/compare?");//计算两个Face的相似性以及五官相似度api地址
  17. define("TYPE","&type=83p");//83点模式
  18. define("MESSAGE_URL", "");//放回图文消息被点击需要跳转的地址,不需要跳转可不填
  19. $wechatObj = new wechatCallbackapiTest();
  20. if($_GET['echostr']){
  21. $wechatObj->valid();
  22. }else{
  23. $wechatObj->responseMsg();
  24. }
  25. class wechatCallbackapiTest{
  26. public function valid(){
  27. $echoStr = $_GET["echostr"];
  28. //valid signature , option
  29. if($this->checkSignature()){
  30. echo $echoStr;
  31. exit;
  32. }
  33. }
  34. public function responseMsg(){
  35. //get post data, May be due to the different environments
  36. $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
  37. //extract post data
  38. if (!emptyempty($postStr)){
  39. /* libxml_disable_entity_loader is to prevent XML eXternal Entity Injection,
  40. the best way is to check the validity of xml by yourself */
  41. libxml_disable_entity_loader(true);
  42. $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
  43. $fromUsername = $postObj->FromUserName;
  44. $toUsername = $postObj->ToUserName;
  45. $keyword = trim($postObj->Content);
  46. $imgUrl = $postObj->PicUrl;
  47. $Event = $postObj->Event;
  48. $EventKey = $postObj->EventKey;
  49. $MsgType = $postObj->MsgType;
  50. $time = time();
  51. $itemTpl = "<item>
  52. <Title><![CDATA[%s]]></Title>
  53. <Description><![CDATA[%s]]></Description>
  54. <PicUrl><![CDATA[%s]]></PicUrl>
  55. <Url><![CDATA[%s]]></Url>
  56. </item>";
  57. if($MsgType == "image"){
  58. $item_str = sprintf($itemTpl, "颜值报告单", face($imgUrl), $imgUrl, MESSAGE_URL);
  59. $xmlTpl = "<xml>
  60. <ToUserName><![CDATA[%s]]></ToUserName>
  61. <FromUserName><![CDATA[%s]]></FromUserName>
  62. <CreateTime>%s</CreateTime>
  63. <MsgType><![CDATA[news]]></MsgType>
  64. <ArticleCount>%s</ArticleCount>
  65. <Articles>$item_str</Articles>
  66. </xml>";
  67. $resultStr = sprintf($xmlTpl, $fromUsername, $toUsername, $time, 1);
  68. echo $resultStr;
  69. }
  70. }else {
  71. echo "";
  72. exit;
  73. }
  74. }
  75. private function checkSignature(){
  76. // you must define TOKEN by yourself
  77. if (!defined("TOKEN")){
  78. throw new Exception('TOKEN is not defined!');
  79. }
  80. $signature = $_GET["signature"];
  81. $timestamp = $_GET["timestamp"];
  82. $nonce = $_GET["nonce"];
  83. $token = TOKEN;
  84. $tmpArr = array($token, $timestamp, $nonce);
  85. // use SORT_STRING rule
  86. sort($tmpArr, SORT_STRING);
  87. $tmpStr = implode( $tmpArr );
  88. $tmpStr = sha1( $tmpStr );
  89. if( $tmpStr == $signature ){
  90. return true;
  91. }else{
  92. return false;
  93. }
  94. }
  95. }
  96. // 调用人脸识别的API返回识别结果
  97. function face($imgUrl){
  98. // face++ 链接
  99. $jsonStr =curl_get_contents(DETECT_URL.API_KEY.API_SECRET."&url=".$imgUrl.ATTRIBUTE);
  100. $replyDic = json_decode($jsonStr,true);
  101. $faceArray = $replyDic['face'];
  102. $resultStr = "";
  103. for ($i= 0;$i< count($faceArray); $i++){
  104. $resultStr .= "<----第".($i+1)."张脸---->\n";
  105. $tempFace = $faceArray[$i];
  106. $faceId = $tempFace['face_id'];
  107. $tempAttr = $tempFace['attribute'];
  108. // 年龄:包含年龄分析结果
  109. // value的值为一个非负整数表示估计的年龄, range表示估计年龄的正负区间
  110. $tempAge = $tempAttr['age'];
  111. // 性别:包含性别分析结果
  112. // value的值为Male/Female, confidence表示置信度
  113. $tempGenger = $tempAttr['gender'];
  114. // 种族:包含人种分析结果
  115. // value的值为Asian/White/Black, confidence表示置信度
  116. $tempRace = $tempAttr['race'];
  117. // 微笑:包含微笑程度分析结果
  118. //value的值为0-100的实数,越大表示微笑程度越高
  119. $tempSmiling = $tempAttr['smiling'];
  120. // 返回性别
  121. $sex=$tempGenger['value'];
  122. if($sex === "Male") {
  123. $resultStr .= "性别:男\n";
  124. } else if($sex === "Female") {
  125. $resultStr .= "性别:女\n";
  126. }
  127. //返回年龄
  128. $maxAge = $tempAge['value'] + ($tempAge['range'])/2;
  129. $age=ceil($maxAge);
  130. $resultStr .= "年龄:".$age."岁左右吧~ \n";
  131. //返回种族
  132. if($tempRace['value'] === "Asian") {
  133. $resultStr .= "肤色:很健康哦~\n";
  134. }
  135. else if($tempRace['value'] === "White") {
  136. $resultStr .= "肤色:皮肤好白哟!^ 3^\n";
  137. }
  138. else if($tempRace['value'] === "Black") {
  139. $resultStr .= " 肤色:你有点黑?!!!\n";
  140. }
  141. //返回微笑度
  142. $smiling = intval($tempSmiling['value']);
  143. $smile = round($tempSmiling['value'],3);
  144. $resultStr .= "微笑:".$smile."%\n";
  145. if($count<3){
  146. //计算颜值
  147. $yanzhi=getYanZhi($faceId,$smiling);
  148. $resultStr .= "外貌协会专家评分:".$yanzhi."分\n\n";
  149. $resultStr .= "\xe2\x9c\xa8小编想说:\n";
  150. switch ($yanzhi){
  151. case $yanzhi>94:
  152. $resultStr .="这颜值,爆表了!\n";
  153. break;
  154. case $yanzhi>87:
  155. $resultStr .="你这么好看,咋不上天呢!\n";
  156. break;
  157. case $yanzhi>82:
  158. $resultStr .="百看不厌,继续加油!\n";
  159. break;
  160. case $yanzhi>72:
  161. $resultStr .="还好,还能看!\n";
  162. break;
  163. case $yanzhi>67:
  164. $resultStr .="哎,只是丑的不明显!\n";
  165. break;
  166. case $yanzhi>62:
  167. $resultStr .="如果有钱,可以去整整!\n";
  168. break;
  169. default:
  170. $resultStr .="让我静静,你家没镜子么?\n";
  171. }
  172. }
  173. //图片中两个人时,计算相似度
  174. if(count($faceArray) === 2){
  175. // 获取face_id
  176. $tempFace1 = $faceArray[0];
  177. $tempId1 = $tempFace1['face_id'];
  178. $tempFace2 = $faceArray[1];
  179. $tempId2 = $tempFace2['face_id'];
  180. // face++ 链接
  181. $jsonStr1 = curl_get_contents(COMPARE_URL.API_KEY.API_SECRET."&face_id2=".$tempId2 ."&face_id1=".$tempId1);
  182. $replyDic1 = json_decode($jsonStr1,true);
  183. //取出相似程度
  184. $tempResult = $replyDic1['similarity'];
  185. $tempSimilarity = $replyDic1['component_similarity'];
  186. $tempEye = $tempSimilarity['eye'];
  187. $tempEyebrow = $tempSimilarity['eyebrow'];
  188. $tempMouth = $tempSimilarity['mouth'];
  189. $tempNose = $tempSimilarity['nose'];
  190. $resultStr .= "<----相似分析---->\n";
  191. $resultStr .= "眼睛:".round($tempEye,3)."%\n";
  192. $resultStr .= "眉毛:".round($tempEyebrow,3)."%\n";
  193. $resultStr .= "嘴巴:".round($tempMouth,3)."%\n";
  194. $resultStr .= "鼻子:".round($tempNose,3)."%\n";
  195. $resultStr .= "\n<----匹配结果---->\n两人相似程度:".round($tempResult,3)."%\n";
  196. if($tempResult>70){
  197. $resultStr .="哇塞!绝对的夫妻相了!\n";
  198. }elseif ($tempResult>50){
  199. $resultStr .="哎哟,长得挺像!你们快点在一起吧!\n";
  200. }else{
  201. $resultStr .="0.0 长得不太一样哦。\n";
  202. }
  203. }
  204. //如果没有检测到人脸
  205. if($resultStr === ""){
  206. $resultStr = "对不起,俺没有识别出来,请换张正脸照试试=.=";
  207. }
  208. return $resultStr;
  209. }
  210. //颜值算法
  211. function getYanZhi($faceId,$smiling){
  212. $t1=microtime(1);
  213. $jsonStr = curl_get_contents(LANDMARK_URL.API_KEY.API_SECRET."&face_id=".$faceId.TYPE);
  214. $t2=microtime(1);
  215. if(($t2-$t1)>1.5){
  216. return 75.632;
  217. }
  218. if ($jsonStr!=false) {
  219. $replyDic = json_decode($jsonStr,true);
  220. $result = $replyDic['result'];
  221. $landmarkArry = $result[0];
  222. $landmark =$landmarkArry['landmark'];
  223. $right_eyebrow_left_corner =$landmark['right_eyebrow_left_corner'];
  224. $left_eyebrow_right_corner =$landmark['left_eyebrow_right_corner'];
  225. $left_eye_left_corner =$landmark['left_eye_left_corner'];
  226. $left_eye_right_corner =$landmark['left_eye_right_corner'];
  227. $mouth_left_corner =$landmark['mouth_left_corner'];
  228. $mouth_right_corner =$landmark['mouth_right_corner'];
  229. $nose_left =$landmark['nose_left'];
  230. $nose_right =$landmark['nose_right'];
  231. $nose_contour_lower_middle =$landmark['nose_contour_lower_middle'];
  232. $right_eye_left_corner =$landmark['right_eye_left_corner'];
  233. $right_eye_right_corner =$landmark['right_eye_right_corner'];
  234. $contour_left1 =$landmark['contour_left1'];
  235. $contour_right1 =$landmark['contour_right1'];
  236. $contour_chin =$landmark['contour_chin'];
  237. $contour_left6 =$landmark['contour_left6'];
  238. $contour_right6 =$landmark['contour_right6'];
  239. //计算两眉头间的距离
  240. $c1=distance($left_eyebrow_right_corner['x'],$left_eyebrow_right_corner['y'],$right_eyebrow_left_corner['x'],$right_eyebrow_left_corner['y']);
  241. //眉毛之间的中点坐标;
  242. $c1_x=($right_eyebrow_left_corner['x']-$left_eyebrow_right_corner['x'])/2+$left_eyebrow_right_corner['x'];
  243. $c1_y=($right_eyebrow_left_corner['y']-$left_eyebrow_right_corner['y'])/2+$left_eyebrow_right_corner['y'];
  244. //眉毛中点到鼻子最低处的距离
  245. $c2 = distance($nose_contour_lower_middle['x'],$nose_contour_lower_middle['y'],$c1_x,$c1_y);
  246. //眼角之间的距离
  247. $c3 = distance($left_eye_right_corner['x'],$left_eye_right_corner['y'],$right_eye_left_corner['x'],$right_eye_left_corner['y']);
  248. //鼻子的宽度
  249. $c4 = distance($nose_left['x'],$nose_left['y'],$nose_right['x'],$nose_right['y']);
  250. //脸的宽度
  251. $c5 = distance($contour_left1['x'],$contour_left1['y'],$contour_right1['x'],$contour_right1['y']);
  252. //下巴到鼻子下方的高度
  253. $c6 = distance($contour_chin['x'],$contour_chin['y'],$nose_contour_lower_middle['x'],$nose_contour_lower_middle['y']);
  254. //眼睛的大小
  255. $c7_left = distance($left_eye_left_corner['x'],$left_eye_left_corner['y'],$left_eye_right_corner['x'],$left_eye_right_corner['y']);
  256. $c7_right = distance($right_eye_left_corner['x'],$right_eye_left_corner['y'],$right_eye_right_corner['x'],$right_eye_right_corner['y']);
  257. //嘴巴的大小
  258. $c8 = distance($mouth_left_corner['x'],$mouth_left_corner['y'],$mouth_right_corner['x'],$mouth_right_corner['y']);
  259. //嘴巴处的face大小
  260. $c9 = distance($contour_left6['x'],$contour_left6['y'],$contour_right6['x'],$contour_right6['y']);
  261. /* 开始计算步骤 */
  262. $yourmark = 100;
  263. $mustm = 0;
  264. //眼角距离为脸宽的1/5,
  265. $mustm += abs(($c3/$c5)*100 - 25);
  266. //鼻子宽度为脸宽的1/5
  267. $mustm += abs(($c4/$c5)*100 - 25);
  268. //眼睛的宽度,应为同一水平脸部宽度的!/5
  269. $eyepj = ($c7_left+$c7_right)/2;
  270. $mustm += abs($eyepj/$c5*100 - 25);
  271. //理想嘴巴宽度应为同一脸部宽度的1/2
  272. $mustm += abs(($c8/$c9)*100 - 50);
  273. //下巴到鼻子下方的高度 == 眉毛中点到鼻子最低处的距离
  274. $mustm += abs($c6 - $c2);
  275. return round($yourmark-$mustm+$smiling/10,3);
  276. }else{
  277. return 60;
  278. }
  279. }
  280. //两点之间的距离
  281. function distance($px1,$py1,$px2,$py2){
  282. return sqrt(abs(pow($px2 - $px1,2)) + abs(pow($py2 - $py1,2)));
  283. }
  284. function curl_get_contents($url) {
  285. $ch = curl_init();
  286. curl_setopt( $ch , CURLOPT_URL,$url);
  287. curl_setopt( $ch , CURLOPT_RETURNTRANSFER,1);
  288. curl_setopt( $ch , CURLOPT_TIMEOUT,1);
  289. curl_setopt( $ch , CURLOPT_CONNECTTIMEOUT,1.5);
  290. $result = curl_exec($ch);
  291. return $result;
  292. }
  293. ?>