C#实现基于ffmpeg加虹软的人脸识别的示例

2019-12-30 18:23:26丽君


using (var detection = LocatorFactory.GetTrackingLocator("appId", "sdkKey"))
{
  var image = Image.FromFile("test.jpg");
  var bitmap = new Bitmap(image);

  var result = detection.Detect(bitmap, out var locateResult);
  using (locateResult)
  {
    if (result == ErrorCode.Ok && locateResult.FaceCount > 0)
    {
      using (var g = Graphics.FromImage(bitmap))
      {
        var face = locateResult.Faces[0].ToRectangle();
        g.DrawRectangle(new Pen(Color.Chartreuse), face.X, face.Y, face.Width, face.Height);
      }

      bitmap.Save("output.jpg", ImageFormat.Jpeg);
    }
  }
}

人脸对比:


using (var proccesor = new FaceProcessor("appid",
        "locatorKey", "recognizeKey", true))
{
  var image1 = Image.FromFile("test2.jpg");
  var image2 = Image.FromFile("test.jpg");

  var result1 = proccesor.LocateExtract(new Bitmap(image1));
  var result2 = proccesor.LocateExtract(new Bitmap(image2));
  
  //FaceProcessor是个整合包装类,集成了检测和识别,如果要单独使用识别,可以使用FaceRecognize类
  //这里做演示,假设图片都只有一张脸
  //可以将FeatureData持久化保存,这个即是人脸特征数据,用于后续的人脸匹配
  //File.WriteAllBytes("XXX.data", feature.FeatureData);FeatureData会自动转型为byte数组

  if ((result1 != null) & (result2 != null))
    Console.WriteLine(proccesor.Match(result1[0].FeatureData, result2[0].FeatureData, true));
}

使用注意事项

LocateResult(检测结果)和Feature(人脸特征)都包含需要释放的内存资源,在使用完毕后,记得需要释放,否则会引起内存泄露。FaceProcessor和FaceRecognize的Match函数,在完成比较后,可以自动释放,只需要最后两个参数指定为true即可,如果是用于人脸匹配(1:N),则可以采用默认参数,这种情况下,第一个参数指定的特征数据不会自动释放,用于循环和特征库的特征进行比对。

整合的完整例子

在Github上,有完整的FaceDemo例子,里面主要实现了通过ffmpeg采集RTSP协议的图像(使用海康的摄像机),然后进行人脸匹配。在开发过程中遇到不少的坑。

人脸识别的首要工作就是捕获摄像机视频帧,这一块上是坑的最久的,因为最开始采用的是OpenCV的包装库,Emgu.CV,在开发过程中,捕获USB摄像头时,倒是问题不大,没有出现过异常。在捕获RTSP视频流时,会不定时的出现AccessviolationException异常,短则几十分钟,长则几个小时,总之就是不稳定。在官方Github地址上,也提了Issue,他们给出的答复是屏蔽的我业务逻辑,仅捕获视频流试试,结果问题依然,所以,我基本坑定了试Emgu.CV上面的问题。后来经过反复的实验,最终确定了选择ffmpeg。