教程地址:請關注我的https://edu.csdn.net/lecturer/1742
Java寫一個簡單的手勢識別程序,這裏採用百度是AI,視覺技術中的人體分析中的手勢識別,識別圖片中的手勢類型,返回手勢名稱、手勢矩形框、概率分數,可識別24種手勢,支持動態手勢識別,適用於手勢特效、智能家居手勢交互等場景;支持的手勢列表:拳頭、OK、祈禱、作揖、作別、單手比心、點贊、diss、我愛你、rock、掌心向上、豎中指、雙手比心(3種)、數字(9種);
請求URL數據格式
向API服務地址使用POST發送請求,必須在URL中帶上參數:
access_token:必須參數,參考“Access Token獲取”。
注意:access_token的有效期爲30天,切記需要每30天進行定期更換,或者每次請求都拉取新token。
- 手勢識別接口示例代碼-(JavaAPI)
import java.net.URLEncoder; import com.alibaba.fastjson.JSON; import com.xs.body.bean.GestureBean; import com.xs.util.baidu.Base64Util; import com.xs.util.baidu.FileUtil; import com.xs.util.baidu.HttpUtil; /** * 手勢識別Java-API調用示例代碼 * Base64Util、FileUtil、HttpUtil工具類下載地址 * http://aixiaoshuai.mydoc.io/?t=234826 * @author 小帥丶 */ public class GestureAPISample { public static String GESTURE_URL = "https://aip.baidubce.com/rest/2.0/image-classify/v1/gesture"; public static void main(String[] args) throws Exception { //返回字符串 // String result = getGestureResult("G:/gesture/搖滾.jpg", "自己的token"); // System.out.println(result); //返回java對象 GestureBean gestureBean = getGestureBean("G:/ht.jpg", "自己的token"); System.out.println("識別個數:"+gestureBean.getResult_num()); String gestureName = ""; for (int i = 0; i < gestureBean.getResult().size(); i++) { if(gestureBean.getResult().get(i).getClassname().equals("Face")){ System.out.println("此圖中識別出人臉"); }else{ gestureName += GestureClassNameWorkBook.getGestureName(gestureBean.getResult().get(i).getClassname())+","; } } System.out.println("識別的手勢:"+gestureName.substring(0, gestureName.length()-1)); } /** * 識別圖片中的手勢類型,返回手勢名稱、手勢矩形框、概率分數,可識別15種手勢,支持動態手勢識別,適用於手勢特效、智能家居手勢交互等場景; * 支持的15類手勢列表:手指、掌心向前、拳頭、OK、祈禱、作揖、作別、單手比心、點贊、diss、rock、掌心向上、雙手比心(3種)。 * @param imagePath 圖片本地路徑 * @param accessToken 應用AccessToken * @return String * @throws Exception */ private static String getGestureResult(String imagePath, String accessToken) throws Exception { byte[] imgData = FileUtil.readFileByBytes(imagePath); String imgStr = Base64Util.encode(imgData); String param = "image=" + URLEncoder.encode(imgStr,"UTF-8"); // 注意這裏僅爲了簡化編碼每一次請求都去獲取access_token,線上環境access_token有過期時間, 客戶端可自行緩存,過期後重新獲取。 String result = HttpUtil.post(GESTURE_URL, accessToken, param); return result; } /** * 識別圖片中的手勢類型,返回手勢名稱、手勢矩形框、概率分數,可識別15種手勢,支持動態手勢識別,適用於手勢特效、智能家居手勢交互等場景; * 支持的15類手勢列表:手指、掌心向前、拳頭、OK、祈禱、作揖、作別、單手比心、點贊、diss、rock、掌心向上、雙手比心(3種)。 * @param imagePath 圖片本地路徑 * @param accessToken 應用AccessToken * @return GestureBean * @throws Exception */ private static GestureBean getGestureBean(String imagePath, String accessToken) throws Exception { byte[] imgData = FileUtil.readFileByBytes(imagePath); String imgStr = Base64Util.encode(imgData); String param = "image=" + URLEncoder.encode(imgStr,"UTF-8"); // 注意這裏僅爲了簡化編碼每一次請求都去獲取access_token,線上環境access_token有過期時間, 客戶端可自行緩存,過期後重新獲取。 String result = HttpUtil.post(GESTURE_URL, accessToken, param); GestureBean gestureBean = JSON.parseObject(result,GestureBean.class); return gestureBean; } }
- 處理後返回的內容
識別個數:2 識別的手勢:拳頭,掌心向前
- 識別返回的JSON數據 可以看到識別出2個手勢 一個爲Fist 另一個爲Palm
{ "log_id": 3773186178434508300, "result_num": 2, "result": [ { "probability": 0.9931142926216125, "top": 153, "height": 299, "classname": "Fist", "width": 269, "left": 499 }, { "probability": 0.9748011231422424, "top": 44, "height": 455, "classname": "Palm", "width": 423, "left": 86 } ] }
- 需要用到的GestureBean
import java.util.List; /** * 手勢Bean 省略set/get * @author 小帥丶 */ public class GestureBean { //手勢數目 private int result_num; //檢測到的目標,手勢、人臉 private List<Result> result; //唯一的log id,用於問題定位 private long log_id; /** * classname 目標所屬類別,15種手勢、other、face * top 目標框上座標 * widt 目標框的寬 * left 目標框最左座標 * height 目標框的高 * probability 目標屬於該類別的概率 * @author 小帥丶 */ public static class Result{ private double probability; private int top; private int height; private String classname; private int width; private int left; } }
- classname轉中文常量代碼
package com.xs.body; /** * 手勢中文說明 * @author 小帥丶 * */ public class GestureClassNameWorkBook { /** * 根據classname返回中文對應的名稱 * @param classname 手勢所屬類別,15種手勢、other、face * @return String * @throws Exception */ public static String getGestureName(String classname) throws Exception { String gestureName =""; if(classname.equals("Thumb_down")){ gestureName="踩|拇指向下"; return gestureName; }else if (classname.equals("Ok")) { gestureName="OK"; return gestureName; }else if (classname.equals("ILY")) { gestureName="Rock"; return gestureName; }else if (classname.equals("Heart_single")) { gestureName="單手比心"; return gestureName; }else if (classname.equals("Thumb_up")) { gestureName="點贊|拇指向上"; return gestureName; }else if (classname.equals("Prayer")) { gestureName="祈禱"; return gestureName; }else if (classname.equals("Fist")) { gestureName="拳頭"; return gestureName; }else if (classname.equals("Point")) { gestureName="點|食指"; return gestureName; }else if (classname.equals("Heart_1")||classname.equals("Heart_2")||classname.equals("Heart_3")) { gestureName="雙手比心"; return gestureName; }else if (classname.equals("Palm")) { gestureName="掌心向前"; return gestureName; }else if (classname.equals("Palm_up")) { gestureName="掌心向上"; return gestureName; }else if (classname.equals("Honour")) { gestureName="作別|告別"; return gestureName; }else if (classname.equals("Rock")) { gestureName="搖滾"; return gestureName; }else if (classname.equals("Congratulation")) { gestureName="作揖|祝賀"; return gestureName; }else{ gestureName ="未能匹配的手勢:"+classname; return gestureName; } } }
- 需要用到的第三方的Jar
fastjson json
獲取access_token示例代碼:
package com.baidu.ai.aip.auth;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;
/**
* 獲取token類
*/
public class AuthService {
/**
* 獲取權限token
* @return 返回示例:
* {
* "access_token": "24.460da4889caad24cccdb1fea17221975.2592000.1491995545.282335-1234567",
* "expires_in": 2592000
* }
*/
public static String getAuth() {
// 官網獲取的 API Key 更新爲你註冊的
String clientId = "百度雲應用的AK";
// 官網獲取的 Secret Key 更新爲你註冊的
String clientSecret = "百度雲應用的SK";
return getAuth(clientId, clientSecret);
}
/**
* 獲取API訪問token
* 該token有一定的有效期,需要自行管理,當失效時需重新獲取.
* @param ak - 百度雲官網獲取的 API Key
* @param sk - 百度雲官網獲取的 Securet Key
* @return assess_token 示例:
* "24.460da4889caad24cccdb1fea17221975.2592000.1491995545.282335-1234567"
*/
public static String getAuth(String ak, String sk) {
// 獲取token地址
String authHost = "https://aip.baidubce.com/oauth/2.0/token?";
String getAccessTokenUrl = authHost
// 1. grant_type爲固定參數
+ "grant_type=client_credentials"
// 2. 官網獲取的 API Key
+ "&client_id=" + ak
// 3. 官網獲取的 Secret Key
+ "&client_secret=" + sk;
try {
URL realUrl = new URL(getAccessTokenUrl);
// 打開和URL之間的連接
HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();
connection.setRequestMethod("GET");
connection.connect();
// 獲取所有響應頭字段
Map<String, List<String>> map = connection.getHeaderFields();
// 遍歷所有的響應頭字段
for (String key : map.keySet()) {
System.err.println(key + "--->" + map.get(key));
}
// 定義 BufferedReader輸入流來讀取URL的響應
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String result = "";
String line;
while ((line = in.readLine()) != null) {
result += line;
}
/**
* 返回結果示例
*/
System.err.println("result:" + result);
JSONObject jsonObject = new JSONObject(result);
String access_token = jsonObject.getString("access_token");
return access_token;
} catch (Exception e) {
System.err.printf("獲取token失敗!");
e.printStackTrace(System.err);
}
return null;
}
}