using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace WIDESEAWCS_Common.Face { public class FaceHelper { static string picturePath = ""; static FileInfo[] fileInfos; static string currentPath = ""; /// /// 人脸识别方法 /// /// 已录入人脸图片路径 /// 要是被的人脸图片路径 /// public static (bool, string) FaceRecognition(string sourcePath, string desPath) { int ret = TH_Faces.IdFaceSdkInit(); if (ret < 0) { IntPtr pRunCode = Marshal.AllocHGlobal(35 + 1); TH_Faces.IdFaceSdkGetRunCode(pRunCode); Marshal.FreeHGlobal(pRunCode); } picturePath = sourcePath; currentPath = desPath; List pFrame_Sources = new List(); List pFeature_Sources = new List(); GetSourceFeature(ref pFrame_Sources, ref pFeature_Sources); IntPtr pFrame_Desc = IntPtr.Zero; IntPtr pFeature_Desc = IntPtr.Zero; GetDesFeature(ref pFrame_Desc, ref pFeature_Desc); List bytes = Check(ref pFrame_Desc, ref pFeature_Desc, ref pFrame_Sources, ref pFeature_Sources); if (bytes.Count == 0) { return (false, "人脸识别失败"); } byte max = bytes.Max(); // 获取最大分数 int index = bytes.IndexOf(max); // 获取最大分数的索引 if (fileInfos.Length > index) { if (max < 80) // 如果最大分数小于80,认为人脸识别失败 { return (false, "人脸识别失败"); } return (true, fileInfos[index].Name); // 返回对应的文件名 } return (false, "人脸识别失败"); } public static (bool, string) FaceRecognitionOne(string sourcePath, string desPath) { int ret = TH_Faces.IdFaceSdkInit(); if (ret < 0) { IntPtr pRunCode = Marshal.AllocHGlobal(35 + 1); TH_Faces.IdFaceSdkGetRunCode(pRunCode); Marshal.FreeHGlobal(pRunCode); } picturePath = sourcePath; currentPath = desPath; IntPtr pFrame_Source = IntPtr.Zero; IntPtr pFeature_Source = IntPtr.Zero; GetSourceFeature(ref pFrame_Source, ref pFeature_Source); IntPtr pFrame_Desc = IntPtr.Zero; IntPtr pFeature_Desc = IntPtr.Zero; GetDesFeature(ref pFrame_Desc, ref pFeature_Desc); byte result = Check(ref pFrame_Desc, ref pFeature_Desc, ref pFrame_Source, ref pFeature_Source); if (result < 80) // 如果最大分数小于80,认为人脸识别失败 { return (false, "人脸识别失败"); } return (true, "人脸识别成功"); // 返回对应的文件名 } private static void GetSourceFeature(ref List pFrame_Sources, ref List pFeature_Sources) { DirectoryInfo dir = new DirectoryInfo(picturePath); fileInfos = dir.GetFiles(); foreach (var file in fileInfos) { // 读原始图象 int nWidth1 = 0; int nHeight1 = 0; IntPtr pSrcFilepath = Marshal.StringToHGlobalAnsi(file.FullName); // 读图象分辨率 int ret = TH_Faces.ReadImageFile(pSrcFilepath, IntPtr.Zero, 0, ref nWidth1, ref nHeight1, 24); if (ret < 0 || nWidth1 <= 0 || nHeight1 <= 0) { continue; } // 根据图象分辨率分配图象数据缓冲区并读出图象数据 IntPtr pFrame_Source = Marshal.AllocHGlobal(nWidth1 * nHeight1 * 3); TH_Faces.ReadImageFile(pSrcFilepath, pFrame_Source, nWidth1 * nHeight1 * 3, ref nWidth1, ref nHeight1, 24); if (ret < 0 || nWidth1 <= 0 || nHeight1 <= 0) { Marshal.FreeHGlobal(pFrame_Source); continue; } // 对原始图象进行人脸检测 TH_Faces.FACE_DETECT_RESULT Face1 = new TH_Faces.FACE_DETECT_RESULT(); int nNum1 = TH_Faces.IdFaceSdkDetectFace(pFrame_Source, nWidth1, nHeight1, ref Face1); if (nNum1 <= 0) { Marshal.FreeHGlobal(pFrame_Source); continue; } // 对原始图象提取人脸特征(输入原始图象及其人脸检测结果) int nFeaSize = TH_Faces.IdFaceSdkFeatureSize(); IntPtr pFeature_Source = Marshal.AllocHGlobal(nFeaSize); ret = TH_Faces.IdFaceSdkFeatureGet(pFrame_Source, nWidth1, nHeight1, ref Face1, pFeature_Source); if (ret != 0) { Marshal.FreeHGlobal(pFrame_Source); Marshal.FreeHGlobal(pFeature_Source); continue; } pFrame_Sources.Add(pFrame_Source); pFeature_Sources.Add(pFeature_Source); } } private static void GetSourceFeature(ref IntPtr pFrame_Source, ref IntPtr pFeature_Source) { // 读原始图象 int nWidth1 = 0; int nHeight1 = 0; IntPtr pSrcFilepath = Marshal.StringToHGlobalAnsi(picturePath); // 读图象分辨率 int ret = TH_Faces.ReadImageFile(pSrcFilepath, IntPtr.Zero, 0, ref nWidth1, ref nHeight1, 24); if (ret < 0 || nWidth1 <= 0 || nHeight1 <= 0) { return; } // 根据图象分辨率分配图象数据缓冲区并读出图象数据 pFrame_Source = Marshal.AllocHGlobal(nWidth1 * nHeight1 * 3); TH_Faces.ReadImageFile(pSrcFilepath, pFrame_Source, nWidth1 * nHeight1 * 3, ref nWidth1, ref nHeight1, 24); if (ret < 0 || nWidth1 <= 0 || nHeight1 <= 0) { Marshal.FreeHGlobal(pFrame_Source); } // 对原始图象进行人脸检测 TH_Faces.FACE_DETECT_RESULT Face1 = new TH_Faces.FACE_DETECT_RESULT(); int nNum1 = TH_Faces.IdFaceSdkDetectFace(pFrame_Source, nWidth1, nHeight1, ref Face1); if (nNum1 <= 0) { Marshal.FreeHGlobal(pFrame_Source); } // 对原始图象提取人脸特征(输入原始图象及其人脸检测结果) int nFeaSize = TH_Faces.IdFaceSdkFeatureSize(); pFeature_Source = Marshal.AllocHGlobal(nFeaSize); ret = TH_Faces.IdFaceSdkFeatureGet(pFrame_Source, nWidth1, nHeight1, ref Face1, pFeature_Source); if (ret != 0) { Marshal.FreeHGlobal(pFrame_Source); Marshal.FreeHGlobal(pFeature_Source); } } private static bool GetDesFeature(ref IntPtr pFrame_Desc, ref IntPtr pFeature_Desc) { // 读目标图象 int nWidth2 = 0; int nHeight2 = 0; IntPtr pDstFilepath = Marshal.StringToHGlobalAnsi(currentPath); // 读图象分辨率 int ret = TH_Faces.ReadImageFile(pDstFilepath, IntPtr.Zero, 0, ref nWidth2, ref nHeight2, 24); if (ret < 0 || nWidth2 <= 0 || nHeight2 <= 0) { return false; } // 根据图象分辨率分配图象数据缓冲区并读出图象数据 pFrame_Desc = Marshal.AllocHGlobal(nWidth2 * nHeight2 * 3); ret = TH_Faces.ReadImageFile(pDstFilepath, pFrame_Desc, nWidth2 * nHeight2 * 3, ref nWidth2, ref nHeight2, 24); if (ret < 0 || nWidth2 <= 0 || nHeight2 <= 0) { Marshal.FreeHGlobal(pFrame_Desc); return false; } // 对目标图象进行人脸检测 TH_Faces.FACE_DETECT_RESULT Face2 = new TH_Faces.FACE_DETECT_RESULT(); int nNum2 = TH_Faces.IdFaceSdkDetectFace(pFrame_Desc, nWidth2, nHeight2, ref Face2); if (nNum2 <= 0) { Marshal.FreeHGlobal(pFrame_Desc); return false; } int nFeaSize = TH_Faces.IdFaceSdkFeatureSize(); pFeature_Desc = Marshal.AllocHGlobal(nFeaSize); ret = TH_Faces.IdFaceSdkFeatureGet(pFrame_Desc, nWidth2, nHeight2, ref Face2, pFeature_Desc); if (ret != 0) { Marshal.FreeHGlobal(pFrame_Desc); Marshal.FreeHGlobal(pFeature_Desc); return false; } return true; } private static List Check(ref IntPtr pFrame_Desc, ref IntPtr pFeature_Desc, ref List pFrame_Sources, ref List pFeature_Sources) { IntPtr hList = TH_Faces.IdFaceSdkListCreate(1000); // 创建支持1000个特征的比对列表 try { List results = new List(); int i, n = 0; for (i = 0; i < pFeature_Sources.Count; i++) { // 将两个人的特征码循环交叉插入比对列表中 int nPos = -1; n = TH_Faces.IdFaceSdkListInsert(hList, ref nPos, pFeature_Sources[i], 1); } if (n != pFeature_Sources.Count) { return results; ; } else { IntPtr pnScores = Marshal.AllocHGlobal(pFeature_Sources.Count); n = TH_Faces.IdFaceSdkListCompare(hList, pFeature_Desc, 0, pFeature_Sources.Count, pnScores); // 现场人与加入列表中的 N 个人进行一对多比对 if (n != pFeature_Sources.Count) { return results; } else { byte[] scores = new byte[pFeature_Sources.Count]; Marshal.Copy(pnScores, scores, 0, pFeature_Sources.Count); results = scores.ToList(); // 将比对结果转换为 List 类型 } Marshal.FreeHGlobal(pnScores); } return results; } finally { TH_Faces.IdFaceSdkListDestroy(hList); // 销毁比对列表 Marshal.FreeHGlobal(pFrame_Desc); Marshal.FreeHGlobal(pFeature_Desc); foreach (var pFrame in pFrame_Sources) { Marshal.FreeHGlobal(pFrame); } foreach (var pFeature in pFeature_Sources) { Marshal.FreeHGlobal(pFeature); } TH_Faces.IdFaceSdkUninit(); } } private static byte Check(ref IntPtr pFrame_Desc, ref IntPtr pFeature_Desc, ref IntPtr pFrame_Source, ref IntPtr pFeature_Source) { try { byte score = TH_Faces.IdFaceSdkFeatureCompare(pFeature_Source, pFeature_Desc); return score; } finally { Marshal.FreeHGlobal(pFrame_Desc); Marshal.FreeHGlobal(pFeature_Desc); Marshal.FreeHGlobal(pFrame_Source); Marshal.FreeHGlobal(pFeature_Source); TH_Faces.IdFaceSdkUninit(); } } } }