上一篇讲到使用虹软算法实现了人脸追踪,这个算法也可以实现人脸识别,这里不采用了,室外工作效果不好,用来追踪还是可以的。接下来采用腾讯云的在线识别技术,从人脸库中查找最相似的人员,根据返回的匹配的分就可以判断是不是同一个人。
调用腾讯云API时需要签名,云API密钥用于生成签名,首先到腾讯云上注册获取SecretId,SecretKey,创建人脸库,也可以通过api创建。
人员库里面添加完测试人员信息、照片后就可以开工了。参考上一篇,编写函数集成到摄像头播放线程里面,实现人脸识别,试了下,速度超快,150ms以内。
using System.Web;
using System.Net;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Security.Cryptography;
//调用腾讯云API时需要签名,云API密钥用于生成签名,获取地址https://console.cloud.tencent.com/
public static string SecretId = "****helpyourself***";
public static string SecretKey = "*******";
//api接口地
public static string api_url = "https://iai.tencentcloudapi.com";
//加密算法HmacSHA256
private static string HmacSHA256(string secret, string signKey)
{
string signRet = string.Empty;
using (HMACSHA256 mac = new HMACSHA256(Encoding.UTF8.GetBytes(signKey)))
{
byte[] hash = mac.ComputeHash(Encoding.UTF8.GetBytes(secret));
signRet = Convert.ToBase64String(hash);
//signRet = ToHexString(hash); ;
}
return signRet;
}
//组装参数
private static string BuildParamStr(SortedDictionary<string, string> requestParams)
{
string retStr = "";
foreach (string key in requestParams.Keys)
{
retStr += string.Format("{0}={1}&", key, requestParams[key]);
}
return retStr.TrimEnd('&');
}
//通过图片从人员库中搜索最相似的人员
private bool SearchFaces(string base64_pic)
{
bool b_success = false;
//时间戳
System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
long Timestamp = (long)(DateTime.Now - startTime).TotalSeconds;
string Nonce = Math.Abs(new Random().Next()).ToString();
try
{
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(api_url);
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
req.Timeout = 500;//单位毫秒
Dictionary<string, string> param = new Dictionary<string, string>();
//公共参数
param.Add("Action", "SearchFaces");//接口名称
param.Add("Timestamp", Timestamp.ToString());
param.Add("Nonce", Nonce);
param.Add("SecretId", SecretId);
param.Add("Version", "2018-03-01");
param.Add("SignatureMethod", "HmacSHA256");//签名方法
//接口参数
param.Add("GroupIds.0", "0001");//希望搜索的人员库列表
param.Add("Image", base64_pic);//图片 base64 数据
param.Add("MaxFaceNum", "1");//最多处理的人脸数目。默认值为1(仅检测图片中面积最大的那张人脸),最大值为10
param.Add("MinFaceSize", "80");//人脸长和宽的最小尺寸,单位为像素。默认为80
param.Add("MaxPersonNum", "3");//最多返回的最相似人员数目。默认值为5,最大值为10。
string requestHost = req.Host;
string requestMethod = req.Method;
string requestPath = "/";
//准备签名,签名原文串的拼接规则为: 请求方法 + 请求主机 +请求路径 + ? + 请求字符串
string sigInParam = "";
sigInParam += requestMethod;
sigInParam += requestHost;
sigInParam += requestPath;
sigInParam += "?";
string req_str = BuildParamStr(new SortedDictionary<string, string>(param, StringComparer.Ordinal));
sigInParam += req_str;
//签名
string sigOutParam = HmacSHA256(sigInParam, SecretKey);
//请求data
SortedDictionary<string, string> requestParams = new SortedDictionary<string, string>(param, StringComparer.Ordinal);
string req_params = "";
foreach (string key in requestParams.Keys)
{
req_params += string.Format("{0}={1}&", key, HttpUtility.UrlEncode(requestParams[key]));
}
req_params = req_params.TrimEnd('&');
//最后加签名
req_params += "&Signature=" + HttpUtility.UrlEncode(sigOutParam);
Stream reqStream = req.GetRequestStream();
byte[] bs = Encoding.UTF8.GetBytes(req_params);
reqStream.Write(bs, 0, bs.Length);
WebResponse wr = req.GetResponse();
Stream rs = wr.GetResponseStream();
Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
StreamReader rsp = new StreamReader(rs, encode);
string rsp_cnt = rsp.ReadToEnd();
rsp.Close();
//解析返回数据
JObject json = (JObject)JsonConvert.DeserializeObject(rsp_cnt);
if (json.Property("Response") != null)
{
JObject json_sub = (JObject)json["Response"];
//string RequestId = json_sub["RequestId"].ToString(); //请求ID
string szTemp = string.Empty;
if (json_sub.Property("Results") != null)//搜索结果
{
JArray Candidates = (JArray)json_sub["Results"][0]["Candidates"];
for (int i = 0; i < Candidates.Count; i++)
{
string PersonId = Candidates[i]["PersonId"].ToString();//人员ID
float Score = (float)Candidates[i]["Score"]; //匹配得分
szTemp = string.Format("PersonId={0},Score={1}", PersonId, Score);
AddLogRecord(txt_log, szTemp);
}
b_success = true;
}
else//失败结果
{
string Error = json_sub["Error"]["Code"].ToString();
string Message = json_sub["Error"]["Message"].ToString();
szTemp = string.Format("Error={0},Message={1}", Error, Message);
AddLogRecord(txt_log, szTemp);
}
}
}
catch (Exception ex)
{
AddLogRecord(txt_log, ex.Message);
}
return b_success;
}