VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 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