C#:从face++的人脸比对说起

0.

昨天有人问我,如何进行把人脸图片上传到服务器,然后与服务器中的一张人脸图片进行比对,判断是不是同一个人。

然后我自己不可能完全按照他的想法,只取其精华,我的想法是,本地有两张图片,然后通过post方法调用一个接口,然后获取获取返回值,然后判断是不是同一个人,那么这种接口真的有吗?

有。    https://console.faceplusplus.com.cn/documents/4887586

由接口可知,我们必须post带4个参数,2个string和2个file(本地两张图片),且接口文档也说了要用mutipart/form-data方式,且file要以二进制方式。(其它限制条件之后说)

一开始觉得很简单,应为之前用java做的类似的post。

且这里有java的解决方案: https://blog.csdn.net/scookiem/article/details/79409608

但是c#里面好像没有封装的 mutipart/form-data的post的方法啊,那我这几个参数要如何post,不几啊。

所以在post我们的4个参数之前,我们有必要熟悉 http的mutipart/form-data的post请求分析,既然没有封装的方法,那我们自己模拟表单提交数据就OK了。

这里直接看一篇教程就懂了:https://www.cnblogs.com/yinq/p/6045995.html

另外一篇详细点:https://www.cnblogs.com/herenzhiming/articles/6841969.html

其实就是请求的信息是按照一定的格式排版的,我们自己模拟提交,只要数据按照这个格式排版就行了(所以你可以自己去封装一个完美的方法啦!!!)

1.我们的代码如下:

private void HttpPostData() {

            //定义边界符
            var boundary = "ThisIsLiuYan";
            //结束标志
            String end = "--" + boundary + "--";
            byte[] end_bytes = Encoding.UTF8.GetBytes(end);
            //下面要用的一个换行符号
            String enter = "\r\n";
            byte[] enter_bytes = Encoding.UTF8.GetBytes(enter);

            //接口地址
            String jiekou = @"https://api-cn.faceplusplus.com/facepp/v3/compare";
            var webRequest = (HttpWebRequest)WebRequest.Create(jiekou);
            webRequest.Method = "POST";
            webRequest.KeepAlive = true;
            //设置边界符 和 ContentType
            webRequest.ContentType = "multipart/form-data; boundary=" + boundary;
            
            //保存我们请求的数据--按照排版格式的顺序
            MemoryStream stream = new MemoryStream();

            //2个string参数
            String formate =
                "--" + boundary + "\r\n" +
                "Content-Disposition: form-data; name=\"{0}\"" +
                "\r\n\r\n{1}\r\n";
            String onekey = String.Format(formate, "api_key", "你的key");
            String twokey = String.Format(formate, "api_secret", "你的secret");
            byte[] data = Encoding.UTF8.GetBytes(onekey);
            stream.Write(data, 0, data.Length); //
            data = Encoding.UTF8.GetBytes(twokey);
            stream.Write(data, 0, data.Length); //
            //2个file参数
            String fmt =
                "--" + boundary + "\r\n" +
                "Content-Type:application/octet-stream" + "\r\n" +
                "Content-Disposition: form-data; filename=\"{1}\"; name=\"{0}\"" +
                "\r\n\r\n";
            String threeKey = String.Format(fmt, "image_file1", "444.png");
            String fourKey = String.Format(fmt, "image_file2", "555.png");
            String one = @"G:\新建文件夹\444.png";
            String two = @"G:\新建文件夹\555.png";
            FileStream onefile = File.OpenRead(one);
            FileStream twofile = File.OpenRead(two);
            int one_lenth = (int)onefile.Length;
            int two_lenth = (int)twofile.Length;
            byte[] one_byte = new byte[one_lenth];
            byte[] two_byte = new byte[two_lenth];
            onefile.Read(one_byte, 0, one_lenth);
            twofile.Read(two_byte, 0, two_lenth);
            onefile.Close();
            twofile.Close();
            data = Encoding.UTF8.GetBytes(threeKey);
            stream.Write(data, 0, data.Length);
            stream.Write(one_byte, 0, one_byte.Length);
            stream.Write(enter_bytes, 0, enter_bytes.Length); //注意:这里有个换行
            data = Encoding.UTF8.GetBytes(fourKey);
            stream.Write(data, 0, data.Length);
            stream.Write(two_byte, 0, two_byte.Length);
            stream.Write(enter_bytes, 0, enter_bytes.Length); //注意:这里有换行和下面结束
            stream.Write(end_bytes, 0, end_bytes.Length);

            webRequest.ContentLength = stream.Length; //应为这里要设置长度,所以前面要用memoryStream保存
            Stream requestStream = webRequest.GetRequestStream();
            stream.Position = 0L;
            stream.CopyTo(requestStream);
            stream.Close();
            requestStream.Close();

            try {
                StreamReader sr = new StreamReader(webRequest.GetResponse().GetResponseStream()); //返回的数据
                String responsString = sr.ReadToEnd();
                sr.Close();

                var jsonobj = JObject.Parse(responsString);
                int v = (int)jsonobj["confidence"]; //只获取关键值,这里设置大于80即为同一人
                if (v > 80) {
                    Label1.Text = "是同一个人";
                }
                else {
                    Label1.Text = "不是同一个人";
                }
            }
            catch (Exception ee) {
                Label1.Text = "" + ee.Message;
            }
            

        }

然后你自己调用这个方法,就可以达到效果了。不亏我一番琢磨。

2.

但是这个接口还是有缺陷的,图片大于2M会报错,图片的像素也有要求限制。如下

图片要求

图片格式:JPG(JPEG),PNG
图片像素尺寸:最小 48*48 像素,最大 4096*4096 像素
图片文件大小:2MB
最小人脸像素尺寸: 系统能够检测到的人脸框为一个正方形,正方形边长的最小值为 150 像素。

猜你喜欢

转载自blog.csdn.net/qq_38261174/article/details/86629044