zoukankan      html  css  js  c++  java
  • WebApiClientCore简约调用百度AI接口

    WebApiClientCore

    WebApiClient.JIT/AOT的netcore版本,集高性能高可扩展性于一体的声明式http客户端库,特别适用于微服务的restful资源请求,也适用于各种畸形http接口请求。

    百度AI

    百度AI目前相当开放(至少在使用上),如果不是高并发请求场景,一般免费使用即可。鉴于其提供的.net sdk比较先进(laji),使用Dictionary类型替代模型参数,以及使用万能的JObject类型做为返回值类型的设计,正常人都无法体会其中精髓。试看以下的api原型,想必大家都想找找没有文档说明吧?我觉得这sdk更像是一个httpUtil,只提供了一个 object Send( object )方法。

    public JObject Detect(string image, string imageType, Dictionary<string, object> options = null);
    

    小牛试刀

    今天我们抛开官方SDK,使用WebApiClientCore请求我们感兴趣的人脸检测接口,虽然只有一个接口,但我会尽量按高规格的设计质量来调用这个接口,让朋友们了解WebApiClientCore的魅力之处。首先,我们先阅读官方文档:Api文档.人脸检测,根据文档内容,大概有以下知识块:

    • access_token获取与使用
    • access_token的过期与刷新
    • 请求参数模型
    • 正确的响应结果模型
    • 人脸识别错误码

    模型设计

    请求参数模型

    为了使用方便,我们将图片类型、人脸类型设计为枚举类型,注意实际请求时,传输的是枚举的键名,而不是值。

    /// <summary>
    /// 表示待人脸检测的图片
    /// </summary>
    public class DetectImage
    {
        /// <summary>
        /// 图片信息
        /// </summary>
        public string Image { get; set; }
    
        /// <summary>
        /// 图片信息
        /// </summary>
        [JsonConverter(typeof(JsonStringEnumConverter))]
        public ImageType Image_type { get; set; }
    
        /// <summary>
        /// 最多处理人脸的数目
        /// </summary>
        [Range(1, 10)]
        public int? Max_face_num { get; set; } = 1;
    
        /// <summary>
        /// 人脸的类型
        /// </summary>
        [JsonConverter(typeof(JsonStringEnumConverter))]
        public FaceType Face_type { get; set; }
    
    
        /// <summary>
        /// 图像类型
        /// </summary>
        public enum ImageType
        {
            /// <summary>
            /// 图片的base64值
            /// </summary>
            BASE64,
            /// <summary>
            /// 图片的 URL地址
            /// </summary>
            URL,
            /// <summary>
            /// 人脸图片的唯一标识
            /// </summary>
            FACE_TOKEN
        }
    
        /// <summary>
        /// 人脸的类型
        /// </summary>
        public enum FaceType
        {
            /// <summary>
            /// 生活照
            /// </summary>
            LIVE,
            /// <summary>
            /// 身份证芯片照
            /// </summary>
            IDCARD,
            /// <summary>
            /// 带水印证件照
            /// </summary>
            WATERMARK,
            /// <summary>
            /// 证件照片
            /// </summary>
            CERT
        }
    }
    

    响应模型

    通过PostMan预请求,我们发现官方文档里提到的响应内容,实际上只是完整响应内容的里面的Result值而已(官方文档有点不靠谱) 。

    /// <summary>
    /// 响应内容
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class Response<T>
    {
        /// <summary>
        /// 错误码
        /// </summary>
        public int Error_code { get; set; }
    
        /// <summary>
        /// 错误信息
        /// </summary>
        public string Error_msg { get; set; }
    
        /// <summary>
        /// 结果值
        /// </summary>
        public T Result { get; set; }
    }
    
    /// <summary>
    /// 表示检测结果
    /// </summary>
    public class DetectResult
    {
        /// <summary>
        /// 人脸数量
        /// </summary>
        public int Face_num { get; set; }
    
        /// <summary>
        /// 人脸列表
        /// </summary>
        public FaceItem[] Face_list { get; set; }
    
        /// <summary>
        /// 人脸
        /// </summary>
        public class FaceItem
        {
            public string Face_token { get; set; }
    
            public FaceLocation Location { get; set; }
    
            public int Face_probability { get; set; }
    
            public FaceAngle Angle { get; set; }
    
            /// <summary>
            /// 位置
            /// </summary>
            public class FaceLocation
            {
                public double Left { get; set; }
                public double Top { get; set; }
                public int Width { get; set; }
                public int Height { get; set; }
                public int Rotation { get; set; }
            }
    
            /// <summary>
            /// 角度
            /// </summary>
            public class FaceAngle
            {
                public double Yaw { get; set; }
                public double Pitch { get; set; }
                public double Roll { get; set; }
            }
        }
    }
    

    接口声明

    应用请求与响应模型

    /// <summary>
    /// 百度人脸相关接口
    /// </summary>
    public interface IBaiduFaceApi
    {
        /// <summary>
        /// 图像的人脸检测
        /// </summary>
        /// <param name="detectImage">待检测图像</param>
        /// <returns></returns>
        [HttpPost("rest/2.0/face/v3/detect")]
        ITask<Response<DetectResult>> DetectAsync([JsonContent] DetectImage detectImage);
    }
    

    应用请求日志

    为了方便调试,我们需要将实际请求内容输出到日志组件,这里为接口应用[LoggingFilter]。

    /// <summary>
    /// 百度人脸相关接口
    /// </summary>
    [LoggingFilter]
    public interface IBaiduFaceApi
    {
        /// <summary>
        /// 图像的人脸检测
        /// </summary>
        /// <param name="detectImage">待检测图像</param>
        /// <returns></returns>
        [HttpPost("rest/2.0/face/v3/detect")]
        ITask<Response<DetectResult>> DetectAsync([JsonContent] DetectImage detectImage);
    }
    

    应用access_token

    access_token我们可以做为一个切面处理,WebApiClientCore.Extensions.OAuths扩展包专门处理这个切面,由于百度的access_token不是标准的放到Authorization请求头,而是放到access_token的query参数,所以我们需要继承ClientCredentialsTokenAttribute来实现自定义token应用特性。

    /// <summary>
    /// token应用特性
    /// </summary>
    class AccessTokenAttribute : ClientCredentialsTokenAttribute
    {
        protected override void UseTokenResult(ApiRequestContext context, TokenResult tokenResult)
        {
            context.HttpContext.RequestMessage.AddUrlQuery("access_token", tokenResult.Access_token);
        }
    }
    
    
    /// <summary>
    /// 百度人脸相关接口
    /// </summary>
    [AccessToken]
    [LoggingFilter]
    public interface IBaiduFaceApi
    {
        /// <summary>
        /// 图像的人脸检测
        /// </summary>
        /// <param name="detectImage">待检测图像</param>
        /// <returns></returns>
        [HttpPost("rest/2.0/face/v3/detect")]
        ITask<Response<DetectResult>> DetectAsync([JsonContent] DetectImage detectImage);
    }
    

    接口注册与配置

    接口注册

    services.AddHttpApi<IBaiduFaceApi>(c =>
    {
        c.HttpHost = new Uri("https://aip.baidubce.com/");
    });
    

    token提供者配置

    百度返回的token有refreshToken值,但文档里没有提到怎么刷新token,尝试使用token请求地址去刷新token会失败,所以这里直接配置禁用使用refreshToken的功能,强迫时间到期之后,重新去申请一次token。

    services.AddClientCredentialsTokenProvider<IBaiduFaceApi>(c =>
    {
        c.Endpoint = new Uri("https://aip.baidubce.com/oauth/2.0/token");
        c.UseRefreshToken = false;
        c.Credentials.Client_id = "API Key";
        c.Credentials.Client_secret = "Secret Key";
    });
    

    接口调用

    将IBaiduFaceApi注入到我们的服务,即可调用

    public class FaceService
    {
        private readonly IBaiduFaceApi baiduFaceApi;
    
        public FaceService(IBaiduFaceApi baiduFaceApi)
        {
            this.baiduFaceApi = baiduFaceApi;
        }
    
        public async Task DetectAsync()
        {
            var img = new DetectImage
            {
                Face_type = DetectImage.FaceType.IDCARD,
                Image = "http://xxx.jpg",
                Image_type = DetectImage.ImageType.URL
            };
            var result = await baiduFaceApi.DetectAsync(img);
        }
    }
    

    现在,我们已经拿到正常的结果,顺便查看请求日志确认请求是否正确。

    POST /rest/2.0/face/v3/detect?access_token=省略值 HTTP/1.1
    Host: aip.baidubce.com
    User-Agent: WebApiClientCore/1.0.6.0
    Accept: application/json; q=0.01, application/xml; q=0.01
    Content-Type: application/json; charset=utf-8
    
    {"image":"http://xxx.jpg","image_type":"URL","max_face_num":1,"face_type":"IDCARD"}
    
    HTTP/1.1 200 OK
    Connection: keep-alive
    Date: Thu, 23 Jul 2020 02:05:58 GMT
    Content-Type: application/json
    Content-Length: 328
    
    {"error_code":0,"error_msg":"SUCCESS","log_id":2599254579794,"timestamp":1595469958,"cached":0,"result":{"face_num":1,"face_list":[{"face_token":"97071a7f306483fea94d0766cfeb120c","location":{"left":34.54,"top":74.23,"width":101,"height":101,"rotation":0},"face_probability":1,"angle":{"yaw":-0.92,"pitch":6.68,"roll":-3.72}}]}}
    

    结束语

    以上为WebApiClientCore在百度Ai请求的一个小例子,当然WebApiClientCore还有好多功能,点击项目链接,带你GET到N种使用技能,不求star,只求提供良好建议。

    https://github.com/dotnetcore/WebApiClient

  • 相关阅读:
    JS面试题(一)
    cookie、locakstorage、sessionstorage的区别
    BOM操作
    DOM表单(复选框)
    DOM表格操作
    Javascript的组成——EMACScript、DOM、BOM
    scrollto 到指定位置
    编写一个javscript函数 fn,该函数有一个参数 n(数字类型),其返回值是一个数组,该数组内是 n 个随机且不重复的整数,且整数取值范围是 [2, 32]。
    使用bluebird解决promise兼容性问题
    Mac 更改/usr/bin 目录权限失败
  • 原文地址:https://www.cnblogs.com/kewei/p/13364828.html
Copyright © 2011-2022 走看看