C# 图片人脸识别

此程序基于 虹软人脸识别进行的开发

前提条件
从虹软官网下载获取ArcFace引擎应用开发包,及其对应的激活码(App_id, SDK_key)
将获取到的开发包导入到您的应用中 

App_id与SDK_key是在初始化的时候需要使用
基本类型
所有基本类型在平台库中有定义。 定义规则是在ANSIC 中的基本类型前加上字母“M”同时将类型的第一个字母改成大写。例如“long” 被定义成“MLong”
数据结构与枚举
AFR_FSDK_FACEINPUT
描述: 脸部信息
定义
typedef struct{
MRECT		rcFace;
AFR_FSDK_OrientCode  lOrient;
} AFR_FSDK_FACEINPUT, *LPAFR_FSDK_FACEINPUT;
                                
成员描述
rcFace
脸部矩形框信息
lOrient
脸部旋转角度
AFR_FSDK_FACEMODEL
描述: 脸部特征信息
定义
typedef struct{
MByte		*pbFeature;
MInt32		lFeatureSize;
} AFR_FSDK_FACEMODEL, *LPAFR_FSDK_FACEMODEL;
                                
成员描述
pbFeature
提取到的脸部特征
lFeatureSize
特征信息长度
AFR_FSDK_VERSION
描述: 引擎版本信息
定义
typedef struct{
MInt32			lCodebase;
MInt32			lMajor;
MInt32			lMinor;
MInt32			lBuild;
MInt32 		lFeatureLevel;
MPChar			Version;
MPChar			BuildDate;
MPChar  		CopyRight;
} AFR_FSDK_VERSION, *LPAFR_FSDK_VERSION;
                                
成员描述
lCodebase
代码库版本号
lMajor
主版本号
lMinor
次版本号
lBuild
编译版本号,递增
lFeatureLevel
特征库版本号
Version
字符串形式的版本号
BuildDate
编译时间
CopyRight
版权
枚举
AFR_FSDK_ORIENTCODE
描述: 基于逆时针的脸部方向枚举值
定义
enum AFR_FSDK_ORIENTCODE{
AFR_FSDK_FOC_0		= 0x1,
AFR_FSDK_FOC_90		= 0x2,
AFR_FSDK_FOC_270		= 0x3,
AFR_FSDK_FOC_180 = 0x4,
AFR_FSDK_FOC_30		= 0x5,
AFR_FSDK_FOC_60		= 0x6,
AFR_FSDK_FOC_120		= 0x7,
AFR_FSDK_FOC_150		= 0x8,
AFR_FSDK_FOC_210		= 0x9,
AFR_FSDK_FOC_240		= 0xa,
AFR_FSDK_FOC_300		= 0xb,
AFR_FSDK_FOC_330		= 0xc
};
                  
成员描述
AFR_FSDK_FOC_0
0 度
AFR_FSDK_FOC_90
90度
AFR_FSDK_FOC_270
270度
AFR_FSDK_FOC_180
180度
AFR_FSDK_FOC_30
30度
AFR_FSDK_FOC_60
60度
AFR_FSDK_FOC_120
120度
AFR_FSDK_FOC_150
150度
AFR_FSDK_FOC_210
210度
AFR_FSDK_FOC_240
240度
AFR_FSDK_FOC_300
300度
AFR_FSDK_FOC_330
330度
支持的颜色格式
描述: 颜色格式及其对齐规则
定义
ASVL_PAF_I420 	 8-bit Y层,之后是8-bit2x2 采样的U层和V
ASVL_PAF_YUYV 	 Y0, U0, Y1, V0
ASVL_PAF_RGB24_B8G8R8 	BGR24, B8G8R8
                                
API Reference
AFR_FSDK_InitialEngine
描述: 初始化引擎参数
原型
MRESULT AFR_FSDK_InitialEngine(
MPChar		AppId,
MPChar		SDKKey,
Mbyte		*pMem,
MInt32		lMemSize,
MHandle	        *phEngine
);
                 
参数
AppId
[in] 用户申请SDK时获取的App Id
SDKKey
[in] 用户申请SDK时获取的SDK Key
pMem
[in] 分配给引擎使用的内存地址
lMemSize
[in] 分配给引擎使用的内存大小
phEngine
[out] 引擎handle
返回值: 成功返回MOK,否则返回失败code。失败codes如下所列:
MERR_INVALID_PARAM 参数输入非法 
MERR_NO_MEMORY 内存不足
AFR_FSDK_ExtractFRFeature
描述: 获取脸部特征参数
原型
MRESULT AFR_FSDK_ExtractFRFeature (
    MHandle			hEngine,
    LPASVLOFFSCREEN		pInputImage,
    LPAFR_FSDK_FACEINPUT	pFaceRes,
    LPAFR_FSDK_FACEMODEL	pFaceModels
);
                            
参数
hEngine
[in] 引擎handle
pInputImage
[in] 输入的图像数据
pFaceRes
[in] 已检测到的脸部信息
pFaceModels
[out] 提取的脸部特征信息
返回值: 成功返回MOK,否则返回失败code。失败codes如下所列:
MERR_INVALID_PARAM 参数输入非法 
MERR_NO_MEMORY 内存不足
AFR_FSDK_FacePairMatching
描述: 脸部特征比较
原型
MRESULT AFR_FSDK_FacePairMatching(
	MHandle			hEngine,
	AFR_FSDK_FACEMODEL		*reffeature,
	AFR_FSDK_FACEMODEL		*probefeature,
	MFloat     			*pfSimilScore
);
                            
参数
hEngine
[in] 引擎handle
reffeature
[in] 已有脸部特征信息
probefeature
[in] 被比较的脸部特征信息
pfSimilScore
[out] 脸部特征相似程度数值
返回值: 成功返回MOK,否则返回失败code。失败codes如下所列:
MERR_INVALID_PARAM 参数输入非法 
MERR_NO_MEMORY 内存不足 
AFR_FSDK_UninitialEngine
描述: 销毁引擎,释放相应资源
原型
MRESULT AFR_FSDK_UninitialEngine(
	MHandle          hEngine
);
                            
参数
hEngine
[in] 引擎handle
返回值: 成功返回MOK,否则返回失败code。失败codes如下所列:
MERR_INVALID_PARAM 参数输入非法 
AFR_FSDK_GetVersion
描述: 获取SDK版本信息参数
原型
const AFR_FSDK_VERSION *  AFR_FSDK_GetVersion(
     MHandle          hEngine
     );

                            
相关事例代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace ArcsoftFace
{


    public struct AFD_FSDK_FACERES
    {
        public int nFace;                     // number of faces detected


        public IntPtr rcFace;                        // The bounding box of face


        public IntPtr lfaceOrient;                   // the angle of each face
    }


}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace ArcsoftFace
{
    public struct AFR_FSDK_FACEINPUT
    {
        public MRECT rcFace;	                   // The bounding box of face


        public int lfaceOrient;                 // The orientation of face
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace ArcsoftFace
{
    public struct AFR_FSDK_FACEMODEL
    {
        public IntPtr pbFeature;	// The extracted features


        public int lFeatureSize;	// The size of pbFeature
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace ArcsoftFace
{
    public struct AFR_FSDK_Version
    {
        public int lCodebase;
        public int lMajor;
        public int lMinor;
        public int lBuild;
        public int lFeatureLevel;
        public IntPtr Version;
        public IntPtr BuildDate;
        public IntPtr CopyRight;
    }
}





using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;


namespace ArcsoftFace
{


    public class AmFaceVerify
    {
        /**
        * 初始化人脸检测引擎
        * @return 初始化人脸检测引擎
        */
        [DllImport("libarcsoft_fsdk_face_detection.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int AFD_FSDK_InitialFaceEngine(string appId, string sdkKey, IntPtr pMem, int lMemSize, ref IntPtr pEngine, int iOrientPriority, int nScale, int nMaxFaceNum);


        /**
        * 获取人脸检测 SDK 版本信息
        * @return 获取人脸检测SDK 版本信息
        */
        [DllImport("libarcsoft_fsdk_face_detection.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr AFD_FSDK_GetVersion(IntPtr pEngine);


        /**
        * 根据输入的图像检测出人脸位置,一般用于静态图像检测
        * @return 人脸位置
        */
        [DllImport("libarcsoft_fsdk_face_detection.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int AFD_FSDK_StillImageFaceDetection(IntPtr pEngine, IntPtr offline, ref IntPtr faceRes);




        /**
        * 初始化人脸识别引擎
        * @return 初始化人脸识别引擎
        */
        [DllImport("libarcsoft_fsdk_face_recognition.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int AFR_FSDK_InitialEngine(string appId, string sdkKey, IntPtr pMem, int lMemSize, ref IntPtr pEngine);


        /**
        * 获取人脸识别SDK 版本信息
        * @return 获取人脸识别SDK 版本信息
        */
        [DllImport("libarcsoft_fsdk_face_recognition.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr AFR_FSDK_GetVersion(IntPtr pEngine);


        /**
        * 提取人脸特征
        * @return 提取人脸特征
        */
        [DllImport("libarcsoft_fsdk_face_recognition.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int AFR_FSDK_ExtractFRFeature(IntPtr pEngine, IntPtr offline, IntPtr faceResult, IntPtr localFaceModels);


        /**
        * 获取相似度
        * @return 获取相似度
        */
        [DllImport("libarcsoft_fsdk_face_recognition.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int AFR_FSDK_FacePairMatching(IntPtr pEngine, IntPtr faceModels1, IntPtr faceModels2, ref float fSimilScore);


        #region delete
        ///**
        // *  创建人脸检测引擎
        // *  @param [in] model_path 模型文件夹路径
        // *  @param [out] engine 创建的人脸检测引擎
        // *  @return =0 表示成功,<0 表示错误码。
        // */
        //[DllImport("AmFaceDet.dll", CallingConvention = CallingConvention.Cdecl)]
        //public static extern int AmCreateFaceDetectEngine(string modelPath, ref IntPtr faceDetectEngine);


        ///**
        // *  创建人脸识别引擎
        // *  @param [in] model_path 模型文件夹路径
        // *  @param [out] engine 创建的人脸识别引擎
        // *  @return =0 表示成功,<0 表示错误码。
        // */
        //[DllImport("AmFaceRec.dll", CallingConvention = CallingConvention.Cdecl)]
        //public static extern int AmCreateFaceRecogniseEngine(string modelPath, ref IntPtr facRecogniseeEngine);


        ///**
        // *  创建人脸比对别引擎
        // *  @param [in] model_path 模型文件夹路径
        // *  @param [out] engine 创建的人脸比对引擎
        // *  @return =0 表示成功,<0 表示错误码。
        // */
        //[DllImport("AmFaceCompare.dll", CallingConvention = CallingConvention.Cdecl)]
        //public static extern int AmCreateFaceCompareEngine(ref IntPtr facCompareEngine);


        ///**
        // *  设置人脸引擎参数
        // *  @param [in] engine 人脸引擎
        // *  @param [in] param 人脸参数
        // */
        //[DllImport("AmFaceDet.dll", CallingConvention = CallingConvention.Cdecl)]
        //public static extern void AmSetParam(IntPtr faceDetectEngine, [MarshalAs(UnmanagedType.LPArray)] [In] TFaceParams[] setFaceParams);


        ///**
        // * 人脸检测
        // * @param [in] engine 人脸引擎
        // * @param [in] bgr 图像数据,BGR格式
        // * @param [in] width 图像宽度
        // * @param [in] height 图像高度
        // * @param [in] pitch 图像数据行字节数
        // * @param [in,out] faces 人脸结构体数组,元素个数应等于期望检测人脸个数
        // * @param [in] face_count 期望检测人脸个数
        // * @return >=0 表示实际检测到的人脸数量,<0 表示错误码。
        // */
        //[DllImport("AmFaceDet.dll", CallingConvention = CallingConvention.Cdecl)]
        //public static extern int AmDetectFaces(IntPtr faceDetectEngine, [MarshalAs(UnmanagedType.LPArray)] [In] byte[] image, int width, int height, int pitch, [MarshalAs(UnmanagedType.LPArray)] [In][Out] TAmFace[] faces, int face_count);


        ///**
        // * 抽取人脸特征
        // * @param [in] engine 人脸引擎
        // * @param [in] bgr 图像数据,BGR格式
        // * @param [in] width 图像宽度
        // * @param [in] height 图像高度
        // * @param [in] pitch 图像数据行字节数
        // * @param [in] face 人脸结构体
        // * @param [out] feature 人脸特征
        // * @return =0 表示成功,<0 表示错误码。
        // */
        //[DllImport("AmFaceRec.dll", CallingConvention = CallingConvention.Cdecl)]
        ////public static extern int AmExtractFeature(IntPtr faceEngine, [MarshalAs(UnmanagedType.LPArray)] [In] byte[] image, int width, int height, int pitch, [MarshalAs(UnmanagedType.LPArray)] [In] TAmFace[] faces, ref byte[] feature);
        //public static extern int AmExtractFeature(IntPtr facRecogniseeEngine, [MarshalAs(UnmanagedType.LPArray)] [In] byte[] image, int width, int height, int pitch, [MarshalAs(UnmanagedType.LPArray)] [In] TAmFace[] faces, [MarshalAs(UnmanagedType.LPArray)] [Out] byte[] feature);


        ///**
        // * 比对两个人脸特征相似度
        // * @param [in] engine 人脸引擎
        // * @param [in] feature1 人脸特征1
        // * @param [in] feature2 人脸特征2
        // * @return 人脸相似度
        // */
        //[DllImport("AmFaceCompare.dll", CallingConvention = CallingConvention.Cdecl)]
        //public static extern float AmCompare(IntPtr facCompareEngine, byte[] feature1, byte[] feature2);
        #endregion
    }
}



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;


namespace ArcsoftFace
{
    public struct ASVLOFFSCREEN
    {
        public int u32PixelArrayFormat;


        public int i32Width;


        public int i32Height;


        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
        public IntPtr[] ppu8Plane;


        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
        public int[] pi32Pitch;
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace ArcsoftFace
{
    public struct MRECT
    {
        public int left;
        public int top;
        public int right;
        public int bottom;
    }
}

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Drawing.Imaging;
using System.Diagnostics;
using System.Threading;
using ArcsoftFace;


namespace ArcsoftFace
{


    public partial class Form1 : Form
    {
        byte[] firstFeature;


        byte[] secondFeature;


        //人脸检测引擎
        IntPtr detectEngine = IntPtr.Zero;


        //人脸识别引擎
        IntPtr regcognizeEngine = IntPtr.Zero;


        //拖拽线程
        private Thread threadMultiExec;


        //构造函数
        public Form1()
        {
            InitializeComponent();
        }


        //把图片转成byte[]
        private byte[] getBGR(Bitmap image, ref int width, ref int height, ref int pitch)
        {
            //Bitmap image = new Bitmap(imgPath);


            const PixelFormat PixelFormat = PixelFormat.Format24bppRgb;


            BitmapData data = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadOnly, PixelFormat);


            IntPtr ptr = data.Scan0;


            int ptr_len = data.Height * Math.Abs(data.Stride);


            byte[] ptr_bgr = new byte[ptr_len];


            Marshal.Copy(ptr, ptr_bgr, 0, ptr_len);


            width = data.Width;


            height = data.Height;


            pitch = Math.Abs(data.Stride);


            int line = width * 3;


            int bgr_len = line * height;


            byte[] bgr = new byte[bgr_len];


            for (int i = 0; i < height; ++i)
            {
                Array.Copy(ptr_bgr, i * pitch, bgr, i * line, line);
            }


            pitch = line;


            image.UnlockBits(data);


            return bgr;
        }


        //选择第一张照片
        private void button4_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFile = new OpenFileDialog();


            openFile.Filter = "图片文件|*.bmp;*.jpg;*.jpeg;*.png|所有文件|*.*;";


            openFile.Multiselect = false;


            openFile.FileName = "";


            if (openFile.ShowDialog() == DialogResult.OK)
            {
                this.pictureBox1.Image = null;


                Image image = Image.FromFile(openFile.FileName);


                this.pictureBox1.Image = new Bitmap(image);


                image.Dispose();


                firstFeature = detectAndExtractFeature(this.pictureBox1.Image, 1);
            }
        }


        //选择第二张照片
        private void button2_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFile = new OpenFileDialog();


            openFile.Filter = "图片文件|*.bmp;*.jpg;*.jpeg;*.png|所有文件|*.*;";


            openFile.Multiselect = false;


            openFile.FileName = "";


            if (openFile.ShowDialog() == DialogResult.OK)
            {
                this.pictureBox2.Image = null;


                Image image = Image.FromFile(openFile.FileName);


                this.pictureBox2.Image = new Bitmap(image);


                image.Dispose();


                secondFeature = detectAndExtractFeature(this.pictureBox2.Image, 2);
            }


        }


        //提取识别出的人脸
        public static Bitmap CutFace(Bitmap srcImage, int StartX, int StartY, int iWidth, int iHeight)
        {
            if (srcImage == null)
            {
                return null;
            }


            int w = srcImage.Width;


            int h = srcImage.Height;


            if (StartX >= w || StartY >= h)
            {
                return null;
            }
            if (StartX + iWidth > w)
            {
                iWidth = w - StartX;
            }
            if (StartY + iHeight > h)
            {
                iHeight = h - StartY;
            }
            try
            {
                Bitmap bmpOut = new Bitmap(iWidth, iHeight, PixelFormat.Format24bppRgb);


                Graphics g = Graphics.FromImage(bmpOut);


                g.DrawImage(srcImage, new Rectangle(0, 0, iWidth, iHeight), new Rectangle(StartX, StartY, iWidth, iHeight), GraphicsUnit.Pixel);


                g.Dispose();


                return bmpOut;
            }
            catch
            {
                return null;
            }
        }


        //获取相似度
        private void button3_Click(object sender, EventArgs e)
        {
            float similar = 0f;


            AFR_FSDK_FACEMODEL localFaceModels = new AFR_FSDK_FACEMODEL();


            IntPtr firstFeaturePtr = Marshal.AllocHGlobal(firstFeature.Length);


            Marshal.Copy(firstFeature, 0, firstFeaturePtr, firstFeature.Length);


            localFaceModels.lFeatureSize = firstFeature.Length;


            localFaceModels.pbFeature = firstFeaturePtr;


            IntPtr secondFeaturePtr = Marshal.AllocHGlobal(secondFeature.Length);


            Marshal.Copy(secondFeature, 0, secondFeaturePtr, secondFeature.Length);


            AFR_FSDK_FACEMODEL localFaceModels2 = new AFR_FSDK_FACEMODEL();


            localFaceModels2.lFeatureSize = secondFeature.Length;


            localFaceModels2.pbFeature = secondFeaturePtr;


            IntPtr firstPtr = Marshal.AllocHGlobal(Marshal.SizeOf(localFaceModels));


            Marshal.StructureToPtr(localFaceModels, firstPtr, false);


            IntPtr secondPtr = Marshal.AllocHGlobal(Marshal.SizeOf(localFaceModels2));


            Marshal.StructureToPtr(localFaceModels2, secondPtr, false);


            Stopwatch stopwatch = new Stopwatch();


            stopwatch.Start();


            int result = AmFaceVerify.AFR_FSDK_FacePairMatching(regcognizeEngine, firstPtr, secondPtr, ref similar);


            stopwatch.Stop();


            setControlText(this.label1, "相似度:" + similar.ToString() + " 耗时:" + stopwatch.ElapsedMilliseconds.ToString() + "ms");


            //this.label1.Text = "相似度:" + similar.ToString() + " 耗时:" + stopwatch.ElapsedMilliseconds.ToString() + "ms";


            localFaceModels = new AFR_FSDK_FACEMODEL();


            Marshal.FreeHGlobal(firstFeaturePtr);


            Marshal.FreeHGlobal(secondFeaturePtr);


            Marshal.FreeHGlobal(firstPtr);


            Marshal.FreeHGlobal(secondPtr);


            localFaceModels2 = new AFR_FSDK_FACEMODEL();
        }


        //检测人脸、提取特征
        private byte[] detectAndExtractFeature(Image imageParam, int firstSecondFlg)
        {
            byte[] feature = null;


            try
            {
                Console.WriteLine();


                Console.WriteLine("############### Face Detect Start #########################");


                int width = 0;


                int height = 0;


                int pitch = 0;


                Bitmap bitmap = new Bitmap(imageParam);


                byte[] imageData = getBGR(bitmap, ref width, ref height, ref pitch);


                //GCHandle hObject = GCHandle.Alloc(imageData, GCHandleType.Pinned);


                //IntPtr imageDataPtr = hObject.AddrOfPinnedObject();


                IntPtr imageDataPtr = Marshal.AllocHGlobal(imageData.Length);


                Marshal.Copy(imageData, 0, imageDataPtr, imageData.Length);


                ASVLOFFSCREEN offInput = new ASVLOFFSCREEN();


                offInput.u32PixelArrayFormat = 513;


                offInput.ppu8Plane = new IntPtr[4];


                offInput.ppu8Plane[0] = imageDataPtr;


                offInput.i32Width = width;


                offInput.i32Height = height;


                offInput.pi32Pitch = new int[4];


                offInput.pi32Pitch[0] = pitch;


                AFD_FSDK_FACERES faceRes = new AFD_FSDK_FACERES();


                IntPtr offInputPtr = Marshal.AllocHGlobal(Marshal.SizeOf(offInput));


                Marshal.StructureToPtr(offInput, offInputPtr, false);


                IntPtr faceResPtr = Marshal.AllocHGlobal(Marshal.SizeOf(faceRes));


                //Marshal.StructureToPtr(faceRes, faceResPtr, false);


                Console.WriteLine("StartTime:{0}", DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.ffff"));


                Stopwatch watchTime = new Stopwatch();


                watchTime.Start();
                //人脸检测
                int detectResult = AmFaceVerify.AFD_FSDK_StillImageFaceDetection(detectEngine, offInputPtr, ref faceResPtr);


                watchTime.Stop();


                if (firstSecondFlg == 1)
                {
                    setControlText(this.label5, String.Format("检测耗时:{0}ms", watchTime.ElapsedMilliseconds));


                    //this.label5.Text = String.Format("检测耗时:{0}ms", watchTime.ElapsedMilliseconds);
                }
                else if (firstSecondFlg == 2)
                {
                    setControlText(this.label2, String.Format("检测耗时:{0}ms", watchTime.ElapsedMilliseconds));


                    //this.label2.Text = String.Format("检测耗时:{0}ms", watchTime.ElapsedMilliseconds);
                }


                object obj = Marshal.PtrToStructure(faceResPtr, typeof(AFD_FSDK_FACERES));


                faceRes = (AFD_FSDK_FACERES)obj;


                Console.WriteLine("  Face Count:{0}", faceRes.nFace);


                for (int i = 0; i < faceRes.nFace; i++)
                {
                    MRECT rect = (MRECT)Marshal.PtrToStructure(faceRes.rcFace + Marshal.SizeOf(typeof(MRECT)) * i, typeof(MRECT));


                    int orient = (int)Marshal.PtrToStructure(faceRes.lfaceOrient + Marshal.SizeOf(typeof(int)) * i, typeof(int));


                    if (i == 0)
                    {
                        Image image = CutFace(bitmap, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);


                        if (firstSecondFlg == 1)
                        {
                            this.pictureBox3.Image = image;
                        }
                        else if (firstSecondFlg == 2)
                        {
                            this.pictureBox4.Image = image;
                        }
                    }


                    Console.WriteLine("    left:{0} top:{1} right:{2} bottom:{3} orient:{4}", rect.left, rect.top, rect.right, rect.bottom, orient);
                }


                Console.WriteLine("  EndTime:{0}", DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.ffff"));


                Console.WriteLine("############### Face Detect End   #########################");


                if (faceRes.nFace > 0)
                {
                    Console.WriteLine();


                    Console.WriteLine("############### Face Recognition Start #########################");


                    AFR_FSDK_FACEINPUT faceResult = new AFR_FSDK_FACEINPUT();


                    int orient = (int)Marshal.PtrToStructure(faceRes.lfaceOrient, typeof(int));


                    faceResult.lfaceOrient = orient;


                    faceResult.rcFace = new MRECT();


                    MRECT rect = (MRECT)Marshal.PtrToStructure(faceRes.rcFace, typeof(MRECT));


                    faceResult.rcFace = rect;


                    IntPtr faceResultPtr = Marshal.AllocHGlobal(Marshal.SizeOf(faceResult));


                    Marshal.StructureToPtr(faceResult, faceResultPtr, false);


                    AFR_FSDK_FACEMODEL localFaceModels = new AFR_FSDK_FACEMODEL();


                    IntPtr localFaceModelsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(localFaceModels));


                    //Marshal.StructureToPtr(localFaceModels, localFaceModelsPtr, false);


                    watchTime.Start();


                    int extractResult = AmFaceVerify.AFR_FSDK_ExtractFRFeature(regcognizeEngine, offInputPtr, faceResultPtr, localFaceModelsPtr);


                    Marshal.FreeHGlobal(faceResultPtr);


                    Marshal.FreeHGlobal(offInputPtr);


                    watchTime.Stop();


                    if (firstSecondFlg == 1)
                    {
                        setControlText(this.label3, String.Format("抽取特征耗时:{0}ms", watchTime.ElapsedMilliseconds));


                        //this.label3.Text = String.Format("抽取特征耗时:{0}ms", watchTime.ElapsedMilliseconds);
                    }
                    else if (firstSecondFlg == 2)
                    {
                        setControlText(this.label4, String.Format("抽取特征耗时:{0}ms", watchTime.ElapsedMilliseconds));


                        //this.label4.Text = String.Format("抽取特征耗时:{0}ms", watchTime.ElapsedMilliseconds);
                    }


                    object objFeature = Marshal.PtrToStructure(localFaceModelsPtr, typeof(AFR_FSDK_FACEMODEL));


                    Marshal.FreeHGlobal(localFaceModelsPtr);


                    localFaceModels = (AFR_FSDK_FACEMODEL)objFeature;


                    feature = new byte[localFaceModels.lFeatureSize];


                    Marshal.Copy(localFaceModels.pbFeature, feature, 0, localFaceModels.lFeatureSize);


                    //localFaceModels = new AFR_FSDK_FACEMODEL();


                    Console.WriteLine("############### Face Recognition End   #########################");


                }


                bitmap.Dispose();


                imageData = null;


                Marshal.FreeHGlobal(imageDataPtr);


                offInput = new ASVLOFFSCREEN();


                faceRes = new AFD_FSDK_FACERES();


                //Marshal.FreeHGlobal(faceResPtr);
            }
            catch (Exception e)
            {
                LogHelper.WriteErrorLog("detect", e.Message + "\n" + e.StackTrace);
            }
            return feature;
        }


        //初始化
        private void Form1_Load(object sender, EventArgs e)
        {
            #region 初始化人脸检测引擎


            int detectSize = 40 * 1024 * 1024;


            IntPtr pMem = Marshal.AllocHGlobal(detectSize);


            //1-1
            //string appId = "4tnYSJ68e8wztSo4Cf7WvbyMZduHwpqtThAEM3obMWbE";


            //1-1
            //string sdkKey = "Cgbaq34izc8PA2Px26x8qqWTQn2P5vxijaWKdUrdCwYT";


            //1-n
            string appId = "8b4R2gvcoFQXKbC4wGtnYcqsa9Bd3FLiN3VWDFtJqcnB";


            //1-n
            string sdkKey = "A5Km3QjZKGuakWRmC2pSWTuNzbNbaSCnj5fFtjBBcdxm";


            //人脸检测引擎初始化


            // IntPtr aaa= AFD_FSDKLibrary.AFD_FSDK_InitialFaceEngine(appId, sdkKey, pMem, detectSize, ref detectEngine, 5, 50, 1);
            int retCode = AmFaceVerify.AFD_FSDK_InitialFaceEngine(appId, sdkKey, pMem, detectSize, ref detectEngine, 5, 50, 1);
            //获取人脸检测引擎版本
            IntPtr versionPtr = AmFaceVerify.AFD_FSDK_GetVersion(detectEngine);


            AFR_FSDK_Version version = (AFR_FSDK_Version)Marshal.PtrToStructure(versionPtr, typeof(AFR_FSDK_Version));


            Console.WriteLine("lCodebase:{0} lMajor:{1} lMinor:{2} lBuild:{3} Version:{4} BuildDate:{5} CopyRight:{6}", version.lCodebase, version.lMajor, version.lMinor, version.lBuild, Marshal.PtrToStringAnsi(version.Version), Marshal.PtrToStringAnsi(version.BuildDate), Marshal.PtrToStringAnsi(version.CopyRight));


            //Marshal.FreeHGlobal(versionPtr);


            #endregion


            #region 初始化人脸识别引擎


            int recognizeSize = 40 * 1024 * 1024;


            IntPtr pMemDetect = Marshal.AllocHGlobal(recognizeSize);


            //1-1
            //string appIdDetect = "4tnYSJ68e8wztSo4Cf7WvbyMZduHwpqtThAEM3obMWbE";


            //1-1
            //string sdkKeyDetect = "Cgbaq34izc8PA2Px26x8qqWaaBHbPD7wWMcTU6xe8VRo";


            //1-n
            string appIdDetect = "8b4R2gvcoFQXKbC4wGtnYcqsa9Bd3FLiN3VWDFtJqcnB";


            //1-n
            string sdkKeyDetect = "A5Km3QjZKGuakWRmC2pSWTuW9zdndn5EkVDo4LceRxLU";


            //人脸识别引擎初始化
            retCode = AmFaceVerify.AFR_FSDK_InitialEngine(appIdDetect, sdkKeyDetect, pMemDetect, recognizeSize, ref regcognizeEngine);


            //获取人脸识别引擎版本
            IntPtr versionPtrDetect = AmFaceVerify.AFR_FSDK_GetVersion(regcognizeEngine);


            AFR_FSDK_Version versionDetect = (AFR_FSDK_Version)Marshal.PtrToStructure(versionPtrDetect, typeof(AFR_FSDK_Version));


            Console.WriteLine("lCodebase:{0} lMajor:{1} lMinor:{2} lBuild:{3} lFeatureLevel:{4} Version:{5} BuildDate:{6} CopyRight:{7}", versionDetect.lCodebase, versionDetect.lMajor, versionDetect.lMinor, versionDetect.lBuild, versionDetect.lFeatureLevel, Marshal.PtrToStringAnsi(versionDetect.Version), Marshal.PtrToStringAnsi(versionDetect.BuildDate), Marshal.PtrToStringAnsi(versionDetect.CopyRight));


            #endregion
        }


        //拖拽事件
        private void Form1_DragDrop(object sender, DragEventArgs e)
        {
            // Extract the data from the DataObject-Container into a string list
            string[] fileList = (string[])e.Data.GetData(DataFormats.FileDrop, false);


            if (fileList.Length >= 2)
            {
                this.threadMultiExec = new Thread(new ParameterizedThreadStart(multiCompare));


                this.threadMultiExec.Start(new object[] { fileList });


                this.threadMultiExec.IsBackground = true;
            }


        }


        private void Form1_DragEnter(object sender, DragEventArgs e)
        {
            // Check if the Dataformat of the data can be accepted
            // (we only accept file drops from Explorer, etc.)
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.Copy; // Okay
            }
            else
            {
                e.Effect = DragDropEffects.None; // Unknown data, ignore it
            }
        }


        //多线程设置PictureBox的图像
        private void setPictureBoxControlImage(PictureBox control, Bitmap value)
        {
            control.Invoke(new Action<PictureBox, Bitmap>((ct, v) => { ct.Image = v; }), new object[] { control, value });
        }


        //多线程设置控件的文本
        private void setControlText(Control control, string value)
        {
            control.Invoke(new Action<Control, string>((ct, v) => { ct.Text = v; }), new object[] { control, value });
        }


        //比对多个图片
        private void multiCompare(object args)
        {
            object[] objs = args as object[];


            string[] fileList = (string[])objs[0];


            for (int i = 0; i < fileList.Length; i++)
            {


                Image image = Image.FromFile(fileList[i]);


                //this.pictureBox1.Image = null;


                //this.pictureBox1.Image = new Bitmap(image);


                setPictureBoxControlImage(this.pictureBox1, new Bitmap(image));


                firstFeature = detectAndExtractFeature(image, 1);


                image.Dispose();


                if (firstFeature == null)
                {


                    continue;
                }


                if (i + 1 >= fileList.Length)
                {


                    continue;
                }


                Image image2 = Image.FromFile(fileList[++i]);


                //this.pictureBox2.Image = null;


                // this.pictureBox2.Image = new Bitmap(image2);


                setPictureBoxControlImage(this.pictureBox2, new Bitmap(image2));


                secondFeature = detectAndExtractFeature(image2, 2);


                image2.Dispose();


                if (secondFeature == null)
                {


                    continue;
                }


                button3_Click(null, null);


                setControlText(this.label6, "正在处理:" + (i + 1).ToString());


                //label6.Text = "正在处理:" + (i + 1).ToString();


                //this.Update();


                Thread.Sleep(10);


            }


        }
 
    }
}

















猜你喜欢

转载自blog.csdn.net/zhang1244/article/details/80049738