1
z8018
2025-06-06 ee5e3a086a5dc145e7f5df3de32e0e072c183949
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
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();
            }
        }
    }
}