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();
}
}
}
}