微信公眾平台開發教程-應用實例之人臉檢測(Java版)


本文轉自柳峰的專欄:http://blog.csdn.net/lyq8479/article/details/17362685 


本文將為讀者介紹人臉檢測應用的完整實現過程。

        人臉檢測屬於人臉識別的范疇,它是一個復雜的具有挑戰性的模式匹配問題,國內外許多組織、科研機構都在專門研究該問題。國內的Face++團隊專注於研發人臉檢測、識別、分析和重建技術,並且向廣大開發者開放了人臉識別API,本文介紹的“人臉檢測”應用正是基於Face++ API進行開發。


Face++簡介

        Face++是北京曠視科技有限公司旗下的人臉識別雲服務平台,Face++平台通過提供雲端API、離線SDK、以及面向用戶的自主研發產品等形式,將人臉識別技術廣泛應用到互聯網及移動應用場景中。Face++為廣大開發者提供了簡單易用的API,開發者可以輕松搭建屬於自己的雲端身份認證、用戶興趣挖掘、移動體感交互、社交娛樂分享等多種類型的應用。

        Face++提供的技術服務包括人臉檢測、人臉分析和人臉識別,主要說明如下:

                1)人臉檢測:可以從圖片中快速、准確的定位面部的關鍵區域位置,包括眉毛、眼睛、鼻子、嘴巴等。
                2)人臉分析:可以從圖片或實時視頻流中分析出人臉的性別(准確度達96%)、年齡、種族等多種屬性。
                3)人臉識別:可以快速判定兩張照片是否為同一個人,或者快速判定視頻中的人像是否為某一位特定的人。

        Face++的中文網址為http://cn.faceplusplus.com/,要使用Face++ API,需要注冊成為Face++開發者,也就是要注冊一個Face++賬號。注冊完成后,先創建應用,創建應用時需要填寫“應用名稱”、“應用描述”、“API服務器”、“應用類型”和“應用平台”,讀者可以根據實際情況填寫。應用創建完成后,可以看到應用的詳細信息,如下圖所示。

                

        上圖中,最重要的是API KEY和API SECRET,在調用Face++提供的API時,需要傳入這兩個參數。


人臉檢測API介紹

        在Face++網站的“API文檔”中,能夠看到Face++提供的所有API,我們要使用的人臉檢測接口是detect分類下的“/detection/detect”,它能夠檢測出給定圖片(Image)中的所有人臉(Face)的位置和相應的面部屬性,目前面部屬性包括性別(gender)、年齡(age)、種族(race)、微笑程度(smiling)、眼鏡(glass)和姿勢(pose)。

        讀者可以在http://cn.faceplusplus.com/uc/doc/home?id=69中了解到人臉檢測接口的詳細信息,該接口的請求地址如下:

[html]  view plain copy 在CODE上查看代碼片 派生到我的代碼片
  1. http://apicn.faceplusplus.com/v2/detection/detect?url=URL&api_secret=API_SECRET&api_key=API_KEY  
調用上述接口,必須要傳入參數api_key、api_secret和待檢測的圖片。其中,待檢測的圖片可以是URL,也可以是POST方式提交的二進制數據。在微信公眾賬號后台,接收用戶發送的圖片,得到的是圖片的訪問路徑(PicUrl),因此,在本例中,直接使用待檢測圖片的URL是最方便的。調用人臉檢測接口返回的是JSON格式數據如下:

[html]  view plain copy 在CODE上查看代碼片 派生到我的代碼片
  1. {  
  2.     "face": [  
  3.         {  
  4.             "attribute": {  
  5.                 "age": {  
  6.                     "range": 5,  
  7.                     "value": 23  
  8.                 },  
  9.                 "gender": {  
  10.                     "confidence": 99.9999,  
  11.                     "value": "Female"  
  12.                 },  
  13.                 "glass": {  
  14.                     "confidence": 99.945,  
  15.                     "value": "None"  
  16.                 },  
  17.                 "pose": {  
  18.                     "pitch_angle": {  
  19.                         "value": 17  
  20.                     },  
  21.                     "roll_angle": {  
  22.                         "value": 0.735735  
  23.                     },  
  24.                     "yaw_angle": {  
  25.                         "value": -2  
  26.                     }  
  27.                 },  
  28.                 "race": {  
  29.                     "confidence": 99.6121,  
  30.                     "value": "Asian"  
  31.                 },  
  32.                 "smiling": {  
  33.                     "value": 4.86501  
  34.                 }  
  35.             },  
  36.             "face_id": "17233b4b1b51ac91e391e5afe130eb78",  
  37.             "position": {  
  38.                 "center": {  
  39.                     "x": 49.4,  
  40.                     "y": 37.6  
  41.                 },  
  42.                 "eye_left": {  
  43.                     "x": 43.3692,  
  44.                     "y": 30.8192  
  45.                 },  
  46.                 "eye_right": {  
  47.                     "x": 56.5606,  
  48.                     "y": 30.9886  
  49.                 },  
  50.                 "height": 26.8,  
  51.                 "mouth_left": {  
  52.                     "x": 46.1326,  
  53.                     "y": 44.9468  
  54.                 },  
  55.                 "mouth_right": {  
  56.                     "x": 54.2592,  
  57.                     "y": 44.6282  
  58.                 },  
  59.                 "nose": {  
  60.                     "x": 49.9404,  
  61.                     "y": 38.8484  
  62.                 },  
  63.                 "width": 26.8  
  64.             },  
  65.             "tag": ""  
  66.         }  
  67.     ],  
  68.     "img_height": 500,  
  69.     "img_id": "22fd9efc64c87e00224c33dd8718eec7",  
  70.     "img_width": 500,  
  71.     "session_id": "38047ad0f0b34c7e8c6efb6ba39ed355",  
  72.     "url": "http://cn.faceplusplus.com/wp-content/themes/faceplusplus.zh/assets/img/demo/1.jpg?v=4"  
  73. }  
這里只對本文將要實現的“人臉檢測”功能中主要用到的參數進行說明,參數說明如下:

1)face是一個數組,當一張圖片中包含多張人臉時,所有識別出的人臉信息都在face數組中。

2)age中的value表示估計年齡,range表示誤差范圍。例如,上述結果中value=23,range=5,表示人的真實年齡在18歲至28歲左右。

3)gender中的value表示性別,男性為Male,女性為Female;gender中的confidence表示檢測結果的可信度。

4)race中的value表示人種,黃色人種為Asian,白色人種為White,黑色人種為Black;race中的confidence表示檢測結果的可信度。

5)center表示人臉框中心點坐標,可以將x用於計算人臉的左右順序,即x坐標的值越小,人臉的位置越靠近圖片的左側。

人臉檢測API的使用方法

        為了方便開發者調用人臉識別API,Face++團隊提供了基於Objective-C、Java(Android)、Matlab、Ruby、C#等多種語言的開發工具包,讀者可以在Face++網站的“工具下載”版塊下載相關的SDK。在本例中,筆者並不打算使用官方提供的SDK進行開發,主要原因如下:1)人臉檢測API的調用比較簡單,自己寫代碼實現也並不復雜;2)如果使用SDK進行開發,筆者還要花費大量篇幅介紹SDK的使用,這些並不是本文的重點;3)自己寫代碼實現比較靈活。當圖片中有多張人臉時,人臉檢測接口返回的數據是無序的,開發者可以按照實際使用需求進行排序,例如,將圖片中的人臉按照從左至右的順序進行排序。


編程調用人臉檢測API

        首先,要對人臉檢測接口返回的結構進行封裝,建立與之對應的Java對象。由於人臉檢測接口返回的參數較多,筆者只是將本例中需要用到的參數抽取出來,封裝成Face對象,對應的代碼如下:

[java]  view plain copy 在CODE上查看代碼片 派生到我的代碼片
  1. package org.liufeng.course.pojo;  
  2.   
  3. /** 
  4.  * Face Model 
  5.  *  
  6.  * @author liufeng 
  7.  * @date 2013-12-18 
  8.  */  
  9. public class Face implements Comparable<Face> {  
  10.     // 被檢測出的每一張人臉都在Face++系統中的標識符  
  11.     private String faceId;  
  12.     // 年齡估計值  
  13.     private int ageValue;  
  14.     // 年齡估計值的正負區間  
  15.     private int ageRange;  
  16.     // 性別:Male/Female  
  17.     private String genderValue;  
  18.     // 性別分析的可信度  
  19.     private double genderConfidence;  
  20.     // 人種:Asian/White/Black  
  21.     private String raceValue;  
  22.     // 人種分析的可信度  
  23.     private double raceConfidence;  
  24.     // 微笑程度  
  25.     private double smilingValue;  
  26.     // 人臉框的中心點坐標  
  27.     private double centerX;  
  28.     private double centerY;  
  29.   
  30.     public String getFaceId() {  
  31.         return faceId;  
  32.     }  
  33.   
  34.     public void setFaceId(String faceId) {  
  35.         this.faceId = faceId;  
  36.     }  
  37.   
  38.     public int getAgeValue() {  
  39.         return ageValue;  
  40.     }  
  41.   
  42.     public void setAgeValue(int ageValue) {  
  43.         this.ageValue = ageValue;  
  44.     }  
  45.   
  46.     public int getAgeRange() {  
  47.         return ageRange;  
  48.     }  
  49.   
  50.     public void setAgeRange(int ageRange) {  
  51.         this.ageRange = ageRange;  
  52.     }  
  53.   
  54.     public String getGenderValue() {  
  55.         return genderValue;  
  56.     }  
  57.   
  58.     public void setGenderValue(String genderValue) {  
  59.         this.genderValue = genderValue;  
  60.     }  
  61.   
  62.     public double getGenderConfidence() {  
  63.         return genderConfidence;  
  64.     }  
  65.   
  66.     public void setGenderConfidence(double genderConfidence) {  
  67.         this.genderConfidence = genderConfidence;  
  68.     }  
  69.   
  70.     public String getRaceValue() {  
  71.         return raceValue;  
  72.     }  
  73.   
  74.     public void setRaceValue(String raceValue) {  
  75.         this.raceValue = raceValue;  
  76.     }  
  77.   
  78.     public double getRaceConfidence() {  
  79.         return raceConfidence;  
  80.     }  
  81.   
  82.     public void setRaceConfidence(double raceConfidence) {  
  83.         this.raceConfidence = raceConfidence;  
  84.     }  
  85.   
  86.     public double getSmilingValue() {  
  87.         return smilingValue;  
  88.     }  
  89.   
  90.     public void setSmilingValue(double smilingValue) {  
  91.         this.smilingValue = smilingValue;  
  92.     }  
  93.   
  94.     public double getCenterX() {  
  95.         return centerX;  
  96.     }  
  97.   
  98.     public void setCenterX(double centerX) {  
  99.         this.centerX = centerX;  
  100.     }  
  101.   
  102.     public double getCenterY() {  
  103.         return centerY;  
  104.     }  
  105.   
  106.     public void setCenterY(double centerY) {  
  107.         this.centerY = centerY;  
  108.     }  
  109.   
  110.     // 根據人臉中心點坐標從左至右排序  
  111.     @Override  
  112.     public int compareTo(Face face) {  
  113.         int result = 0;  
  114.         if (this.getCenterX() > face.getCenterX())  
  115.             result = 1;  
  116.         else  
  117.             result = -1;  
  118.         return result;  
  119.     }  
  120. }  
與普通Java類不同的是, Face類實現了Comparable接口,並實現了該接口的compareTo()方法,這正是Java中對象排序的關鍵所在。 112-119行代碼是通過比較每個Face的臉部中心點的橫坐標來決定對象的排序方式,這樣能夠實現檢測出的多個Face按從左至右的先后順序進行排序。

        接下來,是人臉檢測API的調用及相關處理邏輯,筆者將這些實現全部封裝在FaceService類中,該類的完整實現如下:

[java]  view plain copy 在CODE上查看代碼片 派生到我的代碼片
  1. package org.liufeng.course.service;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.InputStream;  
  5. import java.io.InputStreamReader;  
  6. import java.net.HttpURLConnection;  
  7. import java.net.URL;  
  8. import java.util.ArrayList;  
  9. import java.util.Collections;  
  10. import java.util.List;  
  11. import org.liufeng.course.pojo.Face;  
  12. import net.sf.json.JSONArray;  
  13. import net.sf.json.JSONObject;  
  14.   
  15. /** 
  16.  * 人臉檢測服務 
  17.  *  
  18.  * @author liufeng 
  19.  * @date 2013-12-18 
  20.  */  
  21. public class FaceService {  
  22.     /** 
  23.      * 發送http請求 
  24.      *  
  25.      * @param requestUrl 請求地址 
  26.      * @return String 
  27.      */  
  28.     private static String httpRequest(String requestUrl) {  
  29.         StringBuffer buffer = new StringBuffer();  
  30.         try {  
  31.             URL url = new URL(requestUrl);  
  32.             HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection();  
  33.             httpUrlConn.setDoInput(true);  
  34.             httpUrlConn.setRequestMethod("GET");  
  35.             httpUrlConn.connect();  
  36.             // 將返回的輸入流轉換成字符串  
  37.             InputStream inputStream = httpUrlConn.getInputStream();  
  38.             InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");  
  39.             BufferedReader bufferedReader = new BufferedReader(inputStreamReader);  
  40.   
  41.             String str = null;  
  42.             while ((str = bufferedReader.readLine()) != null) {  
  43.                 buffer.append(str);  
  44.             }  
  45.             bufferedReader.close();  
  46.             inputStreamReader.close();  
  47.             // 釋放資源  
  48.             inputStream.close();  
  49.             inputStream = null;  
  50.             httpUrlConn.disconnect();  
  51.   
  52.         } catch (Exception e) {  
  53.             e.printStackTrace();  
  54.         }  
  55.         return buffer.toString();  
  56.     }  
  57.   
  58.     /** 
  59.      * 調用Face++ API實現人臉檢測 
  60.      *  
  61.      * @param picUrl 待檢測圖片的訪問地址 
  62.      * @return List<Face> 人臉列表 
  63.      */  
  64.     private static List<Face> faceDetect(String picUrl) {  
  65.         List<Face> faceList = new ArrayList<Face>();  
  66.         try {  
  67.             // 拼接Face++人臉檢測的請求地址  
  68.             String queryUrl = "http://apicn.faceplusplus.com/v2/detection/detect?url=URL&api_secret=API_SECRET&api_key=API_KEY";  
  69.             // 對URL進行編碼  
  70.             queryUrl = queryUrl.replace("URL", java.net.URLEncoder.encode(picUrl, "UTF-8"));  
  71.             queryUrl = queryUrl.replace("API_KEY""替換成自己的API Key");  
  72.             queryUrl = queryUrl.replace("API_SECRET""替換成自己的API Secret");  
  73.             // 調用人臉檢測接口  
  74.             String json = httpRequest(queryUrl);  
  75.             // 解析返回json中的Face列表  
  76.             JSONArray jsonArray = JSONObject.fromObject(json).getJSONArray("face");  
  77.             // 遍歷檢測到的人臉  
  78.             for (int i = 0; i < jsonArray.size(); i++) {  
  79.                 // face  
  80.                 JSONObject faceObject = (JSONObject) jsonArray.get(i);  
  81.                 // attribute  
  82.                 JSONObject attrObject = faceObject.getJSONObject("attribute");  
  83.                 // position  
  84.                 JSONObject posObject = faceObject.getJSONObject("position");  
  85.                 Face face = new Face();  
  86.                 face.setFaceId(faceObject.getString("face_id"));  
  87.                 face.setAgeValue(attrObject.getJSONObject("age").getInt("value"));  
  88.                 face.setAgeRange(attrObject.getJSONObject("age").getInt("range"));  
  89.                 face.setGenderValue(genderConvert(attrObject.getJSONObject("gender").getString("value")));  
  90.                 face.setGenderConfidence(attrObject.getJSONObject("gender").getDouble("confidence"));  
  91.                 face.setRaceValue(raceConvert(attrObject.getJSONObject("race").getString("value")));  
  92.                 face.setRaceConfidence(attrObject.getJSONObject("race").getDouble("confidence"));  
  93.                 face.setSmilingValue(attrObject.getJSONObject("smiling").getDouble("value"));  
  94.                 face.setCenterX(posObject.getJSONObject("center").getDouble("x"));  
  95.                 face.setCenterY(posObject.getJSONObject("center").getDouble("y"));  
  96.                 faceList.add(face);  
  97.             }  
  98.             // 將檢測出的Face按從左至右的順序排序  
  99.             Collections.sort(faceList);  
  100.         } catch (Exception e) {  
  101.             faceList = null;  
  102.             e.printStackTrace();  
  103.         }  
  104.         return faceList;  
  105.     }  
  106.   
  107.     /** 
  108.      * 性別轉換(英文->中文) 
  109.      *  
  110.      * @param gender 
  111.      * @return 
  112.      */  
  113.     private static String genderConvert(String gender) {  
  114.         String result = "男性";  
  115.         if ("Male".equals(gender))  
  116.             result = "男性";  
  117.         else if ("Female".equals(gender))  
  118.             result = "女性";  
  119.   
  120.         return result;  
  121.     }  
  122.   
  123.     /** 
  124.      * 人種轉換(英文->中文) 
  125.      *  
  126.      * @param race 
  127.      * @return 
  128.      */  
  129.     private static String raceConvert(String race) {  
  130.         String result = "黃色";  
  131.         if ("Asian".equals(race))  
  132.             result = "黃色";  
  133.         else if ("White".equals(race))  
  134.             result = "白色";  
  135.         else if ("Black".equals(race))  
  136.             result = "黑色";  
  137.         return result;  
  138.     }  
  139.   
  140.     /** 
  141.      * 根據人臉識別結果組裝消息 
  142.      *  
  143.      * @param faceList 人臉列表 
  144.      * @return 
  145.      */  
  146.     private static String makeMessage(List<Face> faceList) {  
  147.         StringBuffer buffer = new StringBuffer();  
  148.         // 檢測到1張臉  
  149.         if (1 == faceList.size()) {  
  150.             buffer.append("共檢測到 ").append(faceList.size()).append(" 張人臉").append("\n");  
  151.             for (Face face : faceList) {  
  152.                 buffer.append(face.getRaceValue()).append("人種,");  
  153.                 buffer.append(face.getGenderValue()).append(",");  
  154.                 buffer.append(face.getAgeValue()).append("歲左右").append("\n");  
  155.             }  
  156.         }  
  157.         // 檢測到2-10張臉  
  158.         else if (faceList.size() > 1 && faceList.size() <= 10) {  
  159.             buffer.append("共檢測到 ").append(faceList.size()).append(" 張人臉,按臉部中心位置從左至右依次為:").append("\n");  
  160.             for (Face face : faceList) {  
  161.                 buffer.append(face.getRaceValue()).append("人種,");  
  162.                 buffer.append(face.getGenderValue()).append(",");  
  163.                 buffer.append(face.getAgeValue()).append("歲左右").append("\n");  
  164.             }  
  165.         }  
  166.         // 檢測到10張臉以上  
  167.         else if (faceList.size() > 10) {  
  168.             buffer.append("共檢測到 ").append(faceList.size()).append(" 張人臉").append("\n");  
  169.             // 統計各人種、性別的人數  
  170.             int asiaMale = 0;  
  171.             int asiaFemale = 0;  
  172.             int whiteMale = 0;  
  173.             int whiteFemale = 0;  
  174.             int blackMale = 0;  
  175.             int blackFemale = 0;  
  176.             for (Face face : faceList) {  
  177.                 if ("黃色".equals(face.getRaceValue()))  
  178.                     if ("男性".equals(face.getGenderValue()))  
  179.                         asiaMale++;  
  180.                     else  
  181.                         asiaFemale++;  
  182.                 else if ("白色".equals(face.getRaceValue()))  
  183.                     if ("男性".equals(face.getGenderValue()))  
  184.                         whiteMale++;  
  185.                     else  
  186.                         whiteFemale++;  
  187.                 else if ("黑色".equals(face.getRaceValue()))  
  188.                     if ("男性".equals(face.getGenderValue()))  
  189.                         blackMale++;  
  190.                     else  
  191.                         blackFemale++;  
  192.             }  
  193.             if (0 != asiaMale || 0 != asiaFemale)  
  194.                 buffer.append("黃色人種:").append(asiaMale).append("男").append(asiaFemale).append("女").append("\n");  
  195.             if (0 != whiteMale || 0 != whiteFemale)  
  196.                 buffer.append("白色人種:").append(whiteMale).append("男").append(whiteFemale).append("女").append("\n");  
  197.             if (0 != blackMale || 0 != blackFemale)  
  198.                 buffer.append("黑色人種:").append(blackMale).append("男").append(blackFemale).append("女").append("\n");  
  199.         }  
  200.         // 移除末尾空格  
  201.         buffer = new StringBuffer(buffer.substring(0, buffer.lastIndexOf("\n")));  
  202.         return buffer.toString();  
  203.     }  
  204.   
  205.     /** 
  206.      * 提供給外部調用的人臉檢測方法 
  207.      *  
  208.      * @param picUrl 待檢測圖片的訪問地址 
  209.      * @return String 
  210.      */  
  211.     public static String detect(String picUrl) {  
  212.         // 默認回復信息  
  213.         String result = "未識別到人臉,請換一張清晰的照片再試!";  
  214.         List<Face> faceList = faceDetect(picUrl);  
  215.         if (null != faceList) {  
  216.             result = makeMessage(faceList);  
  217.         }  
  218.         return result;  
  219.     }  
  220.   
  221.     public static void main(String[] args) {  
  222.         String picUrl = "http://pic11.nipic.com/20101111/6153002_002722872554_2.jpg";  
  223.         System.out.println(detect(picUrl));  
  224.     }  
  225. }  
上述代碼雖然多,但條理很清晰,並不難理解,所以筆者只挑重點的進行講解,主要說明如下:

1)70行:參數url表示圖片的鏈接,由於鏈接中存在特殊字符,作為參數傳遞時必須進行URL編碼。請讀者記住:不管是什么應用,調用什么接口,凡是通過GET傳遞的參數中可能會包含特殊字符,都必須進行URL編碼,除了中文以外,特殊字符還包括等號“=”、與“&”、空格“ ”等。

2)76-97行:使用JSON-lib解析人臉檢測接口返回的JSON數據,並將解析結果存入List中。

3)99行:對集合中的對象進行排序,使用Collections.sort()方法排序的前提是集合中的Face對象實現了Comparable接口

4)146-203行:組裝返回給用戶的消息內容。考慮到公眾平台的文本消息內容長度有限制,當一張圖片中識別出的人臉過多,則只返回一些匯總信息給用戶。

5)211-219行:detect()方法是public的,提供給其他類調用。筆者可以在本地的開發工具中運行上面的main()方法,測試detect()方法的輸出。


公眾賬號后台的實現

在公眾賬號后台的CoreService類中,需要對用戶發送的消息類型進行判斷,如果是圖片消息,則調用人臉檢測方法進行分析,如果是其他消息,則返回人臉檢測的使用指南。CoreService類的完整代碼如下:

[java]  view plain copy 在CODE上查看代碼片 派生到我的代碼片
  1. package org.liufeng.course.service;  
  2.   
  3. import java.util.Date;  
  4. import java.util.Map;  
  5. import javax.servlet.http.HttpServletRequest;  
  6. import org.liufeng.course.message.resp.TextMessage;  
  7. import org.liufeng.course.util.MessageUtil;  
  8.   
  9. /** 
  10.  * 核心服務類 
  11.  *  
  12.  * @author liufeng 
  13.  * @date 2013-12-19 
  14.  */  
  15. public class CoreService {  
  16.     /** 
  17.      * 處理微信發來的請求 
  18.      */  
  19.     public static String processRequest(HttpServletRequest request) {  
  20.         // 返回給微信服務器的xml消息  
  21.         String respXml = null;  
  22.         try {  
  23.             // xml請求解析  
  24.             Map<String, String> requestMap = MessageUtil.parseXml(request);  
  25.             // 發送方帳號(open_id)  
  26.             String fromUserName = requestMap.get("FromUserName");  
  27.             // 公眾帳號  
  28.             String toUserName = requestMap.get("ToUserName");  
  29.             // 消息類型  
  30.             String msgType = requestMap.get("MsgType");  
  31.   
  32.             // 回復文本消息  
  33.             TextMessage textMessage = new TextMessage();  
  34.             textMessage.setToUserName(fromUserName);  
  35.             textMessage.setFromUserName(toUserName);  
  36.             textMessage.setCreateTime(new Date().getTime());  
  37.             textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);  
  38.   
  39.             // 圖片消息  
  40.             if (MessageUtil.REQ_MESSAGE_TYPE_IMAGE.equals(msgType)) {  
  41.                 // 取得圖片地址  
  42.                 String picUrl = requestMap.get("PicUrl");  
  43.                 // 人臉檢測  
  44.                 String detectResult = FaceService.detect(picUrl);  
  45.                 textMessage.setContent(detectResult);  
  46.             }  
  47.             // 其它類型的消息  
  48.             else  
  49.                 textMessage.setContent(getUsage());  
  50.   
  51.             respXml = MessageUtil.textMessageToXml(textMessage);  
  52.         } catch (Exception e) {  
  53.             e.printStackTrace();  
  54.         }  
  55.         return respXml;  
  56.     }  
  57.   
  58.     /** 
  59.      * 人臉檢測幫助菜單 
  60.      */  
  61.     public static String getUsage() {  
  62.         StringBuffer buffer = new StringBuffer();  
  63.         buffer.append("人臉檢測使用指南").append("\n\n");  
  64.         buffer.append("發送一張清晰的照片,就能幫你分析出種族、年齡、性別等信息").append("\n");  
  65.         buffer.append("快來試試你是不是長得太着急");  
  66.         return buffer.toString();  
  67.     }  
  68. }  
到這里,人臉檢測應用就全部開發完成了,整個項目的完整結構如下:

        

運行結果如下:

         

筆者用自己的相片測試了兩次,測試結果分別是26歲、30歲,這與筆者的實際年齡相差不大,可見,Face++的人臉檢測准確度還是比較高的。為了增加人臉檢測應用的趣味性和娛樂性,筆者忽略了年齡估計值的正負區間。讀者可以充分發揮自己的想像力和創造力,使用Face++ API實現更多實用、有趣的功能。應用開發不是簡單的接口調用!

(沒有展開的代碼統統和前面幾篇介紹開發模式、消息封裝的代碼相同,沒看的返回看前幾篇)



注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com