2020-08-27

使用C#对华为IPC摄像头二次开发(二)

华为IPC SDK把人脸抓拍注册成功后,摄像头本身带的有人脸识别算法,捕获到人脸后,会把数据回调给注册事件,注册事件中根据回调中给的人脸数据的内存地址取出数据,实例化成C#的数据结构,把图片转换成byte[]写入到队列里,定时处理队列时取出数据写成图片,即完成了摄像头人脸识别抓拍(有的摄像头带人脸比对算法,可直接进行人脸比对)。

上一篇我们实现了用SDK登录摄像头并实现预览(https://www.cnblogs.com/wdw984/p/13564195.html),这次我们实现通过SDK调用摄像头本身自带的人脸抓拍功能。

因为篇幅较短,这里直接上代码。

首先我们在MainWindow代码里定义一个安全队列用来存储抓拍到的人脸数据,一个定时取队列数据的定时器,一个人脸抓拍回调事件

  private static ConcurrentQueue<CaptureInfo> _concurrentQueue = new ConcurrentQueue<CaptureInfo>();  private static HuaWeiSdkHelper.PfRealDataCallBack _fedRealPlayCallbackFaceCapture;  private Timer _timer;

在窗体加载事件中初始化定时器,用来把抓拍到的数据保存到本地

  private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)  {
//上一篇文章中的代码省略 _timer = new Timer(300) { Enabled = false }; _timer.Elapsed += Timer_Elapsed; }

SDK定义了人脸捕获需要定义的Struct和Enum

namespace HuaWeiCamera.Struct{ /// <summary> /// 元数据获取相关参数 /// </summary> [StructLayout(LayoutKind.Sequential)] public struct PU_META_DATA {  /// <summary>  /// 数据容量  /// </summary>  public ushort usCapacity;  /// <summary>  /// 有效数目  /// </summary>  public ushort usValidNumber;  /// <summary>  /// 参考PU_UserData 定义  /// </summary>  public System.IntPtr pstMetaUserData; }}
namespace HuaWeiCamera.Struct{ /// <summary> /// 元数据用户数据 /// </summary> [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential, Pack = 1)] public struct PU_UserData {  /// <summary>  /// 元数据类型  /// </summary>  public LAYER_THREE_TYPE eType;  /// <summary>  /// 用户元数据详情  /// </summary>  public PU_UserData_unMetadata Union1; }}
namespace HuaWeiCamera.Struct{ /// <summary> /// 用户元数据详情 /// </summary> [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Explicit)] public struct PU_UserData_unMetadata {  [System.Runtime.InteropServices.FieldOffset(0)]  public int bBoolValue;  [System.Runtime.InteropServices.FieldOffset(0)]  public byte charValue;  [System.Runtime.InteropServices.FieldOffset(0)]  public byte ucharValue;  [System.Runtime.InteropServices.FieldOffset(0)]  public short shortValue;  [System.Runtime.InteropServices.FieldOffset(0)]  public ushort ushortValue;  [System.Runtime.InteropServices.FieldOffset(0)]  public int IntValue;  [System.Runtime.InteropServices.FieldOffset(0)]  public uint uIntValue;  [System.Runtime.InteropServices.FieldOffset(0)]  public long longlongValue;  [System.Runtime.InteropServices.FieldOffset(0)]  public ulong uLonglongValue;  /// <summary>  /// 元数据二进制颜色  /// </summary>  [System.Runtime.InteropServices.FieldOffset(0)]  public ST_BINARY stBinay;  /// <summary>  /// 元数据矩形  /// </summary>  [System.Runtime.InteropServices.FieldOffset(0)]  public META_RECT_S stRec;  /// <summary>  /// 元数据划点  /// </summary>  [System.Runtime.InteropServices.FieldOffset(0)]  public META_POINT_S stPoint;  /// <summary>  /// 元数据划线  /// </summary>  [System.Runtime.InteropServices.FieldOffset(0)]  public META_LINE_S stLine;  [System.Runtime.InteropServices.FieldOffset(0)]  public IntPtr stPolyGon;  [System.Runtime.InteropServices.FieldOffset(0)]  public IntPtr stColor;  [System.Runtime.InteropServices.FieldOffset(0)]  public IntPtr stHumanAttr;  /// <summary>  /// 人脸信息  /// </summary>  [System.Runtime.InteropServices.FieldOffset(0)]  public META_FACE_INFO stFaceInfo;  /// <summary>  /// 人脸属性  /// </summary>  [System.Runtime.InteropServices.FieldOffset(0)]  public META_FACE_ATTRIBUTES stFaceAttr;  [System.Runtime.InteropServices.FieldOffset(0)]  public IntPtr szUserData; }}

LAYER_THREE_TYPE的Enum请参考https://support.huawei.com/enterprise/zh/doc/EDOC1100084903

定时器事件中处理捕获到的人脸数据(存为本地图片)

#region 处理人脸数据  private void Timer_Elapsed(object sender, ElapsedEventArgs e)  {   if (_concurrentQueue.Count == 0)   {    Console.WriteLine(@"暂无人脸图片");    return;   }   if (!_concurrentQueue.TryDequeue(out CaptureInfo face))   {    Console.WriteLine(@"读取队列错误");    return;   }   if (face._dataFacePic != null && face._dataFacePic.Length > 0)   {    Console.WriteLine(@"人脸存储中");    Task.Run(async () =>    {     var saveFaceFile = Path.Combine($"{AppDomain.CurrentDomain.BaseDirectory}", "jpg", $"face_{DateTime.Now:yyyy-MM-dd-HH-mm-ss}.jpg");     await YuvHelper.Byte2Jpg(face._dataFacePic, saveFaceFile).ConfigureAwait(false);    });   }   if (face._dataFacePanorama != null && face._dataFacePanorama.Length > 0)   {    Console.WriteLine(@"全景图片存储中");    Task.Run(async () =>    {     var savePanoramaFile = Path.Combine($"{AppDomain.CurrentDomain.BaseDirectory}", "jpg", $"Panorama_{DateTime.Now:yyyy-MM-dd-HH-mm-ss}.jpg");     await YuvHelper.Byte2Jpg(face._dataFacePanorama, savePanoramaFile).ConfigureAwait(false);    });   }  }  

No comments:

Post a Comment