using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Runtime.InteropServices; using System.IO; using OpenCvSharp; // 提取人脸特征值 namespace FaceAI { // 人脸特征值结构体 [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct BDFaceFeature { public int size; // 人脸的特征值,提取出来后是128个float的浮点值 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] public float[] data;// = new float[128]; } // 人脸特征值结构体 [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct BDDepthFeature { public int size; // 人脸的深度特征值,提取出来后是256个float的浮点值 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] public float[] data;// = new float[256]; } class FaceFeature { // 提取人脸特征值 [DllImport("BaiduFaceApi.dll", EntryPoint = "face_feature", CharSet = CharSet.Ansi , CallingConvention = CallingConvention.Cdecl)] // 返回num为特征值的人数,type为0表示提取生活照的特征值,1表示nir的特征值 public static extern int face_feature(IntPtr feature, IntPtr box, IntPtr mat, int type); public void test_face_feature() { long t_begin = TimeUtil.get_time_stamp(); BDFaceFeature[] fea1 = test_get_face_feature_by_path("../images/2.jpg"); long t_end = TimeUtil.get_time_stamp(); Console.WriteLine("get feature time cost is:" + (t_end - t_begin)); } // 获取特征值,传入图片路径 public BDFaceFeature[] test_get_face_feature_by_path(string img_path) { // 特征值的长度,128个float值 int dim_count = 128; Mat mat = Cv2.ImRead(img_path); // 假设提取的人数,需要比实际的人数多,因为需要提取分配内存 int faceNum = 5; BDFaceFeature[] feaList = new BDFaceFeature[faceNum]; for(int i = 0; i < faceNum; i++) { feaList[i].data = new float[dim_count]; feaList[i].size = 0; } if (mat.Empty()) { return null; } int sizeFeature = Marshal.SizeOf(typeof(BDFaceFeature)); IntPtr ptFea = Marshal.AllocHGlobal(sizeFeature * faceNum); // 构造返回的人脸框数据 BDFaceBBox[] info = new BDFaceBBox[faceNum]; int sizeBox = Marshal.SizeOf(typeof(BDFaceBBox)); IntPtr ptBox = Marshal.AllocHGlobal(sizeBox * faceNum); // 返回num为特征值的人数,type为0表示提取生活照的特征值,1表示证件照的特征值,2表示nir的特征值 int type = 0; int num = face_feature(ptFea, ptBox, mat.CvPtr, type); if (num <= 0) { return null; } Console.WriteLine("face num is:{0}", num); // 请确保faceNum大于num, faceNum为c#期望的检测人数,需要预先分配内存,否则无法获取 if (num > faceNum) { num = faceNum; } for (int index = 0; index < num; index++) { IntPtr ptrF = new IntPtr(); IntPtr ptrB = new IntPtr(); if (8 == IntPtr.Size) { ptrF = (IntPtr)(ptFea.ToInt64() + sizeFeature * index); ptrB = (IntPtr)(ptBox.ToInt64() + sizeBox * index); } else if (4 == IntPtr.Size) { ptrF = (IntPtr)(ptFea.ToInt32() + sizeFeature * index); ptrB = (IntPtr)(ptBox.ToInt32() + sizeBox * index); } feaList[index] = (BDFaceFeature)Marshal.PtrToStructure(ptrF, typeof(BDFaceFeature)); Console.WriteLine("feaList[index].size is:{0}", feaList[index].size); for (int k = 0; k < feaList[index].size; k++) { Console.WriteLine("feature is {0}:", feaList[index].data[k]); } info[index] = (BDFaceBBox)Marshal.PtrToStructure(ptrB, typeof(BDFaceBBox)); // 索引值 Console.WriteLine("detect score is:{0}", info[index].index); // 置信度 Console.WriteLine("detect score is:{0}", info[index].score); // 人脸宽度 Console.WriteLine("detect mWidth is:{0}", info[index].width); // 中心点X,Y坐标 Console.WriteLine("detect mCenter_x is:{0}", info[index].center_x); Console.WriteLine("detect mCenter_y is:{0}", info[index].center_y); } // 绘制人脸框 FaceDraw.draw_rects(ref mat, faceNum, info); //mat.ImWrite("detect.jpg"); mat.Release(); return feaList; } } }