当前位置:
首页 > Python基础教程 >
-
C#教程之C# 虹软SDK视频人脸识别和注册
一,准备工作
1.Afoge视频参数类
using AForge.Video.DirectShow; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FaceRecognization.Common { public class CameraPara { /// <summary> /// 是否有摄像头 /// </summary> public bool HasVideoDevice { get; set; } /// <summary> /// 视频源 /// </summary> public VideoCaptureDevice VideoSource { get; set; } /// <summary> /// 视频图片的宽度 /// </summary> public int FrameWidth { get; set; } /// <summary> /// 视频图片的高度 /// </summary> public int FrameHeight { get; set; } /// <summary> /// 视频图片的字节数 /// </summary> public int ByteCount { get; set; } public CameraPara() { var videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice); if (videoDevices.Count == 0)//没有检测到摄像头 { HasVideoDevice = false; return; } VideoSource = new VideoCaptureDevice(videoDevices[0].MonikerString);//连接第一个摄像头 var videoResolution = VideoSource.VideoCapabilities.First(ii => ii.FrameSize.Width == VideoSource.VideoCapabilities.Max(jj => jj.FrameSize.Width)); //获取摄像头最高的分辨率 FrameWidth = videoResolution.FrameSize.Width; FrameHeight = videoResolution.FrameSize.Height; ByteCount = videoResolution.BitCount / 8; VideoSource.VideoResolution = videoResolution; HasVideoDevice = true; } } }
2.人脸识别相关的结构、类 和枚举
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace FaceRecognization.Face { /// <summary> /// 人脸库 /// </summary> public class FaceLib { public List<Item> Items { get; set; } = new List<Item>(); public class Item { /// <summary> /// 用于排序 /// </summary> public long OrderId { get; set; } /// <summary> /// 文件名作为ID /// </summary> public string ID { get; set; } /// <summary> /// 人脸模型 /// </summary> public FaceModel FaceModel { get; set; } } } /// <summary> /// 人脸识别结果 /// </summary> public class FaceResult { //public int NotMatchedCount { get; set; } public string ID { get; set; } public float Score { get; set; } public System.Drawing.Rectangle Rectangle { get; set; } public int Age { get; set; } /// <summary> /// 0:男,1:女,其他:未知 /// </summary> public int Gender { get; set; } public override string ToString() { string ret = ""; if (!string.IsNullOrEmpty(ID)) ret = ID + ","; ret += Age + "岁"; if (Gender == 0) ret += ",男"; else if (Gender == 1) ret += ",女"; return ret + "," + Score; } } /// <summary> /// 人脸跟踪、检测、性别年龄评估和获取人脸信息的输入参数 /// </summary> [StructLayout(LayoutKind.Sequential)] public struct ImageData { public uint u32PixelArrayFormat; public int i32Width; public int i32Height; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public IntPtr[] ppu8Plane; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4, ArraySubType = UnmanagedType.I4)] public int[] pi32Pitch; } /// <summary> /// 人脸跟踪的结果 /// </summary> [StructLayout(LayoutKind.Sequential)] internal struct TraceResult { [MarshalAs(UnmanagedType.I4)] public int nFace; [MarshalAs(UnmanagedType.I4)] public int lfaceOrient; public IntPtr rcFace; } /// <summary> /// 人脸检测的结果 /// </summary> [StructLayout(LayoutKind.Sequential)] internal struct DetectResult { [MarshalAs(UnmanagedType.I4)] public int nFace; public IntPtr rcFace; public IntPtr lfaceOrient; } /// <summary> /// 人脸在图片中的位置 /// </summary> [StructLayout(LayoutKind.Sequential)] public struct FaceRect { public int left; public int top; public int right; public int bottom; } /// <summary> /// 获取人脸特征的输入参数 /// </summary> [StructLayout(LayoutKind.Sequential)] internal struct FaceFeatureInput { public FaceRect rcFace; public int lOrient; } /// <summary> /// 人脸特征 /// </summary> [StructLayout(LayoutKind.Sequential)] public struct FaceModel { public IntPtr pbFeature; [MarshalAs(UnmanagedType.I4)] public int lFeatureSize; } /// <summary> /// 性别和年龄评估的输入参数 /// </summary> [StructLayout(LayoutKind.Sequential)] internal struct EstimationInput { public IntPtr pFaceRectArray; public IntPtr pFaceOrientArray; public int lFaceNumber; } /// <summary> /// 性别和年龄评估的结果 /// </summary> [StructLayout(LayoutKind.Sequential)] internal struct EstimationResult { public IntPtr pResult; public int lFaceNumber; } /// <summary> /// 错误代码 /// </summary> public enum ErrorCode { /// <summary> /// 正确 /// </summary> Ok = 0, /// <summary> /// 通用错误类型 /// </summary> BasicBase = 0x0001, /// <summary> /// 错误原因不明 /// </summary> Unknown = BasicBase, /// <summary> /// 无效的参数 /// </summary> InvalidParam = BasicBase + 1, /// <summary> /// 引擎不支持 /// </summary> Unsupported = BasicBase + 2, /// <summary> /// 内存不足 /// </summary> NoMemory = BasicBase + 3, /// <summary> /// 状态错误 /// </summary> BadState = BasicBase + 4, /// <summary> /// 用户取消相关操作 /// </summary> UserCancel = BasicBase + 5, /// <summary> /// 操作时间过期 /// </summary> Expired = BasicBase + 6, /// <summary> /// 用户暂停操作 /// </summary> UserPause = BasicBase + 7, /// <summary> /// 缓冲上溢 /// </summary> BufferOverflow = BasicBase + 8, /// <summary> /// 缓冲下溢 /// </summary> BufferUnderflow = BasicBase + 9, /// <summary> /// 存贮空间不足 /// </summary> NoDiskspace = BasicBase + 10, /// <summary> /// 组件不存在 /// </summary> ComponentNotExist = BasicBase + 11, /// <summary> /// 全局数据不存在 /// </summary> GlobalDataNotExist = BasicBase + 12, /// <summary> /// Free SDK通用错误类型 /// </summary> SdkBase = 0x7000, /// <summary> /// 无效的App Id /// </summary> InvalidAppId = SdkBase + 1, /// <summary> /// 无效的SDK key /// </summary> InvalidSdkId = SdkBase + 2, /// <summary> /// AppId和SDKKey不匹配 /// </summary> InvalidIdPair = SdkBase + 3, /// <summary> /// SDKKey 和使用的SDK 不匹配 /// </summary> MismatchIdAndSdk = SdkBase + 4, /// <summary> /// 系统版本不被当前SDK所支持 /// </summary> SystemVersionUnsupported = SdkBase + 5, /// <summary> /// SDK有效期过期,需要重新下载更新 /// </summary> LicenceExpired = SdkBase + 6, /// <summary> /// Face Recognition错误类型 /// </summary> FaceRecognitionBase = 0x12000, /// <summary> /// 无效的输入内存 /// </summary> InvalidMemoryInfo = FaceRecognitionBase + 1, /// <summary> /// 无效的输入图像参数 /// </summary> InvalidImageInfo = FaceRecognitionBase + 2, /// <summary> /// 无效的脸部信息 /// </summary> InvalidFaceInfo = FaceRecognitionBase + 3, /// <summary> /// 当前设备无GPU可用 /// </summary> NoGpuAvailable = FaceRecognitionBase + 4, /// <summary> /// 待比较的两个人脸特征的版本不一致 /// </summary> MismatchedFeatureLevel = FaceRecognitionBase + 5 } /// <summary> /// 脸部角度的检测范围 /// </summary> public enum OrientPriority { /// <summary> /// 检测 0 度(±45 度)方向 /// </summary> Only0 = 0x1, /// <summary> /// 检测 90 度(±45 度)方向 /// </summary> Only90 = 0x2, /// <summary> /// 检测 270 度(±45 度)方向 /// </summary> Only270 = 0x3, /// <summary> /// 检测 180 度(±45 度)方向 /// </summary> Only180 = 0x4, /// <summary> /// 检测 0, 90, 180, 270 四个方向,0 度更优先 /// </summary> Ext0 = 0x5 } }
3.虹软SDK的dll封装
注意要把相应的dll复制的debug\Libs文件夹或release\Libs文件夹
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace FaceRecognization.Face { internal class Detect { private const string DllPath = "Libs/libarcsoft_fsdk_face_detection.dll"; /// <summary> /// /// </summary> /// <param name="appId"></param> /// <param name="sdkKey"></param> /// <param name="memory"></param> /// <param name="memroySize"></param> /// <param name="engine"></param> /// <param name="orientPriority"></param> /// <param name="scale">最小人脸尺寸有效值范围[2,50] 推荐值 16。该尺寸是人脸相对于所在图片的长边的占比。例如,如果用户想检测到的最小人脸尺寸是图片长度的 1/8,那么这个 nScale 就应该设置为8</param> /// <param name="maxFaceNumber">用户期望引擎最多能检测出的人脸数有效值范围[1,100]</param> /// <returns></returns> [DllImport(DllPath, EntryPoint = "AFD_FSDK_InitialFaceEngine", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern int Init(string appId, string sdkKey, byte[] memory, int memroySize, out IntPtr engine, int orientPriority, int scale, int maxFaceNumber); [DllImport(DllPath, EntryPoint = "AFD_FSDK_StillImageFaceDetection", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern int Detection(IntPtr engine, ref ImageData imgData, out IntPtr pDetectResult); [DllImport(DllPath, EntryPoint = "AFD_FSDK_UninitialFaceEngine", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern int Close(IntPtr engine); } internal class Trace { private const string DllPath = "Libs/libarcsoft_fsdk_face_tracking.dll"; /// <summary> /// /// </summary> /// <param name="appId"></param> /// <param name="sdkKey"></param> /// <param name="buffer"></param> /// <param name="bufferSize"></param> /// <param name="engine"></param> /// <param name="orientPriority"></param> /// <param name="scale">最小人脸尺寸有效值范围[2,16] 推荐值 16。该尺寸是人脸相对于所在图片的长边的占比。例如,如果用户想检测到的最小人脸尺寸是图片长度的 1/8,那么这个 nScale 就应该设置为8</param> /// <param name="faceNumber">用户期望引擎最多能检测出的人脸数有效值范围[1,20]</param> /// <returns></returns> [DllImport(DllPath, EntryPoint = "AFT_FSDK_InitialFaceEngine", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern int Init(string appId, string sdkKey, byte[] buffer, int bufferSize, out IntPtr engine, int orientPriority, int scale, int faceNumber); [DllImport(DllPath, EntryPoint = "AFT_FSDK_FaceFeatureDetect", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern int Detection(IntPtr engine, ref ImageData imgData, out IntPtr pTraceResult); [DllImport(DllPath, EntryPoint = "AFT_FSDK_UninitialFaceEngine", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern int Close(IntPtr engine); } internal class Match { private const string DllPath = "Libs/libarcsoft_fsdk_face_recognition.dll"; [DllImport(DllPath, EntryPoint = "AFR_FSDK_InitialEngine", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern int Init(string appId, string sdkKey, byte[] buffer, int bufferSize, out IntPtr engine); [DllImport(DllPath, EntryPoint = "AFR_FSDK_ExtractFRFeature", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern int ExtractFeature(IntPtr engine, ref ImageData imageData, ref FaceFeatureInput faceFeatureInput, out FaceModel pFaceModels); [DllImport(DllPath, EntryPoint = "AFR_FSDK_FacePairMatching", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern int FacePairMatch(IntPtr engine, ref FaceModel faceModel1, ref FaceModel faceModel2, out float score); [DllImport(DllPath, EntryPoint = "AFR_FSDK_UninitialEngine", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern int Close(IntPtr engine); } internal class Age { private const string DllPosition = "libs/libarcsoft_fsdk_age_estimation.dll"; [DllImport(DllPosition, EntryPoint = "ASAE_FSDK_InitAgeEngine", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern int Init(string appId, string sdkKey, byte[] buffer, int bufferSize, out IntPtr engine); [DllImport(DllPosition, EntryPoint = "ASAE_FSDK_AgeEstimation_StaticImage", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern int EstimationStatic(IntPtr engine, ref ImageData imgData, ref EstimationInput estimationInputInput, out EstimationResult pAgeResult); [DllImport(DllPosition, EntryPoint = "ASAE_FSDK_AgeEstimation_Preview", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern int EstimationPreview(IntPtr engine, ref ImageData imgData, ref EstimationInput estimationInputInput, out EstimationResult pAgeResult); [DllImport(DllPosition, EntryPoint = "ASAE_FSDK_UninitAgeEngine", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern int Close(IntPtr engine); } internal class Gender { private const string DllPosition = "libs/libarcsoft_fsdk_gender_estimation.dll"; [DllImport(DllPosition, EntryPoint = "ASGE_FSDK_InitGenderEngine", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern int Init(string appId, string sdkKey, byte[] buffer, int bufferSize, out IntPtr engine); [DllImport(DllPosition, EntryPoint = "ASGE_FSDK_GenderEstimation_StaticImage", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern int EstimationStatic(IntPtr engine, ref ImageData imgData, ref EstimationInput estimationInputInput, out EstimationResult pGenderResult); [DllImport(DllPosition, EntryPoint = "ASGE_FSDK_GenderEstimation_Preview", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern int EstimationPreview(IntPtr engine, ref ImageData imgData, ref EstimationInput estimationInputInput, out EstimationResult pGenderResesult); [DllImport(DllPosition, EntryPoint = "ASGE_FSDK_UninitGenderEngine", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern int Close(IntPtr engine); } }
二、正式开始
1.添加一个Form,将Name改为“Main”,添加Load和FormClosing事件
2.拖一个Afoge.Controls.VideoSourcePlayer到Main,将Name改为“VideoPlayer”,添加Click事件;
3.拖一个PictureBox到Main,懒得改名字了,就叫“pictureBox1”;
4.拖一个Lable到Main,将Text改为“ID”;
5.拖一个TextBox到Main,将Name改为“TextBoxID”;
6.拖一个Button到Main,将Name改为ButtonRegister,将Text改为“注册”,添加Click事件。
界面如下图,从左到右,从上到下6个控件:
对应的代码为:
using AForge.Video.DirectShow; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using FaceRecognization.Common; using System.Runtime.InteropServices; using System.Diagnostics; using System.IO; using System.Threading; using System.Drawing.Imaging; namespace FaceRecognization { public partial class Main : Form { #region Property /// <summary> /// 保存人脸数据的文件夹 /// </summary> const string FeaturePath = "d:\\FeatureData"; /// <summary> /// 虹软SDK的AppId /// </summary> const
栏目列表
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
SQL SERVER中递归
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
这是目前我见过最好的跨域解决方案!
减少回流与重绘
减少回流与重绘
如何使用KrpanoToolJS在浏览器切图
performance.now() 与 Date.now() 对比
一款纯 JS 实现的轻量化图片编辑器
关于开发 VS Code 插件遇到的 workbench.scm.
前端设计模式——观察者模式
前端设计模式——中介者模式
创建型-原型模式