人脸检测哪家强?百度、腾讯、旷视大比拼(2)百度人脸检测类实现

同系列文章

/* ----------------------------------------------------------
 * 文件名称:BaiduFr.cs
 * 作者:秦建辉
 * 
 * 微信:splashcn
 * 
 * 博客:http://www.firstsolver.com/wordpress/
 * 
 * 开发环境:
 *      Visual Studio V2017
 *      .NET Framework 4
 *      Newtonsoft.Json 11.0.2
 *      
 * 版本历史:
 *      V1.0    2018年03月27日
 *              百度人脸检测类实现
------------------------------------------------------------ */
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Net;
using System.Text;

namespace Com.FirstSolver.FR
{
    public class BaiduFr : FrCore
    {
        /// <summary>
        /// 厂家名称
        /// </summary>
        public override string Company { get { return "百度"; } }

        /// <summary>
        /// 应用标识
        /// </summary>
        private const string API_KEY = "Vnrv8o6lmHm3jAYsB62tZBod";

        /// <summary>
        /// 应用密钥
        /// </summary>
        private const string API_SECRET = "VmYQyST8kq3s0HcrGcdRHcLbxeGwNQDe";

        /// <summary>
        /// 访问授权码
        /// </summary>
        public string AccessToken { get; private set; }

        /// <summary>
        /// 人脸识别属性设置
        /// </summary>
        public Dictionary<string, string> RequestOptions = new Dictionary<string, string>{
            { "max_face_num", "5"},
            { "face_fields", "landmark" }
        };

        /// <summary>
        /// 人脸识别接口初始化
        /// </summary>
        /// <returns>
        ///     0-成功
        ///     其它-失败
        /// </returns>
        public override int Initialize()
        {
            ErrorMessage = null;

            // 获取授权码,授权服务地址:https://aip.baidubce.com/oauth/2.0/token
            StringBuilder sb = new StringBuilder();
            sb.Append("https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=").Append(API_KEY).Append("&client_secret=").Append(API_SECRET);

            try
            {
                HttpWebRequest httpWebRequest = WebRequest.Create(sb.ToString()) as HttpWebRequest;
                if (httpWebRequest == null) return -1;

                using (HttpWebResponse response = httpWebRequest.GetResponse() as HttpWebResponse)
                {
                    using (StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
                    {
                        AccessToken = JObject.Parse(sr.ReadToEnd())["access_token"].ToString();
                        return 0;
                    }
                }
            }
            catch (Exception e)
            {
                ErrorMessage = e.Message;
                return -2;
            }
        }

        public override int Detect(byte[] image, out FFI[] faceset)
        {
            ErrorMessage = null;
            faceset = null;

            try
            {
                string options = CreateFaceDetectParameters(image);
                var result = DoHttpPost("https://aip.baidubce.com/rest/2.0/face/v2/detect?access_token=" + AccessToken, options);
                var error_code = result["error_code"];
                if (error_code != null)
                {
                    ErrorMessage = result["error_msg"].ToString();
                    return -1; // 人脸检测失败
                }
                else
                {
                    JArray FaceJArray = result["result"] as JArray;
                    if (FaceJArray.Count == 0)
                    {
                        ErrorMessage = "未检测出人脸";
                        return -1; // 人脸检测失败
                    }

                    List<FFI> FaceCollection = new List<FFI>();
                    foreach (dynamic item in FaceJArray)
                    {
                        FFI face = new FFI();

                        // 显示人脸框及特征点
                        var location = item["location"];
                        face.Region = new Rectangle((int)location["left"], (int)location["top"], (int)location["width"], (int)location["height"]);

                        // 标记4个关键点
                        List<Point> CriticalPoints = new List<Point>();
                        foreach (dynamic point in item["landmark"])
                        {
                            CriticalPoints.Add(new Point((int)point["x"], (int)point["y"]));
                        }
                        face.CriticalPoints = CriticalPoints.ToArray();

                        // 标记72个特征点
                        List<Point> FeaturePoints = new List<Point>();
                        foreach (dynamic point in item["landmark72"])
                        {
                            FeaturePoints.Add(new Point((int)point["x"], (int)point["y"]));
                        }
                        face.FeaturePoints = FeaturePoints.ToArray();

                        FaceCollection.Add(face);
                    }

                    faceset = FaceCollection.ToArray();
                    return 0; // 成功
                }
            }
            catch (System.Exception e)
            {
                ErrorMessage = e.Message;
                return -2; // 异常
            }
        }

        /// <summary>
        /// 创建人脸检测调用参数
        /// </summary>
        /// <param name="image">图像数据</param>
        /// <returns>人脸检测调用参数</returns>
        private string CreateFaceDetectParameters(byte[] image)
        {
            StringBuilder sb = new StringBuilder();
            foreach (KeyValuePair<string, string> item in RequestOptions)
            {
                if (!string.IsNullOrEmpty(item.Value))
                {
                    sb.Append(item.Key).Append('=').Append(FrCore.UrlEncode(item.Value, Encoding.UTF8, false)).Append('&');
                }
            }

            return sb.ToString() + "image=" + FrCore.UrlEncode(Convert.ToBase64String(image), Encoding.UTF8, false);
        }

        /// <summary>
        /// 获取人脸检测结果
        /// </summary>
        /// <param name="url">人脸检测访问接口</param>
        /// <param name="options">人脸检测参数</param>
        /// <returns>人脸检测结果</returns>
        public static JObject DoHttpPost(string url, string options)
        {
            HttpWebRequest httpWebRequest = WebRequest.Create(url) as HttpWebRequest;
            if (httpWebRequest == null) return null;

            httpWebRequest.Method = "POST";
            httpWebRequest.KeepAlive = true;
            httpWebRequest.ContentType = "application/x-www-form-urlencoded"; // 内容类型

            byte[] Args = Encoding.UTF8.GetBytes(options);
            httpWebRequest.ContentLength = Args.Length;
            using (Stream requestStream = httpWebRequest.GetRequestStream())
            {
                requestStream.Write(Args, 0, Args.Length);
            }

            using (HttpWebResponse response = httpWebRequest.GetResponse() as HttpWebResponse)
            {
                using (StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
                {
                    return JObject.Parse(sr.ReadToEnd());
                }
            }
        }
    }
}

Comments are closed.