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 = "";
|
|
/// <summary>
|
/// 人脸识别方法
|
/// </summary>
|
/// <param name="sourcePath">已录入人脸图片路径</param>
|
/// <param name="desPath">要是被的人脸图片路径</param>
|
/// <returns></returns>
|
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<IntPtr> pFrame_Sources = new List<IntPtr>();
|
List<IntPtr> pFeature_Sources = new List<IntPtr>();
|
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<byte> 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<IntPtr> pFrame_Sources, ref List<IntPtr> 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<byte> Check(ref IntPtr pFrame_Desc, ref IntPtr pFeature_Desc, ref List<IntPtr> pFrame_Sources, ref List<IntPtr> pFeature_Sources)
|
{
|
IntPtr hList = TH_Faces.IdFaceSdkListCreate(1000); // 创建支持1000个特征的比对列表
|
try
|
{
|
List<byte> results = new List<byte>();
|
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<byte> 类型
|
|
}
|
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();
|
}
|
}
|
}
|
}
|