| | |
| | | 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; |
| | | //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); |
| | | //// 提取人脸特征值 |
| | | //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 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; |
| | | } |
| | | // // 获取特征值,传入图片路径 |
| | | // 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; |
| | | } |
| | | // if (mat.Empty()) |
| | | // { |
| | | // return null; |
| | | // } |
| | | |
| | | int sizeFeature = Marshal.SizeOf(typeof(BDFaceFeature)); |
| | | IntPtr ptFea = Marshal.AllocHGlobal(sizeFeature * faceNum); |
| | | // 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); |
| | | // // 构造返回的人脸框数据 |
| | | // 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]); |
| | | } |
| | | // 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)); |
| | | // 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); |
| | | // // 索引值 |
| | | // 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; |
| | | } |
| | | // //mat.ImWrite("detect.jpg"); |
| | | // mat.Release(); |
| | | // return feaList; |
| | | // } |
| | | |
| | | } |
| | | } |
| | | // } |
| | | //} |