//释放内存 public void Close() { if (_DEnginer != IntPtr.Zero) { ArcWrapper.DClose(_DEnginer); _DEnginer = IntPtr.Zero; } if (_DBuffer != IntPtr.Zero) { Marshal.FreeCoTaskMem(_DBuffer); _DBuffer = IntPtr.Zero; } if (_REnginer != IntPtr.Zero) { ArcWrapper.RClose(_REnginer); _REnginer = IntPtr.Zero; } if (_RBuffer != IntPtr.Zero) { Marshal.FreeCoTaskMem(_RBuffer); _RBuffer = IntPtr.Zero; } foreach (var item in _FaceLib.Items) { Marshal.FreeCoTaskMem(item.FaceModel.PFeature); } }
//人脸比对 public FaceMatchResults Match(Bitmap bitmap, float degree = 0.90f, int num = 1) { var faceMatchResults = new FaceMatchResults() { Items = new List<FaceMatchResult>() }; var faceModel = ExtractFeature(bitmap); foreach (var item in _FaceLib.Items.OrderByDescending(ii => ii.OrderId)) { ArcWrapper.Match(_REnginer, ref faceModel, ref item.FaceModel, out float score); if (score > degree) { faceMatchResults.Items.Add(new FaceMatchResult { ID = item.ID, Score = score }); if (faceMatchResults.Items.Count >= num) { return faceMatchResults; } } } return faceMatchResults; }
//特征提取 private FaceModel ExtractFeature(Bitmap bitmap) { var detectResult = Detection(bitmap); var bmpData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height) , ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); var imageData = new ImageData { PixelArrayFormat = 513,//Rgb24, Width = bitmap.Width, Height = bitmap.Height, Pitch = new int[4] { bmpData.Stride, 0, 0, 0 }, ppu8Plane = new IntPtr[4] { bmpData.Scan0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero } }; var FFI = new FaceFeatureInput(); FFI.FaceRect = Marshal.PtrToStructure<FaceRect>(detectResult.PFaceRect); FFI.Orient = 1; FaceModel faceModel = new FaceModel() { Size = 22020, PFeature = Marshal.AllocCoTaskMem(22020) }; faceModel.Size = 0; if (ArcWrapper.ExtractFeature(_REnginer, ref imageData, ref FFI, out var fm) == (int)ErrorCode.Ok) { faceModel.Size = fm.Size; ArcWrapper.CopyMemory(faceModel.PFeature, fm.PFeature, fm.Size); } return faceModel; }
//人脸比对初始化 private bool Rinit(string appId, string sdkKey, IntPtr pBuffer, int bufferSize, out IntPtr engine) { pBuffer = Marshal.AllocCoTaskMem(bufferSize); var initResult = (ErrorCode)ArcWrapper.RInit(appId, sdkKey, pBuffer, bufferSize, out engine); if (initResult != ErrorCode.Ok) { return false; } return true; }
//人脸检测初始化 private bool Dinit(string appId, string sdkKey, IntPtr pBuffer, int bufferSize , out IntPtr engine, int orientPriority, int scale, int maxFaceNumber) { pBuffer = Marshal.AllocCoTaskMem(bufferSize); var initResult = (ErrorCode)ArcWrapper.DInit(appId, sdkKey, pBuffer, bufferSize , out engine, (int)EOrientPriority.Only0, scale, maxFaceNumber); if (initResult != ErrorCode.Ok) { return false; } return true; }
//人脸检测 public DetectResult Detection(Bitmap bitmap) { var bmpData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height) , ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); var imageData = new ImageData { PixelArrayFormat = 513,//Rgb24, Width = bitmap.Width, Height = bitmap.Height, Pitch = new int[4] { bmpData.Stride, 0, 0, 0 }, ppu8Plane = new IntPtr[4] { bmpData.Scan0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero } }; var ret = (ErrorCode)ArcWrapper.Detection(_DEnginer, ref imageData, out var pDetectResult); if (ret != ErrorCode.Ok) { bitmap.UnlockBits(bmpData); return new DetectResult { FaceCout = 0 }; } var detectResult = Marshal.PtrToStructure<DetectResult>(pDetectResult); bitmap.UnlockBits(bmpData); return detectResult; }