【征稿计划第三期】人体关键点识别
风搅火 发布于2019-09-15 浏览:1760 回复:1
0
收藏
最后编辑于2019-09-16

【使用攻略】【人体关键点识别】

人体关键点识别:检测图像中的人体并返回人体矩形框位置,精准定位21个核心关键点,包含头顶、五官、颈部、四肢主要关节部位,支持多人检测、大动作等复杂场景

功能接入:
点击OCR功能链接:https://console.bce.baidu.com/ai/?fromai=1#/ai/body/overview/index
进入界面后点击“创建应用”

输入应用信息即可。


百度现在提供每天一定量的免费调用额度,足够大家测试使用了。


获取Access Token
调用人体关键点识别功能前需要先调用鉴权API,确保安全。
具体说明请查阅:http://ai.baidu.com/docs#/Auth/top

请求URL数据格式
向授权服务地址https://aip.baidubce.com/oauth/2.0/token发送请求(推荐使用POST),并在URL中带上以下参数:
grant_type: 必须参数,固定为client_credentials;
client_id: 必须参数,应用的API Key;
client_secret: 必须参数,应用的Secret Key;
例如:
https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=Va5yQRHlA4Fq5eR3LT0vuXV4&client_secret=0rDSjzQ20XUj5itV6WRtznPQSzr5pVw2&


人体关键点识别AP调用
人体关键点识别的API说明链接为:https://ai.baidu.com/docs#/Body-API/b717c300

接口描述
对于输入的一张图片(可正常解码,且长宽比适宜),检测图片中的所有人体,输出每个人体的21个主要关键点,包含头顶、五官、脖颈、四肢等部位,同时输出人体的坐标信息和数量。
支持多人检测、人体位置重叠、遮挡、背面、侧面、中低空俯拍、大动作等复杂场景。
21个关键点的位置:头顶、左耳、右耳、左眼、右眼、鼻子、左嘴角、右嘴角、脖子、左肩、右肩、左手肘、右手肘、左手腕、右手腕、左髋部、右髋部、左膝、右膝、左脚踝、右脚踝。示意图如下,正在持续扩展更多关键点,敬请期待。

请求说明
请求URL: https://aip.baidubce.com/rest/2.0/image-classify/v1/body_analysis

具体参数:


返回说明:
1、body_parts,一共21个part,每个part包含x,y两个坐标,如果part被截断,则x、y坐标为part被截断的图片边界位置,part顺序以实际返回顺序为准。
2、接口返回人体坐标框和每个关键点的置信度分数,在应用时可综合置信度score分数,过滤掉置信度低的“无效人体”,建议过滤方法:当关键点得分大于0.2的个数大于3,且人体框的分数大于0.03时,才认为是有效人体。实际应用中,可根据对误识别、漏识别的容忍程度,调整阈值过滤方案,灵活应用。
返回示例
{
"person_num": 2,
"person_info": [
{
"body_parts": {
"left_hip": {
"y": 573,
"x": 686.09375,
"score": 0.78743487596512
},
"top_head": {
"y": 242.53125,
"x": 620,
"score": 0.87757384777069
},
"right_mouth_corner": {
"y": 308.625,
"x": 606.78125,
"score": 0.90121293067932
},
"neck": {
"y": 335.0625,
"x": 620,
"score": 0.84662038087845
},
"left_shoulder": {
"y": 361.5,
"x": 699.3125,
"score": 0.83550786972046
},
"left_knee": {
"y": 731.625,
"x": 699.3125,
"score": 0.83575332164764
},
"left_ankle": {
"y": 877.03125,
"x": 725.75,
"score": 0.85220056772232
},
"left_mouth_corner": {
"y": 308.625,
"x": 633.21875,
"score": 0.91475087404251
},
"right_elbow": {
"y": 348.28125,
"x": 461.375,
"score": 0.81766486167908
},
"right_ear": {
"y": 282.1875,
"x": 593.5625,
"score": 0.86551451683044
},
"nose": {
"y": 295.40625,
"x": 620,
"score": 0.90894532203674
},
"left_eye": {
"y": 282.1875,
"x": 633.21875,
"score": 0.89628517627716
},
"right_eye": {
"y": 282.1875,
"x": 606.78125,
"score": 0.89676940441132
},
"right_hip": {
"y": 586.21875,
"x": 593.5625,
"score": 0.79803824424744
},
"left_wrist": {
"y": 374.71875,
"x": 884.375,
"score": 0.89635348320007
},
"left_ear": {
"y": 295.40625,
"x": 659.65625,
"score": 0.86607384681702
},
"left_elbow": {
"y": 361.5,
"x": 791.84375,
"score": 0.83910942077637
},
"right_shoulder": {
"y": 348.28125,
"x": 553.90625,
"score": 0.85635334253311
},
"right_ankle": {
"y": 890.25,
"x": 580.34375,
"score": 0.85149073600769
},
"right_knee": {
"y": 744.84375,
"x": 580.34375,
"score": 0.83749794960022
},
"right_wrist": {
"y": 348.28125,
"x": 368.84375,
"score": 0.83893859386444
}
},
"location": {
"height": 703.20654296875,
"width": 652.61810302734,
"top": 221.92272949219,
"score": 0.99269664287567,
"left": 294.03039550781
}
},
{
"body_parts": {
"left_hip": {
"y": 576,
"x": 1239.5625,
"score": 0.84608125686646
},
"top_head": {
"y": 261.15625,
"x": 1176.59375,
"score": 0.871442258358
},
"right_mouth_corner": {
"y": 336.71875,
"x": 1164,
"score": 0.90951544046402
},
"neck": {
"y": 361.90625,
"x": 1176.59375,
"score": 0.85904294252396
},
"left_shoulder": {
"y": 361.90625,
"x": 1239.5625,
"score": 0.8512310385704
},
"left_knee": {
"y": 714.53125,
"x": 1277.34375,
"score": 0.82312393188477
},
"left_ankle": {
"y": 853.0625,
"x": 1315.125,
"score": 0.83786374330521
},
"left_mouth_corner": {
"y": 336.71875,
"x": 1189.1875,
"score": 0.90610301494598
},
"right_elbow": {
"y": 387.09375,
"x": 1025.46875,
"score": 0.88956367969513
},
"right_ear": {
"y": 311.53125,
"x": 1138.8125,
"score": 0.86518502235413
},
"nose": {
"y": 324.125,
"x": 1176.59375,
"score": 0.9168484210968
},
"left_eye": {
"y": 311.53125,
"x": 1189.1875,
"score": 0.91715461015701
},
"right_eye": {
"y": 311.53125,
"x": 1164,
"score": 0.90343600511551
},
"right_hip": {
"y": 576,
"x": 1164,
"score": 0.81976848840714
},
"left_wrist": {
"y": 298.9375,
"x": 1378.09375,
"score": 0.86095398664474
},
"left_ear": {
"y": 311.53125,
"x": 1201.78125,
"score": 0.86899447441101
},
"left_elbow": {
"y": 324.125,
"x": 1315.125,
"score": 0.89198768138885
},
"right_shoulder": {
"y": 387.09375,
"x": 1101.03125,
"score": 0.85161662101746
},
"right_ankle": {
"y": 878.25,
"x": 1151.40625,
"score": 0.83667933940887
},
"right_knee": {
"y": 727.125,
"x": 1151.40625,
"score": 0.85485708713531
},
"right_wrist": {
"y": 387.09375,
"x": 949.90625,
"score": 0.83042001724243
}
},
"location": {
"height": 670.80139160156,
"width": 524.25476074219,
"top": 241.42504882812,
"score": 0.98725789785385,
"left": 902.15216064453
}
}
],
"log_id": "6362401025381690607"
}


详细代码(C#):

  public static class AccessToken
	{
	    // 调用getAccessToken()获取的 access_token建议根据expires_in 时间 设置缓存
	    // 返回token示例
     // 百度云中开通对应服务应用的 API Key 建议开通应用的时候多选服务
		private static String clientId = "你获得的ID";
		// 百度云中开通对应服务应用的 Secret Key
		private static String clientSecret = "你获得的KEY";

		public static String getAccessToken() {
			String authHost = "https://aip.baidubce.com/oauth/2.0/token";
			HttpClient client = new HttpClient();
			List> paraList = new List>();
			paraList.Add(new KeyValuePair("grant_type", "client_credentials"));
			paraList.Add(new KeyValuePair("client_id", clientId));
			paraList.Add(new KeyValuePair("client_secret", clientSecret));

			HttpResponseMessage response = client.PostAsync(authHost, new FormUrlEncodedContent(paraList)).Result;
			String result = response.Content.ReadAsStringAsync().Result;
			Console.WriteLine(result);
            JObject jobject = (JObject)JsonConvert.DeserializeObject(result);
            string token = jobject["access_token"].ToString();
            return token;
			//return result;
		}
		public class BodyAnalysis
    {
        // 人体关键点识别
       public static string bodyAnalysis(String imagefilename)
        {
            string token = AccessToken.getAccessToken();
            Console.WriteLine(token);
            string host = "https://aip.baidubce.com/rest/2.0/image-classify/v1/body_analysis?access_token=" + token;
            Encoding encoding = Encoding.Default;
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(host);
            request.Method = "post";
            request.KeepAlive = true;
            // 图片的base64编码
            string base64 = getFileBase64(imagefilename);
            String str = "image=" + HttpUtility.UrlEncode(base64);
            byte[] buffer = encoding.GetBytes(str);
            request.ContentLength = buffer.Length;
            request.GetRequestStream().Write(buffer, 0, buffer.Length);
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.Default);
            string result = reader.ReadToEnd();
            Console.WriteLine("分析结果:");
            Console.WriteLine(result);
            return result;
        }


        public static String getFileBase64(String fileName) {
            FileStream filestream = new FileStream(fileName, FileMode.Open);
            byte[] arr = new byte[filestream.Length];
            filestream.Read(arr, 0, (int)filestream.Length);
            string baser64 = Convert.ToBase64String(arr);
            filestream.Close();
            return baser64;
        }
    }

功能测试:

返回结果

{"person_num": 2, "person_info": [{"body_parts": {"left_hip": {"y": 236.125, "x": 312.0, "score": 0.8076009750366211}, "top_head": {"y": 59.5625, "x": 319.0625, "score": 0.8812817335128784}, "right_mouth_corner": {"y": 94.875, "x": 297.875, "score": 0.7361928224563599}, "neck": {"y": 101.9375, "x": 326.125, "score": 0.8763977289199829}, "left_shoulder": {"y": 123.125, "x": 290.8125, "score": 0.8646792769432068}, "left_knee": {"y": 313.8125, "x": 312.0, "score": 0.8524078130722046}, "left_ankle": {"y": 398.5625, "x": 319.0625, "score": 0.7862233519554138}, "left_mouth_corner": {"y": 94.875, "x": 304.9375, "score": 0.7294610738754272}, "right_elbow": {"y": 172.5625, "x": 396.75, "score": 0.8090545535087585}, "right_ear": {"y": 87.8125, "x": 333.1875, "score": 0.8393241167068481}, "nose": {"y": 87.8125, "x": 297.875, "score": 0.8581699728965759}, "left_eye": {"y": 80.75, "x": 304.9375, "score": 0.8476552367210388}, "right_eye": {"y": 80.75, "x": 297.875, "score": 0.7916366457939148}, "right_hip": {"y": 236.125, "x": 347.3125, "score": 0.8387147188186646}, "left_wrist": {"y": 193.75, "x": 227.25, "score": 0.8242149949073792}, "left_ear": {"y": 80.75, "x": 319.0625, "score": 0.8044617772102356}, "left_elbow": {"y": 165.5, "x": 262.5625, "score": 0.7947859764099121}, "right_shoulder": {"y": 130.1875, "x": 361.4375, "score": 0.8196337223052979}, "right_ankle": {"y": 363.25, "x": 347.3125, "score": 0.8110532760620117}, "right_knee": {"y": 292.625, "x": 340.25, "score": 0.845771074295044}, "right_wrist": {"y": 214.9375, "x": 410.875, "score": 0.8344536423683167}}, "location": {"height": 376.4992980957031, "width": 228.4523773193359, "top": 50.31480407714844, "score": 0.999314546585083, "left": 198.7234191894531}}, {"body_parts": {"left_hip": {"y": 219.0, "x": 105.40625, "score": 0.8145551085472107}, "top_head": {"y": 49.46875, "x": 132.53125, "score": 0.8663356900215149}, "right_mouth_corner": {"y": 90.15625, "x": 146.09375, "score": 0.8473300933837891}, "neck": {"y": 96.9375, "x": 118.96875, "score": 0.8699936270713806}, "left_shoulder": {"y": 117.28125, "x": 85.0625, "score": 0.7904418706893921}, "left_knee": {"y": 286.8125, "x": 118.96875, "score": 0.6598986387252808}, "left_ankle": {"y": 313.9375, "x": 118.96875, "score": 0.8089110255241394}, "left_mouth_corner": {"y": 90.15625, "x": 146.09375, "score": 0.8620769381523132}, "right_elbow": {"y": 171.53125, "x": 159.65625, "score": 0.8686186075210571}, "right_ear": {"y": 76.59375, "x": 125.75, "score": 0.8651143312454224}, "nose": {"y": 83.375, "x": 152.875, "score": 0.8689935803413391}, "left_eye": {"y": 76.59375, "x": 152.875, "score": 0.8549364805221558}, "right_eye": {"y": 76.59375, "x": 146.09375, "score": 0.9198991060256958}, "right_hip": {"y": 219.0, "x": 139.3125, "score": 0.822985053062439}, "left_wrist": {"y": 185.09375, "x": 125.75, "score": 0.3645369112491608}, "left_ear": {"y": 76.59375, "x": 112.1875, "score": 0.6177537441253662}, "left_elbow": {"y": 171.53125, "x": 91.84375, "score": 0.6671625375747681}, "right_shoulder": {"y": 117.28125, "x": 146.09375, "score": 0.8579935431480408}, "right_ankle": {"y": 374.96875, "x": 132.53125, "score": 0.8338804841041565}, "right_knee": {"y": 293.59375, "x": 139.3125, "score": 0.8524692058563232}, "right_wrist": {"y": 205.4375, "x": 200.34375, "score": 0.8065598607063293}}, "location": {"height": 360.5743713378906, "width": 163.5292663574219, "top": 43.69062805175781, "score": 0.9966723322868347, "left": 63.1578254699707}}], "log_id": 509355340872423951}

渲染后如图所示:

 

再来一张


测试结论及建议
测试后发现效果很好,调用速度很快,结果准确,有广泛的应用前景,例如根据人体关键点信息,分析人体姿态、运动轨迹、动作角度等,辅助运动员进行体育训练,分析健身锻炼效果,提升教学效率;或者视频直播平台、线下互动屏幕等场景,可基于人体检测和关键点分析,增加身体道具、体感游戏等互动形式,丰富娱乐体验;等等。

后续可以考虑增加更多的点位,强化功能。

收藏
点赞
0
个赞
共1条回复 最后由风搅火回复于2019-09-16
#2风搅火回复于2019-09-16

相信这个一定会应用的更加广泛的

0
TOP
切换版块