1
z8018
2025-06-06 7876ac5d67b12e206a68db17c4034df52fa2f060
1
已删除13个文件
已修改11个文件
已添加14个文件
98946 ■■■■■ 文件已修改
project/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/17.14.670.39694/CodeChunks.db 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/17.14.670.39694/CodeChunks.db-shm 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/17.14.670.39694/CodeChunks.db-wal 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/17.14.670.39694/SemanticSymbols.db 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/17.14.670.39694/SemanticSymbols.db-shm 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/17.14.670.39694/SemanticSymbols.db-wal 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/Face/CHS_Capture.cs 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/Face/FaceHelper.cs 314 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/Face/TH_Faces.cs 210 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/FaceAI/FaceAttr.cs 196 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/FaceAI/FaceCompare.cs 1488 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/FaceAI/FaceDraw.cs 290 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/FaceAI/FaceFeature.cs 238 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/FaceAI/FaceLiveness.cs 970 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/FaceAI/FaceManager.cs 380 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/FaceAI/FaceTrack.cs 406 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_ISystemServices/ISys_UserFaceService.cs 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Model/Models/System/Sys_Log.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Model/Models/System/Sys_UserFace.cs 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Controllers/System/Sys_UserController.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Controllers/System/Sys_UserFaceController.cs 134 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/DownLoad/face-plugin.zip 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_Server.csproj 56 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/wwwroot/WIDESEAWCS_DB.DBSeed.Json/Dt_DeviceInfo.tsv 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/wwwroot/WIDESEAWCS_DB.DBSeed.Json/Dt_DeviceProtocol.tsv 2977 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/wwwroot/WIDESEAWCS_DB.DBSeed.Json/Dt_DeviceProtocolDetail.tsv 262 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/wwwroot/WIDESEAWCS_DB.DBSeed.Json/Dt_DispatchInfo.tsv 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/wwwroot/WIDESEAWCS_DB.DBSeed.Json/Dt_Router.tsv 362 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/wwwroot/WIDESEAWCS_DB.DBSeed.Json/Dt_Task.tsv 5651 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/wwwroot/WIDESEAWCS_DB.DBSeed.Json/Dt_TaskExecuteDetail.tsv 83282 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/wwwroot/WIDESEAWCS_DB.DBSeed.Json/Sys_Dictionary.tsv 254 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/wwwroot/WIDESEAWCS_DB.DBSeed.Json/Sys_DictionaryList.tsv 548 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/wwwroot/WIDESEAWCS_DB.DBSeed.Json/Sys_Menu.tsv 344 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/wwwroot/WIDESEAWCS_DB.DBSeed.Json/Sys_Role.tsv 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/wwwroot/WIDESEAWCS_DB.DBSeed.Json/Sys_RoleAuth.tsv 167 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/wwwroot/WIDESEAWCS_DB.DBSeed.Json/Sys_User.tsv 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_SystemServices/Sys_UserFaceService.cs 214 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_SystemServices/Sys_UserService.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
project/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/17.14.670.39694/CodeChunks.db
Binary files differ
project/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/17.14.670.39694/CodeChunks.db-shm
Binary files differ
project/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/17.14.670.39694/CodeChunks.db-wal
Binary files differ
project/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/17.14.670.39694/SemanticSymbols.db
Binary files differ
project/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/17.14.670.39694/SemanticSymbols.db-shm
Binary files differ
project/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/17.14.670.39694/SemanticSymbols.db-wal
Binary files differ
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/Face/CHS_Capture.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace WIDESEAWCS_Common.Face
{
    // ç›¸æœºå–帧及帧图象显示组件
    public class CHS_Capture
    {
        // è¿”回相机个数
        [DllImport("SmCameraPreview.dll", EntryPoint = "SmCameraGetCount", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int SmCameraGetCount();
        // æ‰“开相机(根据相机索引号 nDeviceId)
        [DllImport("SmCameraPreview.dll", EntryPoint = "SmCameraOpen", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern IntPtr SmCameraOpen(int nDeviceId, int nWidth, int nHeight);
        // æ‰“开相机(根据相机VID+PIC)
        [DllImport("SmCameraPreview.dll", EntryPoint = "SmCameraOpenEx", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern IntPtr SmCameraOpenEx(int nVid, int nPid, int nWidth, int nHeight);
        // ä»Žæ‰“开的相机提取一帧视频数据
        [DllImport("SmCameraPreview.dll", EntryPoint = "SmCameraGetFrame", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int SmCameraGetFrame(IntPtr hCamera, IntPtr pFrameBuf, int bMirror, int bFlip);
        // å…³é—­ç›¸æœº
        [DllImport("SmCameraPreview.dll", EntryPoint = "SmCameraClose", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern void SmCameraClose(IntPtr hCamera);
        // åˆ›å»ºè§†é¢‘帧显示对象(nWidth * nHeight ä¸ºè§†é¢‘帧的分辨率,hWnd ä¸ºæ˜¾ç¤ºçª—口句柄)
        [DllImport("SmCameraPreview.dll", EntryPoint = "SmCameraPreviewCreate", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern IntPtr SmCameraPreviewCreate(int nWidth, int nHeight, IntPtr hWND);
        // æ˜¾ç¤ºè§†é¢‘帧
        [DllImport("SmCameraPreview.dll", EntryPoint = "SmCameraPreview", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern void SmCameraPreview(IntPtr hCameraPreview, IntPtr pFrame);
        // æ˜¾ç¤ºè§†é¢‘帧及人脸框(weight为边框的厚度)
        [DllImport("SmCameraPreview.dll", EntryPoint = "SmCameraPreviewFace", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern void SmCameraPreviewFace(IntPtr hCameraPreview, IntPtr pFrame, int left, int top, int right, int bottom, int weight, int color);
        // é‡Šæ”¾è§†é¢‘帧显示对象
        [DllImport("SmCameraPreview.dll", EntryPoint = "SmCameraPreviewDestroy", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern void SmCameraPreviewDestroy(IntPtr hCameraPreivew);
    }
}
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/Face/FaceHelper.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,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();
            }
        }
    }
}
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/Face/TH_Faces.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,210 @@
using System.Runtime.InteropServices;
namespace WIDESEAWCS_Common.Face
{
    public class TH_Faces // äººè„¸æ£€æµ‹åŠè¯†åˆ«SDK接口,可参见 IdFaceSdk.h(内含所有接口的功能、参数、返回值的具体描述)
    {
        #region ç»“构体定义
        public struct RECT
        {
            public Int32 left;
            public Int32 top;
            public Int32 right;
            public Int32 bottom;
        };
        public struct POINT
        {
            public Int32 x;
            public Int32 y;
        };
        // äººè„¸æ£€æµ‹è¿”回的人脸坐标参数
        public struct FACE_DETECT_RESULT
        {
            public RECT rcFace;//coordinate of face
            public POINT ptLeftEye;//coordinate of left eye
            public POINT ptRightEye;//coordinate of right eye
            public POINT ptMouth;//coordinate of mouth
            public POINT ptNose;//coordinate of nose
            public Int32 nAngleYaw, nAnglePitch, nAngleRoll;//value of face angle
            public Int32 nQuality;//quality of face(from 0 to 100)
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
            public Byte[] FaceData;
        };
        // äººè„¸è´¨é‡æ£€æµ‹è¿”回的人脸质量参数
        public struct FACE_QUALITY_LEVEL
        {
            public Int32 nHalf; // äººè„¸å®Œæ•´æ€§: 0-正常,1-人脸不太完整,2-人脸非常不完整
            public Int32 nSmall; // äººè„¸å¤§å°ï¼š0-正常,1-人脸较小,2-人脸太小
            public Int32 nPosture; // å§¿æ€ï¼š0-正常,1-偏头较多,2-偏头太多
            public Int32 nMask; // è„¸éƒ¨é®æŒ¡: 0-正常,1-人脸有遮挡,2-人脸遮挡太多
            public Int32 nFaceMask; // å£ç½©ï¼š0-正常,1-有戴口罩,2-确认戴口罩
            public Int32 nHat; // å¸½å­ï¼š0-正常,1-有戴帽,2-帽子遮挡脸部
            public Int32 nGlasses; // çœ¼é•œ: 0-正常,1-有戴眼镜,2-确认戴眼镜
            public Int32 nGape; // å¼ å˜´: 0-正常,1-张嘴,2-张大嘴
            public Int32 nBlur; // æ¨¡ç³Šåº¦ï¼š0-正常,1-较模糊,2-太模糊
            public Int32 nBright; // è„¸éƒ¨æ›å…‰åº¦ï¼š0-正常,1-太暗,2-过爆
            public Int32 nLight; // å…‰æºæ–¹å‘: 0-正常,1-侧光,2-顶光, 3-逆光
        };
        #endregion
        #region åˆå§‹åŒ–及基本功能
        // è¿”回SDK版本号(随时可调用)
        [DllImport("IdFaceSdk.dll", EntryPoint = "IdFaceSdkVer", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern Int32 IdFaceSdkVer();
        // è¿”回设备运行码
        [DllImport("IdFaceSdk.dll", EntryPoint = "IdFaceSdkGetRunCode", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern Int32 IdFaceSdkGetRunCode([Out] IntPtr pStrRunCode);
        // SDK初始化,成功返回0(后面除辅助接口外的所有功能接口都必须是SDK初始化成功后才有用)
        [DllImport("IdFaceSdk.dll", EntryPoint = "IdFaceSdkInit", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern Int32 IdFaceSdkInit();
        // SDK反初始化(后面除辅助接口外的所有功能接口在调用反初始化后均不可用,除非再次初始化)
        [DllImport("IdFaceSdk.dll", EntryPoint = "IdFaceSdkUninit", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern void IdFaceSdkUninit();
        // è®¾ç½®æ£€æµ‹å¤§å°ï¼ˆé’ˆå¯¹é«˜åˆ†è¾¨çŽ‡ä¸”äººè„¸å æ¯”è¾ƒå°æ—¶è®¾ç½®æ£€æµ‹å¤§å°ï¼Œé€šå¸¸ä¸å¿…è°ƒç”¨ï¼‰
        [DllImport("IdFaceSdk.dll", EntryPoint = "IdFaceSdkSetDetectSize", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern void IdFaceSdkSetDetectSize(Int32 nDetectSize);
        // è¿”回特征码大小
        [DllImport("IdFaceSdk.dll", EntryPoint = "IdFaceSdkFeatureSize", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern Int32 IdFaceSdkFeatureSize();
        // è¿”回当前的授权是否支持活体检测
        [DllImport("IdFaceSdk.dll", EntryPoint = "IdFaceSdkGetLiveFaceStatus", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern Int32 IdFaceSdkGetLiveFaceStatus();
        #endregion
        #region å•人脸检测
        // æ£€æµ‹æœ€å¤§äººè„¸
        [DllImport("IdFaceSdk.dll", EntryPoint = "IdFaceSdkDetectFace", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern Int32 IdFaceSdkDetectFace(IntPtr pImage, Int32 nWidth, Int32 nHeight, ref FACE_DETECT_RESULT Face);
        #endregion
        #region å¤šäººè„¸æ£€æµ‹å¹¶æå–特征
        // æ£€æµ‹å¤šäººè„¸åŒæ—¶æå–各人脸的特征(nMaxFace è¡¨ç¤ºæœ€å¤šè¦æ£€æµ‹çš„人脸个数,Faces å¿…须按最大人脸个数分配人脸坐标空间, pFeatures å¿…须按最大人脸个数分配特征码空间,pFeatures å‚æ•°ä¼  0 æ—¶åˆ™åªæ£€æµ‹äººè„¸ä¸æç‰¹å¾ï¼‰
        [DllImport("IdFaceSdk.dll", EntryPoint = "IdFaceSdkFaceFeature", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern Int32 IdFaceSdkFaceFeature(IntPtr pImage, Int32 nWidth, Int32 nHeight, Int32 nMaxFace, [Out] FACE_DETECT_RESULT[] Faces, [Out] IntPtr pFeatures);
        #endregion
        #region äººè„¸è´¨é‡æ£€æµ‹
        // æ£€æµ‹äººè„¸è´¨é‡ï¼ˆéœ€è¾“入人脸检测返回的人脸坐标)
        [DllImport("IdFaceSdk.dll", EntryPoint = "IdFaceSdkFaceQualityLevel", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern Int32 IdFaceSdkFaceQualityLevel(IntPtr pImage, Int32 nWidth, Int32 nHeight, ref FACE_DETECT_RESULT Face, ref FACE_QUALITY_LEVEL FaceQualityLevel);
        #endregion
        #region SDK特征提取
        // æå–人脸特征(需输入人脸检测返回的人脸坐标,pFeature需分配不小于一个人脸特征的空间)
        [DllImport("IdFaceSdk.dll", EntryPoint = "IdFaceSdkFeatureGet", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern Int32 IdFaceSdkFeatureGet(IntPtr pImage, Int32 nWidth, Int32 nHeight, ref FACE_DETECT_RESULT Face, [Out] IntPtr pFeature);
        #endregion
        #region ä¸€å¯¹ä¸€æ¯”对(1:1,多用于人证核验)
        // ä¸¤ä¸ªäººè„¸ç‰¹å¾æ¯”对出相似度
        [DllImport("IdFaceSdk.dll", EntryPoint = "IdFaceSdkFeatureCompare", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern Byte IdFaceSdkFeatureCompare(IntPtr pFeature1, IntPtr pFeature2);
        #endregion
        #region ä¸€å¯¹å¤šæ¯”对(1:N,多用于服务器识别)
        // åˆ›å»ºä¸€å¯¹å¤šäººè„¸æ¯”对列表
        [DllImport("IdFaceSdk.dll", EntryPoint = "IdFaceSdkListCreate", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern IntPtr IdFaceSdkListCreate(Int32 nMaxFeatureNum);
        // å‘人脸比对列表中增加/插入模板的人脸特征
        [DllImport("IdFaceSdk.dll", EntryPoint = "IdFaceSdkListInsert", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern Int32 IdFaceSdkListInsert(IntPtr hList, [In, Out] ref Int32 nPos, IntPtr pFeatures, Int32 nFeatureNum);
        // ä»Žäººè„¸æ¯”对列表中删除部分人脸特征
        [DllImport("IdFaceSdk.dll", EntryPoint = "IdFaceSdkListRemove", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern Int32 IdFaceSdkListRemove(IntPtr hList, Int32 nPos, Int32 nFeatureNum);
        // æ¸…空人脸比对列表中的所有人脸特征
        [DllImport("IdFaceSdk.dll", EntryPoint = "IdFaceSdkListClearAll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern void IdFaceSdkListClearAll(IntPtr hList);
        // ä¸€å¯¹å¤šäººè„¸æ¯”对,返回参与比对的特征数,pnScores éœ€åˆ†é…ä¸å°äºŽæ¨¡æ¿ç‰¹å¾æ•°çš„空间,调用后将输出与每个模板特征比对的结果(特征相似度)
        [DllImport("IdFaceSdk.dll", EntryPoint = "IdFaceSdkListCompare", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern Int32 IdFaceSdkListCompare(IntPtr hList, IntPtr pFeature, Int32 nPosBegin, Int32 nFeatureNum, [Out] IntPtr pnScores);
        // é”€æ¯ä¸€å¯¹å¤šç‰¹å¾æ¯”对列表
        [DllImport("IdFaceSdk.dll", EntryPoint = "IdFaceSdkListDestroy", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern void IdFaceSdkListDestroy(IntPtr hList);
        #endregion
        #region æ´»ä½“检测
        // æ´»ä½“检测(返回1表示活体),需传入人脸检测返回的人脸坐标,pImageColor ä¸Ž pImageBW å‡æœ‰æ•ˆåˆ™è¿›è¡ŒåŒç›®æ´»ä½“检测,如 pImageBW ä¸º 0 åˆ™è¿›è¡Œå½©è‰²å•目活体检测,pImageColor ä¸º 0 åˆ™è¿›è¡Œçº¢å¤–双目活体检测
        [DllImport("IdFaceSdk.dll", EntryPoint = "IdFaceSdkLiveFaceDetect", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern Int32 IdFaceSdkLiveFaceDetect(Int32 nWidth, Int32 nHeight, IntPtr pImageColor, ref FACE_DETECT_RESULT FaceColor, IntPtr pImageBW, ref FACE_DETECT_RESULT FaceBW);
        // æ´»ä½“检测并输出活检分数(可根据活检分数是否达到阈值判别是否为活体),需传入人脸检测返回的人脸坐标,pImageColor ä¸Ž pImageBW å‡æœ‰æ•ˆåˆ™è¿›è¡ŒåŒç›®æ´»ä½“检测,如 pImageBW ä¸º 0 åˆ™è¿›è¡Œå½©è‰²å•目活体检测,pImageColor ä¸º 0 åˆ™è¿›è¡Œçº¢å¤–双目活体检测
        [DllImport("IdFaceSdk.dll", EntryPoint = "IdFaceSdkLiveFaceDetectEx", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern Int32 IdFaceSdkLiveFaceDetectEx(Int32 nWidth, Int32 nHeight, IntPtr pImageColor, ref FACE_DETECT_RESULT FaceColor, IntPtr pImageBW, ref FACE_DETECT_RESULT FaceBW, ref Int32 nScore);
        #endregion
        #region è¾…助接口
        // è¯»å›¾è±¡æ–‡ä»¶åˆ°RGB24图象数据缓冲区,支持BMP、JPG、PNG图象文件,pRgbBuf å¿…须分配足够的缓冲区(不小于 nWidth * nHeight * 3),如不知道图象分辨率可将此参数传 0 åˆ™æœ¬æ¬¡è°ƒç”¨åªè¿”回图象分辨率,然后分配足够的缓冲区再次调用读出图象数据
        [DllImport("IdFaceSdk.dll", EntryPoint = "ReadImageFile", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern Int32 ReadImageFile(IntPtr filename, [Out] IntPtr pRgbBuf, Int32 nBufSize, ref Int32 nWidth, ref Int32 nHeight, Int32 nDepth);
        // è¯»å›¾è±¡æ–‡ä»¶æ•°æ®åˆ°RGB图象数据缓冲区,支持BMP、JPG、PNG图象文件,pRgbBuf å¿…须分配足够的缓冲区(不小于 nWidth * nHeight * 3),如不知道图象分辨率可将此参数传 0 åˆ™æœ¬æ¬¡è°ƒç”¨åªè¿”回图象分辨率,然后分配足够的缓冲区再次调用读出图象数据
        [DllImport("IdFaceSdk.dll", EntryPoint = "ReadImageFileData", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern Int32 ReadImageFileData(IntPtr pFileData, Int32 nFileDataSize, [Out] IntPtr pRgbBuf, Int32 nBufSize, ref Int32 nWidth, ref Int32 nHeight, Int32 nDepth);
        // æ—‹è½¬RGB24图象数据,nDegree为旋转角度(支持0、90、180、270),nMirror为0表示不镜象,为1表示左右镜象
        [DllImport("IdFaceSdk.dll", EntryPoint = "RotateRgb24Data", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern Int32 RotateRgb24Data(IntPtr pSrc, Int32 nWidth, Int32 nHeight, Int32 nDegree, Int32 nMirror, [Out] IntPtr pDst);
        // ä»ŽRGB24图象数据裁剪出小图
        // è¾“入参数:
        //           pSrc ---- åŽŸå›¾æ•°æ®ï¼ˆRGB24格式)
        //           nSrcWidth ---- åŽŸå›¾å®½åº¦
        //           nSrcHeight ---- åŽŸå›¾é«˜åº¦
        //           nLeft ---- è£å‰ªåŒºåŸŸå·¦ä¸Šè§’X坐标
        //           nTop ---- è£å‰ªåŒºåŸŸå·¦ä¸Šè§’Y坐标
        //           nWidth ---- è£å‰ªåŒºåŸŸå®½åº¦
        //           nHeight ---- è£å‰ªåŒºåŸŸé«˜åº¦
        //           nRate ---- è£å‰ªå›¾è±¡ç¼©å°å€æ•°ï¼ˆ0-不缩小,1-宽高缩小至原来的1/2,2-宽高缩小至原来的1/3,...)
        // è¾“出参数:
        //           pDst ---- å°å›¾æ•°æ®(RGB24格式,调用前需分析足够的缓冲区)
        // è¿”回值:
        //        0 ---- æˆåŠŸ
        //       -1 ---- å‚数错误
        // å¤‡æ³¨ï¼šè£å‰ªåŽçš„图象分辨率为:宽度 = nWidth / (nRate + 1), é«˜åº¦ = nHeight / (nRate + 1)
        [DllImport("IdFaceSdk.dll", EntryPoint = "CropImage", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern Int32 CropImage(IntPtr pSrc, Int32 nSrcWidth, Int32 nSrcHeight, [Out] IntPtr pDst, int nLeft, int nTop, int nWidth, int nHeight, int nRate);
        // å°†RGB24图象数据保存为JPEG文件
        [DllImport("IdFaceSdk.dll", EntryPoint = "SaveJpegFile", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern Int32 SaveJpegFile(IntPtr filename, IntPtr pRgbData, Int32 nWidth, Int32 nHeight, Int32 nDepth, Int32 nQuality);
        // å°†RGB24图象数据保存为JPEG文件数据
        [DllImport("IdFaceSdk.dll", EntryPoint = "SaveJpegFileData", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern Int32 SaveJpegFileData(IntPtr pRgbData, Int32 nWidth, Int32 nHeight, Int32 nDepth, Int32 nQuality, [Out] IntPtr pFileDataBuf, Int32 nBufSize, ref Int32 nFileDataSize);
        #endregion
    }
}
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/FaceAI/FaceAttr.cs
@@ -1,109 +1,109 @@
using System;
using System.Runtime.InteropServices;
using OpenCvSharp;
//using System;
//using System.Runtime.InteropServices;
//using OpenCvSharp;
namespace FaceAI
{
    /**
         * @brief   äººè„¸è¡¨æƒ…属性枚举
         */
    enum BDFaceAttributeEmotionType
    {
        BDFACE_ATTRIBUTE_EMOTION_FROWN = 0,     // çš±çœ‰
        BDFACE_ATTRIBUTE_EMOTION_SMILE = 1,     // ç¬‘
        BDFACE_ATTRIBUTE_EMOTION_CALM = 2,      // å¹³é™
    };
//namespace FaceAI
//{
//    /**
//         * @brief   äººè„¸è¡¨æƒ…属性枚举
//         */
//    enum BDFaceAttributeEmotionType
//    {
//        BDFACE_ATTRIBUTE_EMOTION_FROWN = 0,     // çš±çœ‰
//        BDFACE_ATTRIBUTE_EMOTION_SMILE = 1,     // ç¬‘
//        BDFACE_ATTRIBUTE_EMOTION_CALM = 2,      // å¹³é™
//    };
    /**
     * @brief   äººè„¸ç§æ—å±žæ€§æžšä¸¾
     */
    enum BDFaceRace
    {
        BDFACE_RACE_YELLOW = 0, // é»„种人
        BDFACE_RACE_WHITE = 1,  // ç™½ç§äºº
        BDFACE_RACE_BLACK = 2,  // é»‘种人
        BDFACE_RACE_INDIAN = 3, // å°ç¬¬å®‰äºº
    };
//    /**
//     * @brief   äººè„¸ç§æ—å±žæ€§æžšä¸¾
//     */
//    enum BDFaceRace
//    {
//        BDFACE_RACE_YELLOW = 0, // é»„种人
//        BDFACE_RACE_WHITE = 1,  // ç™½ç§äºº
//        BDFACE_RACE_BLACK = 2,  // é»‘种人
//        BDFACE_RACE_INDIAN = 3, // å°ç¬¬å®‰äºº
//    };
    /**
     * @brief   çœ¼é•œçŠ¶æ€å±žæ€§æžšä¸¾
     */
    enum BDFaceGlasses
    {
        BDFACE_NO_GLASSES = 0,   // æ— çœ¼é•œ
        BDFACE_GLASSES = 1,      // æœ‰çœ¼é•œ
        BDFACE_SUN_GLASSES = 2,  // å¢¨é•œ
    };
//    /**
//     * @brief   çœ¼é•œçŠ¶æ€å±žæ€§æžšä¸¾
//     */
//    enum BDFaceGlasses
//    {
//        BDFACE_NO_GLASSES = 0,   // æ— çœ¼é•œ
//        BDFACE_GLASSES = 1,      // æœ‰çœ¼é•œ
//        BDFACE_SUN_GLASSES = 2,  // å¢¨é•œ
//    };
    /**
     * @brief   æ€§åˆ«å±žæ€§æžšä¸¾
     */
    enum BDFaceGender
    {
        BDFACE_GENDER_FEMAILE = 0, // å¥³æ€§
        BDFACE_GENDER_MALE = 1,    // ç”·æ€§
    };
//    /**
//     * @brief   æ€§åˆ«å±žæ€§æžšä¸¾
//     */
//    enum BDFaceGender
//    {
//        BDFACE_GENDER_FEMAILE = 0, // å¥³æ€§
//        BDFACE_GENDER_MALE = 1,    // ç”·æ€§
//    };
    /**
     * @brief   äººè„¸å±žæ€§ç»“构体
     */
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    struct BDFaceAttribute
    {
        public int age;                            // å¹´é¾„
        public BDFaceRace race;                    // ç§æ—
        public BDFaceAttributeEmotionType emotion; // è¡¨æƒ…
        public BDFaceGlasses glasses;              // æˆ´çœ¼é•œçŠ¶æ€
        public BDFaceGender gender;                // æ€§åˆ«
    };
//    /**
//     * @brief   äººè„¸å±žæ€§ç»“构体
//     */
//    [StructLayout(LayoutKind.Sequential, Pack = 1)]
//    struct BDFaceAttribute
//    {
//        public int age;                            // å¹´é¾„
//        public BDFaceRace race;                    // ç§æ—
//        public BDFaceAttributeEmotionType emotion; // è¡¨æƒ…
//        public BDFaceGlasses glasses;              // æˆ´çœ¼é•œçŠ¶æ€
//        public BDFaceGender gender;                // æ€§åˆ«
//    };
    // äººè„¸å±žæ€§ç¤ºä¾‹åŠæŽ¥å£
    class FaceAttr
    {
        // èŽ·å–äººè„¸å±žæ€§
        [DllImport("BaiduFaceApi.dll", EntryPoint = "face_attr", CharSet = CharSet.Ansi
            , CallingConvention = CallingConvention.Cdecl)]
        public static extern int face_attr(IntPtr ptr, IntPtr mat);
//    // äººè„¸å±žæ€§ç¤ºä¾‹åŠæŽ¥å£
//    class FaceAttr
//    {
//        // èŽ·å–äººè„¸å±žæ€§
//        [DllImport("BaiduFaceApi.dll", EntryPoint = "face_attr", CharSet = CharSet.Ansi
//            , CallingConvention = CallingConvention.Cdecl)]
//        public static extern int face_attr(IntPtr ptr, IntPtr mat);
        // æµ‹è¯•获取人脸属性
        public void test_get_face_attr()
        {
            int max_face_num = 5; // è®¾ç½®æœ€å¤šæ£€æµ‹è·Ÿè¸ªäººæ•°ï¼ˆå¤šäººè„¸æ£€æµ‹ï¼‰ï¼Œé»˜è®¤ä¸º1,最多可设为50
//        // æµ‹è¯•获取人脸属性
//        public void test_get_face_attr()
//        {
//            int max_face_num = 5; // è®¾ç½®æœ€å¤šæ£€æµ‹è·Ÿè¸ªäººæ•°ï¼ˆå¤šäººè„¸æ£€æµ‹ï¼‰ï¼Œé»˜è®¤ä¸º1,最多可设为50
            BDFaceAttribute[] attr_info = new BDFaceAttribute[max_face_num];
            int size = Marshal.SizeOf(typeof(BDFaceAttribute));
            IntPtr ptT = Marshal.AllocHGlobal(size * max_face_num);
            string img_path = "../images/rgb.png";
            Mat mat = Cv2.ImRead(img_path);
            int faceNum = face_attr(ptT, mat.CvPtr);
            Console.WriteLine("faceNum is:" + faceNum);
            for (int index = 0; index < faceNum; index++)
            {
                IntPtr ptr = new IntPtr();
                if (8 == IntPtr.Size)
                {
                    ptr = (IntPtr)(ptT.ToInt64() + size * index);
                }
                else if (4 == IntPtr.Size)
                {
                    ptr = (IntPtr)(ptT.ToInt32() + size * index);
                }
//            BDFaceAttribute[] attr_info = new BDFaceAttribute[max_face_num];
//            int size = Marshal.SizeOf(typeof(BDFaceAttribute));
//            IntPtr ptT = Marshal.AllocHGlobal(size * max_face_num);
//            string img_path = "../images/rgb.png";
//            Mat mat = Cv2.ImRead(img_path);
//            int faceNum = face_attr(ptT, mat.CvPtr);
//            Console.WriteLine("faceNum is:" + faceNum);
//            for (int index = 0; index < faceNum; index++)
//            {
//                IntPtr ptr = new IntPtr();
//                if (8 == IntPtr.Size)
//                {
//                    ptr = (IntPtr)(ptT.ToInt64() + size * index);
//                }
//                else if (4 == IntPtr.Size)
//                {
//                    ptr = (IntPtr)(ptT.ToInt32() + size * index);
//                }
                attr_info[index] = (BDFaceAttribute)Marshal.PtrToStructure(ptr, typeof(BDFaceAttribute));
                // å¹´é¾„
                Console.WriteLine("age is {0}:", attr_info[index].age);
                // ç§æ—
                Console.WriteLine("race is:{0}", attr_info[index].race);
                // è¡¨æƒ…
                Console.WriteLine("emotion is:{0}", attr_info[index].emotion);
                // æˆ´çœ¼é•œçŠ¶æ€
                Console.WriteLine("glasses is:{0}", attr_info[index].glasses);
                // æ€§åˆ«
                Console.WriteLine("gender is:{0}", attr_info[index].gender);
            }
            Marshal.FreeHGlobal(ptT);
        }
//                attr_info[index] = (BDFaceAttribute)Marshal.PtrToStructure(ptr, typeof(BDFaceAttribute));
//                // å¹´é¾„
//                Console.WriteLine("age is {0}:", attr_info[index].age);
//                // ç§æ—
//                Console.WriteLine("race is:{0}", attr_info[index].race);
//                // è¡¨æƒ…
//                Console.WriteLine("emotion is:{0}", attr_info[index].emotion);
//                // æˆ´çœ¼é•œçŠ¶æ€
//                Console.WriteLine("glasses is:{0}", attr_info[index].glasses);
//                // æ€§åˆ«
//                Console.WriteLine("gender is:{0}", attr_info[index].gender);
//            }
//            Marshal.FreeHGlobal(ptT);
//        }
       
    }
}
//    }
//}
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/FaceAI/FaceCompare.cs
@@ -1,781 +1,781 @@
using System;
using System.Runtime.InteropServices;
using System.IO;
using OpenCvSharp;
//using System;
//using System.Runtime.InteropServices;
//using System.IO;
//using OpenCvSharp;
// äººè„¸æ¯”对(备注:人脸比对,实际上是人脸的特征值比对,提取出人脸特征值,用compare_feature方法比对)
namespace FaceAI
{
    // äººè„¸æ¯”较1:1、1:N、抽取人脸特征值、按特征值比较等
    public class FaceCompare
    {
        //  æå–人脸特征值(传图片文件路径)
        /// <summary>
        /// æå–人脸特征值,为512个浮点值,已加密
        /// </summary>
        /// <param name="file_name">图片信息,数据大小小于10M,传入图片文件路径</param>
        /// <param name="length">通过引用返回特征值的长度,若为2048表示提取正确,其他值表示提取了错误的特征值</param>
        /// <returns></returns>
        [DllImport("BaiduFaceApi.dll", EntryPoint = "get_face_feature", CharSet = CharSet.Ansi
            , CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr get_face_feature(string file_name, ref int length);
        // æå–人脸特征值(传二进制图片buffer)
        /// <summary>
        /// æå–人脸特征值,为2048个byte (传入二进制图片buffer)
        /// </summary>
        /// <param name="buf"></param>
        /// <param name="size"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        [DllImport("BaiduFaceApi.dll", EntryPoint = "get_face_feature_by_buf", CharSet = CharSet.Ansi
            , CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr get_face_feature_by_buf(byte[] buf, int size, ref int length);
        //// èŽ·å–äººè„¸ç‰¹å¾å€¼ï¼ˆä¼ å…¥opencv视频帧及人脸信息,适应于多人脸)
        ///// <summary>
        ///// èŽ·å–äººè„¸ç‰¹å¾å€¼ï¼ˆä¼ å…¥opencv视频帧及人脸信息,适应于多人脸)
        ///// </summary>
        ///// <param name="mat"></param>
        ///// <param name="info"></param>
        ///// <param name="feaptr"></param>
        ///// <returns></returns>
        //[DllImport("BaiduFaceApi.dll", EntryPoint = "get_face_feature_by_face", CharSet = CharSet.Ansi
        //    , CallingConvention = CallingConvention.Cdecl)]
        //public static extern int get_face_feature_by_face(IntPtr mat, ref TrackFaceInfo info, ref IntPtr feaptr);
        // äººè„¸1:1比对(传图片文件路径)
        /// <summary>
        /// äººè„¸å¯¹æ¯”接口(传入图片文件路径)
        /// </summary>
        /// <param name="file_name1">需要对比的第一张图片,小于10M,传入图片文件路径</param>
        /// <param name="file_name2">需要对比的第二张图片,小于10M,传入图片文件路径</param>
        /// <returns></returns>
        [DllImport("BaiduFaceApi.dll", EntryPoint = "match", CharSet = CharSet.Ansi
            , CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr match(string file_name1, string file_name2);
        // äººè„¸1:1比对(传二进制图片buffer)
        /// <summary>
        /// äººè„¸å¯¹æ¯”接口(传入二进制图片buffer)
        /// </summary>
        /// <param name="buf1">需要对比的第一张图片,小于10M</param>
        /// <param name="size1">图片1的大小</param>
        /// <param name="buf2">需要对比的第二张图片,小于10M</param>
        /// <param name="size2">图片2的大小</param>
        /// <returns></returns>
        [DllImport("BaiduFaceApi.dll", EntryPoint = "match_by_buf", CharSet = CharSet.Ansi
            , CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr match_by_buf(byte[] buf1, int size1, byte[] buf2, int size2);
        // äººè„¸1:1比对(传opencv视频帧)
        /// <summary>
        /// äººè„¸1:1比对(传opencv视频帧)
        /// </summary>
        /// <param name="img1"></param>
        /// <param name="img2"></param>
        /// <returns></returns>
        [DllImport("BaiduFaceApi.dll", EntryPoint = "match_by_mat", CharSet = CharSet.Ansi
            , CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr match_by_mat(IntPtr img1, IntPtr img2);// byte[] buf1, int size1, byte[] buf2, int size2);
        // äººè„¸1:1比对(传人脸特征值和二进制图片buffer)
        /// <summary>
        /// äººè„¸å¯¹æ¯”接口(传入二进制图片buffer)
        /// </summary>
        /// <param name="feature">文件特征</param>
        /// <param name="fea_len"></param>
        /// <param name="buf2"></param>
        /// <param name="size2"></param>
        /// <returns></returns>
        [DllImport("BaiduFaceApi.dll", EntryPoint = "match_by_feature", CharSet = CharSet.Ansi
            , CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr match_by_feature(byte[] feature, int fea_len, byte[] buf2, int size2);
        // ç‰¹å¾å€¼æ¯”对(传2个人脸的特征值)
        /// <summary>
        /// ç‰¹å¾å€¼æ¯”对
        /// </summary>
        /// <param name="f1"></param>
        /// <param name="f1_len"></param>
        /// <param name="f2"></param>
        /// <param name="f2_len"></param>
        /// <returns></returns>
        [DllImport("BaiduFaceApi.dll", EntryPoint = "compare_feature", CharSet = CharSet.Ansi
            , CallingConvention = CallingConvention.Cdecl)]
        public static extern float compare_feature(byte[] f1, int f1_len, byte[] f2, int f2_len);
        // 1:N人脸识别(传图片文件路径和库里的比对)
        /// <summary>
        /// äººè„¸è¯†åˆ«ï¼Œæä¾›1:N查找 (传入图片文件路径)
        /// </summary>
        /// <param name="image">图片信息,数据大小小于10M,传入图片文件路径</param>
        /// <param name="group_id_list">组id列表。默认至少填写一个group_id,从指定的group中进行查找。需要同时查询多个group,用逗号分隔,上限10个</param>
        /// <param name="user_id">用户id,若指定了某个user,则只会与指定group下的这个user进行对比;若user_id传空字符串” â€ï¼Œåˆ™ä¼šä¸Žæ­¤group下的所有user进行1:N识别</param>
        /// <param name="user_top_num">识别后返回的用户top数,默认为1,最多返回50个结果</param>
        /// <returns></returns>
        [DllImport("BaiduFaceApi.dll", EntryPoint = "identify", CharSet = CharSet.Ansi
           , CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr identify(string image, string group_id_list, string user_id, int user_top_num = 1);
        // 1:N人脸识别(传图片二进制文件buffer和库里的比对)
        /// <summary>
        /// äººè„¸è¯†åˆ«ï¼Œæä¾›1:N查找 (传入二进制图片buffer)
        /// </summary>
        /// <param name="buf">二进制图片信息,数据大小小于10M</param>
        /// <param name="size">图片大小</param>
        /// <param name="group_id_list">组id列表。默认至少填写一个group_id,从指定的group中进行查找。需要同时查询多个group,用逗号分隔,上限10个</param>
        /// <param name="user_id">用户id,若指定了某个user,则只会与指定group下的这个user进行对比;若user_id传空字符串” â€ï¼Œåˆ™ä¼šä¸Žæ­¤group下的所有user进行1:N识别</param>
        /// <param name="user_top_num">识别后返回的用户top数,默认为1,最多返回50个结果</param>
        /// <returns></returns>
        [DllImport("BaiduFaceApi.dll", EntryPoint = "identify_by_buf", CharSet = CharSet.Ansi
           , CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr identify_by_buf(byte[] buf, int size, string group_id_list,
            string user_id, int user_top_num = 1);
        // 1:N人脸识别(传人脸特征值和库里的比对)
        /// <summary>
        /// 1:N人脸识别(传人脸特征值和库里的比对)
        /// </summary>
        /// <param name="feature"></param>
        /// <param name="fea_len"></param>
        /// <param name="group_id_list">组id列表。默认至少填写一个group_id,从指定的group中进行查找。需要同时查询多个group,用逗号分隔,上限10个</param>
        /// <param name="user_id">用户id,若指定了某个user,则只会与指定group下的这个user进行对比;若user_id传空字符串” â€ï¼Œåˆ™ä¼šä¸Žæ­¤group下的所有user进行1:N识别</param>
        /// <param name="user_top_num">识别后返回的用户top数,默认为1,最多返回50个结果</param>
        /// <returns></returns>
        [DllImport("BaiduFaceApi.dll", EntryPoint = "identify_by_feature", CharSet = CharSet.Ansi
          , CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr identify_by_feature(byte[] feature, int fea_len, string group_id_list,
            string user_id, int user_top_num = 1);
//// äººè„¸æ¯”对(备注:人脸比对,实际上是人脸的特征值比对,提取出人脸特征值,用compare_feature方法比对)
//namespace FaceAI
//{
//    // äººè„¸æ¯”较1:1、1:N、抽取人脸特征值、按特征值比较等
//    public class FaceCompare
//    {
//        //  æå–人脸特征值(传图片文件路径)
//        /// <summary>
//        /// æå–人脸特征值,为512个浮点值,已加密
//        /// </summary>
//        /// <param name="file_name">图片信息,数据大小小于10M,传入图片文件路径</param>
//        /// <param name="length">通过引用返回特征值的长度,若为2048表示提取正确,其他值表示提取了错误的特征值</param>
//        /// <returns></returns>
//        [DllImport("BaiduFaceApi.dll", EntryPoint = "get_face_feature", CharSet = CharSet.Ansi
//            , CallingConvention = CallingConvention.Cdecl)]
//        public static extern IntPtr get_face_feature(string file_name, ref int length);
//        // æå–人脸特征值(传二进制图片buffer)
//        /// <summary>
//        /// æå–人脸特征值,为2048个byte (传入二进制图片buffer)
//        /// </summary>
//        /// <param name="buf"></param>
//        /// <param name="size"></param>
//        /// <param name="length"></param>
//        /// <returns></returns>
//        [DllImport("BaiduFaceApi.dll", EntryPoint = "get_face_feature_by_buf", CharSet = CharSet.Ansi
//            , CallingConvention = CallingConvention.Cdecl)]
//        public static extern IntPtr get_face_feature_by_buf(byte[] buf, int size, ref int length);
//        //// èŽ·å–äººè„¸ç‰¹å¾å€¼ï¼ˆä¼ å…¥opencv视频帧及人脸信息,适应于多人脸)
//        ///// <summary>
//        ///// èŽ·å–äººè„¸ç‰¹å¾å€¼ï¼ˆä¼ å…¥opencv视频帧及人脸信息,适应于多人脸)
//        ///// </summary>
//        ///// <param name="mat"></param>
//        ///// <param name="info"></param>
//        ///// <param name="feaptr"></param>
//        ///// <returns></returns>
//        //[DllImport("BaiduFaceApi.dll", EntryPoint = "get_face_feature_by_face", CharSet = CharSet.Ansi
//        //    , CallingConvention = CallingConvention.Cdecl)]
//        //public static extern int get_face_feature_by_face(IntPtr mat, ref TrackFaceInfo info, ref IntPtr feaptr);
//        // äººè„¸1:1比对(传图片文件路径)
//        /// <summary>
//        /// äººè„¸å¯¹æ¯”接口(传入图片文件路径)
//        /// </summary>
//        /// <param name="file_name1">需要对比的第一张图片,小于10M,传入图片文件路径</param>
//        /// <param name="file_name2">需要对比的第二张图片,小于10M,传入图片文件路径</param>
//        /// <returns></returns>
//        [DllImport("BaiduFaceApi.dll", EntryPoint = "match", CharSet = CharSet.Ansi
//            , CallingConvention = CallingConvention.Cdecl)]
//        public static extern IntPtr match(string file_name1, string file_name2);
//        // äººè„¸1:1比对(传二进制图片buffer)
//        /// <summary>
//        /// äººè„¸å¯¹æ¯”接口(传入二进制图片buffer)
//        /// </summary>
//        /// <param name="buf1">需要对比的第一张图片,小于10M</param>
//        /// <param name="size1">图片1的大小</param>
//        /// <param name="buf2">需要对比的第二张图片,小于10M</param>
//        /// <param name="size2">图片2的大小</param>
//        /// <returns></returns>
//        [DllImport("BaiduFaceApi.dll", EntryPoint = "match_by_buf", CharSet = CharSet.Ansi
//            , CallingConvention = CallingConvention.Cdecl)]
//        public static extern IntPtr match_by_buf(byte[] buf1, int size1, byte[] buf2, int size2);
//        // äººè„¸1:1比对(传opencv视频帧)
//        /// <summary>
//        /// äººè„¸1:1比对(传opencv视频帧)
//        /// </summary>
//        /// <param name="img1"></param>
//        /// <param name="img2"></param>
//        /// <returns></returns>
//        [DllImport("BaiduFaceApi.dll", EntryPoint = "match_by_mat", CharSet = CharSet.Ansi
//            , CallingConvention = CallingConvention.Cdecl)]
//        public static extern IntPtr match_by_mat(IntPtr img1, IntPtr img2);// byte[] buf1, int size1, byte[] buf2, int size2);
//        // äººè„¸1:1比对(传人脸特征值和二进制图片buffer)
//        /// <summary>
//        /// äººè„¸å¯¹æ¯”接口(传入二进制图片buffer)
//        /// </summary>
//        /// <param name="feature">文件特征</param>
//        /// <param name="fea_len"></param>
//        /// <param name="buf2"></param>
//        /// <param name="size2"></param>
//        /// <returns></returns>
//        [DllImport("BaiduFaceApi.dll", EntryPoint = "match_by_feature", CharSet = CharSet.Ansi
//            , CallingConvention = CallingConvention.Cdecl)]
//        public static extern IntPtr match_by_feature(byte[] feature, int fea_len, byte[] buf2, int size2);
//        // ç‰¹å¾å€¼æ¯”对(传2个人脸的特征值)
//        /// <summary>
//        /// ç‰¹å¾å€¼æ¯”对
//        /// </summary>
//        /// <param name="f1"></param>
//        /// <param name="f1_len"></param>
//        /// <param name="f2"></param>
//        /// <param name="f2_len"></param>
//        /// <returns></returns>
//        [DllImport("BaiduFaceApi.dll", EntryPoint = "compare_feature", CharSet = CharSet.Ansi
//            , CallingConvention = CallingConvention.Cdecl)]
//        public static extern float compare_feature(byte[] f1, int f1_len, byte[] f2, int f2_len);
//        // 1:N人脸识别(传图片文件路径和库里的比对)
//        /// <summary>
//        /// äººè„¸è¯†åˆ«ï¼Œæä¾›1:N查找 (传入图片文件路径)
//        /// </summary>
//        /// <param name="image">图片信息,数据大小小于10M,传入图片文件路径</param>
//        /// <param name="group_id_list">组id列表。默认至少填写一个group_id,从指定的group中进行查找。需要同时查询多个group,用逗号分隔,上限10个</param>
//        /// <param name="user_id">用户id,若指定了某个user,则只会与指定group下的这个user进行对比;若user_id传空字符串” â€ï¼Œåˆ™ä¼šä¸Žæ­¤group下的所有user进行1:N识别</param>
//        /// <param name="user_top_num">识别后返回的用户top数,默认为1,最多返回50个结果</param>
//        /// <returns></returns>
//        [DllImport("BaiduFaceApi.dll", EntryPoint = "identify", CharSet = CharSet.Ansi
//           , CallingConvention = CallingConvention.Cdecl)]
//        public static extern IntPtr identify(string image, string group_id_list, string user_id, int user_top_num = 1);
//        // 1:N人脸识别(传图片二进制文件buffer和库里的比对)
//        /// <summary>
//        /// äººè„¸è¯†åˆ«ï¼Œæä¾›1:N查找 (传入二进制图片buffer)
//        /// </summary>
//        /// <param name="buf">二进制图片信息,数据大小小于10M</param>
//        /// <param name="size">图片大小</param>
//        /// <param name="group_id_list">组id列表。默认至少填写一个group_id,从指定的group中进行查找。需要同时查询多个group,用逗号分隔,上限10个</param>
//        /// <param name="user_id">用户id,若指定了某个user,则只会与指定group下的这个user进行对比;若user_id传空字符串” â€ï¼Œåˆ™ä¼šä¸Žæ­¤group下的所有user进行1:N识别</param>
//        /// <param name="user_top_num">识别后返回的用户top数,默认为1,最多返回50个结果</param>
//        /// <returns></returns>
//        [DllImport("BaiduFaceApi.dll", EntryPoint = "identify_by_buf", CharSet = CharSet.Ansi
//           , CallingConvention = CallingConvention.Cdecl)]
//        public static extern IntPtr identify_by_buf(byte[] buf, int size, string group_id_list,
//            string user_id, int user_top_num = 1);
//        // 1:N人脸识别(传人脸特征值和库里的比对)
//        /// <summary>
//        /// 1:N人脸识别(传人脸特征值和库里的比对)
//        /// </summary>
//        /// <param name="feature"></param>
//        /// <param name="fea_len"></param>
//        /// <param name="group_id_list">组id列表。默认至少填写一个group_id,从指定的group中进行查找。需要同时查询多个group,用逗号分隔,上限10个</param>
//        /// <param name="user_id">用户id,若指定了某个user,则只会与指定group下的这个user进行对比;若user_id传空字符串” â€ï¼Œåˆ™ä¼šä¸Žæ­¤group下的所有user进行1:N识别</param>
//        /// <param name="user_top_num">识别后返回的用户top数,默认为1,最多返回50个结果</param>
//        /// <returns></returns>
//        [DllImport("BaiduFaceApi.dll", EntryPoint = "identify_by_feature", CharSet = CharSet.Ansi
//          , CallingConvention = CallingConvention.Cdecl)]
//        public static extern IntPtr identify_by_feature(byte[] feature, int fea_len, string group_id_list,
//            string user_id, int user_top_num = 1);
        // æå‰åŠ è½½åº“é‡Œæ‰€æœ‰æ•°æ®åˆ°å†…å­˜ä¸­
        /// <summary>
        /// æå‰åŠ è½½åº“é‡Œæ‰€æœ‰æ•°æ®åˆ°å†…å­˜ä¸­
        /// </summary>
        /// <returns></returns>
        [DllImport("BaiduFaceApi.dll", EntryPoint = "load_db_face", CharSet = CharSet.Ansi
          , CallingConvention = CallingConvention.Cdecl)]
        public static extern bool load_db_face();
//        // æå‰åŠ è½½åº“é‡Œæ‰€æœ‰æ•°æ®åˆ°å†…å­˜ä¸­
//        /// <summary>
//        /// æå‰åŠ è½½åº“é‡Œæ‰€æœ‰æ•°æ®åˆ°å†…å­˜ä¸­
//        /// </summary>
//        /// <returns></returns>
//        [DllImport("BaiduFaceApi.dll", EntryPoint = "load_db_face", CharSet = CharSet.Ansi
//          , CallingConvention = CallingConvention.Cdecl)]
//        public static extern bool load_db_face();
        // 1:N人脸识别(传人脸图片文件和内存已加载的整个库数据比对)
        /// <summary>
        /// 1:N人脸识别(传人脸图片文件和内存已加载的整个库数据比对)
        /// </summary>
        /// <param name="image"></param>
        /// <param name="user_top_num"></param>
        /// <returns></returns>
        [DllImport("BaiduFaceApi.dll", EntryPoint = "identify_with_all", CharSet = CharSet.Ansi
          , CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr identify_with_all(string image, int user_top_num = 1);
//        // 1:N人脸识别(传人脸图片文件和内存已加载的整个库数据比对)
//        /// <summary>
//        /// 1:N人脸识别(传人脸图片文件和内存已加载的整个库数据比对)
//        /// </summary>
//        /// <param name="image"></param>
//        /// <param name="user_top_num"></param>
//        /// <returns></returns>
//        [DllImport("BaiduFaceApi.dll", EntryPoint = "identify_with_all", CharSet = CharSet.Ansi
//          , CallingConvention = CallingConvention.Cdecl)]
//        public static extern IntPtr identify_with_all(string image, int user_top_num = 1);
        // 1:N人脸识别(传人脸图片文件和内存已加载的整个库数据比对)
        /// <summary>
        ///
        /// </summary>
        /// <param name="image">图片的二进制文件</param>
        /// <param name="size"></param>
        /// <param name="user_top_num"></param>
        /// <returns></returns>
        [DllImport("BaiduFaceApi.dll", EntryPoint = "identify_by_buf_with_all", CharSet = CharSet.Ansi
          , CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr identify_by_buf_with_all(byte[] image, int size, int user_top_num = 1);
//        // 1:N人脸识别(传人脸图片文件和内存已加载的整个库数据比对)
//        /// <summary>
//        ///
//        /// </summary>
//        /// <param name="image">图片的二进制文件</param>
//        /// <param name="size"></param>
//        /// <param name="user_top_num"></param>
//        /// <returns></returns>
//        [DllImport("BaiduFaceApi.dll", EntryPoint = "identify_by_buf_with_all", CharSet = CharSet.Ansi
//          , CallingConvention = CallingConvention.Cdecl)]
//        public static extern IntPtr identify_by_buf_with_all(byte[] image, int size, int user_top_num = 1);
        // 1:N人脸识别(传人脸特征值和内存已加载的整个库数据比对)
        /// <summary>
        /// 1:N人脸识别(传人脸特征值和内存已加载的整个库数据比对)
        /// </summary>
        /// <param name="feature"></param>
        /// <param name="fea_len"></param>
        /// <param name="user_top_num"></param>
        /// <returns></returns>
        [DllImport("BaiduFaceApi.dll", EntryPoint = "identify_by_feature_with_all", CharSet = CharSet.Ansi
          , CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr identify_by_feature_with_all(byte[] feature, int fea_len, int user_top_num = 1);
//        // 1:N人脸识别(传人脸特征值和内存已加载的整个库数据比对)
//        /// <summary>
//        /// 1:N人脸识别(传人脸特征值和内存已加载的整个库数据比对)
//        /// </summary>
//        /// <param name="feature"></param>
//        /// <param name="fea_len"></param>
//        /// <param name="user_top_num"></param>
//        /// <returns></returns>
//        [DllImport("BaiduFaceApi.dll", EntryPoint = "identify_by_feature_with_all", CharSet = CharSet.Ansi
//          , CallingConvention = CallingConvention.Cdecl)]
//        public static extern IntPtr identify_by_feature_with_all(byte[] feature, int fea_len, int user_top_num = 1);
        // æµ‹è¯•获取人脸特征值(2048个byte)
        public void test_get_face_feature()
        {
            byte[] fea = new byte[2048];
            string file_name = "G:\\Development\\Application\\testface\\img\\beckham\\2.jpg";
            int len = 0;
            IntPtr ptr = get_face_feature(file_name, ref len);
            if (ptr == IntPtr.Zero)
            {
                Console.WriteLine("get face feature error");
            }
            else
            {
                if (len == 2048)
                {
                    Console.WriteLine("get face feature success");
                    Marshal.Copy(ptr, fea, 0, 2048);
                    // å¯ä¿å­˜ç‰¹å¾å€¼2048个字节的fea到文件中
                    // FileUtil.byte2file("G:\\Development\\Application\\testface\\img\\beckham\\fea1.txt",fea, 2048);
                }
                else
                {
                    Console.WriteLine("get face feature error");
                }
            }
        }
        /// <summary>
        /// èŽ·å–äººè„¸ç‰¹å¾å€¼(2048个byte)
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public string GetFaceFeature(string fileName)
        {
            try
            {
                byte[] fea = new byte[2048];
                string file_name = fileName == null ? fileName : "G:\\Development\\Application\\testface\\img\\beckham\\2.jpg";
                int len = 0;
                IntPtr ptr = get_face_feature(file_name, ref len);
                if (ptr == IntPtr.Zero)
                {
                    Console.WriteLine("get face feature error");
                    return "error";
                }
                else
                {
                    if (len == 2048)
                    {
                        Console.WriteLine("get face feature success");
                        Marshal.Copy(ptr, fea, 0, 2048);
                        return fea.ToString();
                        // å¯ä¿å­˜ç‰¹å¾å€¼2048个字节的fea到文件中
                        // FileUtil.byte2file("G:\\Development\\Application\\testface\\img\\beckham\\fea1.txt",fea, 2048);
                    }
                    else
                    {
                        Console.WriteLine("get face feature error");
                        return "error";
                    }
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }
        /// <summary>
        /// èŽ·å–äººè„¸ç‰¹å¾å€¼ 2048Byte
        /// </summary>
        /// <param name="file_name">图片信息,数据大小小于10M,传入图片文件路径</param>
        /// <param name="length">通过引用返回特征值的长度,若为2048表示提取正确,其他值表示提取了错误的特征值</param>
        /// <returns></returns>
        public string GetFaceFeature(string file_name, ref int length)
        {
            byte[] fea = new byte[2048];
            int len = length == 0 ? 0 : length; //defalut=0
            string result = "";
            IntPtr ptr = get_face_feature(file_name, ref len);
            if (ptr == IntPtr.Zero)
            {
                result = ("get face feature error");
            }
            else
            {
                if (len == 2048)
                {
                    result = ("get face feature success");
                    Marshal.Copy(ptr, fea, 0, 2048);
                    // å¯ä¿å­˜ç‰¹å¾å€¼2048个字节的fea到文件中
                    // FileUtil.byte2file("G:\\Development\\Application\\testface\\img\\beckham\\fea1.txt",fea, 2048);
                }
                else
                {
                    result = ("get face feature error");
                }
            }
            return result;
        }
//        // æµ‹è¯•获取人脸特征值(2048个byte)
//        public void test_get_face_feature()
//        {
//            byte[] fea = new byte[2048];
//            string file_name = "G:\\Development\\Application\\testface\\img\\beckham\\2.jpg";
//            int len = 0;
//            IntPtr ptr = get_face_feature(file_name, ref len);
//            if (ptr == IntPtr.Zero)
//            {
//                Console.WriteLine("get face feature error");
//            }
//            else
//            {
//                if (len == 2048)
//                {
//                    Console.WriteLine("get face feature success");
//                    Marshal.Copy(ptr, fea, 0, 2048);
//                    // å¯ä¿å­˜ç‰¹å¾å€¼2048个字节的fea到文件中
//                    // FileUtil.byte2file("G:\\Development\\Application\\testface\\img\\beckham\\fea1.txt",fea, 2048);
//                }
//                else
//                {
//                    Console.WriteLine("get face feature error");
//                }
//            }
//        }
//        /// <summary>
//        /// èŽ·å–äººè„¸ç‰¹å¾å€¼(2048个byte)
//        /// </summary>
//        /// <param name="fileName"></param>
//        /// <returns></returns>
//        public string GetFaceFeature(string fileName)
//        {
//            try
//            {
//                byte[] fea = new byte[2048];
//                string file_name = fileName == null ? fileName : "G:\\Development\\Application\\testface\\img\\beckham\\2.jpg";
//                int len = 0;
//                IntPtr ptr = get_face_feature(file_name, ref len);
//                if (ptr == IntPtr.Zero)
//                {
//                    Console.WriteLine("get face feature error");
//                    return "error";
//                }
//                else
//                {
//                    if (len == 2048)
//                    {
//                        Console.WriteLine("get face feature success");
//                        Marshal.Copy(ptr, fea, 0, 2048);
//                        return fea.ToString();
//                        // å¯ä¿å­˜ç‰¹å¾å€¼2048个字节的fea到文件中
//                        // FileUtil.byte2file("G:\\Development\\Application\\testface\\img\\beckham\\fea1.txt",fea, 2048);
//                    }
//                    else
//                    {
//                        Console.WriteLine("get face feature error");
//                        return "error";
//                    }
//                }
//            }
//            catch (Exception e)
//            {
//                throw e;
//            }
//        }
//        /// <summary>
//        /// èŽ·å–äººè„¸ç‰¹å¾å€¼ 2048Byte
//        /// </summary>
//        /// <param name="file_name">图片信息,数据大小小于10M,传入图片文件路径</param>
//        /// <param name="length">通过引用返回特征值的长度,若为2048表示提取正确,其他值表示提取了错误的特征值</param>
//        /// <returns></returns>
//        public string GetFaceFeature(string file_name, ref int length)
//        {
//            byte[] fea = new byte[2048];
//            int len = length == 0 ? 0 : length; //defalut=0
//            string result = "";
//            IntPtr ptr = get_face_feature(file_name, ref len);
//            if (ptr == IntPtr.Zero)
//            {
//                result = ("get face feature error");
//            }
//            else
//            {
//                if (len == 2048)
//                {
//                    result = ("get face feature success");
//                    Marshal.Copy(ptr, fea, 0, 2048);
//                    // å¯ä¿å­˜ç‰¹å¾å€¼2048个字节的fea到文件中
//                    // FileUtil.byte2file("G:\\Development\\Application\\testface\\img\\beckham\\fea1.txt",fea, 2048);
//                }
//                else
//                {
//                    result = ("get face feature error");
//                }
//            }
//            return result;
//        }
        //// æµ‹è¯•获取人脸特征值(2048个byte)
        //public void test_get_face_feature_by_buf()
        //{
        //    byte[] fea = new byte[2048];
        //    System.Drawing.Image img = System.Drawing.Image.FromFile("G:\\Development\\Application\\testface\\img\\beckham\\2.jpg");
        //    byte[] img_bytes = ImageUtil.img2byte(img);
        //    int len = 0;
        //    IntPtr ptr = get_face_feature_by_buf(img_bytes, img_bytes.Length, ref len);
        //    if (ptr == IntPtr.Zero)
        //    {
        //        Console.WriteLine("get face feature error");
        //    }
        //    else
        //    {
        //        if (len == 2048)
        //        {
        //            Console.WriteLine("get face feature success");
        //            Marshal.Copy(ptr, fea, 0, 2048);
        //            // å¯ä¿å­˜ç‰¹å¾å€¼2048个字节的fea到文件中
        //            //  FileUtil.byte2file("G:\\Development\\Application\\testface\\img\\beckham\\fea2.txt",fea, 2048);
        //        }
        //        else
        //        {
        //            Console.WriteLine("get face feature error");
        //        }
        //    }
        //}
//        //// æµ‹è¯•获取人脸特征值(2048个byte)
//        //public void test_get_face_feature_by_buf()
//        //{
//        //    byte[] fea = new byte[2048];
//        //    System.Drawing.Image img = System.Drawing.Image.FromFile("G:\\Development\\Application\\testface\\img\\beckham\\2.jpg");
//        //    byte[] img_bytes = ImageUtil.img2byte(img);
//        //    int len = 0;
//        //    IntPtr ptr = get_face_feature_by_buf(img_bytes, img_bytes.Length, ref len);
//        //    if (ptr == IntPtr.Zero)
//        //    {
//        //        Console.WriteLine("get face feature error");
//        //    }
//        //    else
//        //    {
//        //        if (len == 2048)
//        //        {
//        //            Console.WriteLine("get face feature success");
//        //            Marshal.Copy(ptr, fea, 0, 2048);
//        //            // å¯ä¿å­˜ç‰¹å¾å€¼2048个字节的fea到文件中
//        //            //  FileUtil.byte2file("G:\\Development\\Application\\testface\\img\\beckham\\fea2.txt",fea, 2048);
//        //        }
//        //        else
//        //        {
//        //            Console.WriteLine("get face feature error");
//        //        }
//        //    }
//        //}
        ///// <summary>
        ///// èŽ·å–äººè„¸ç‰¹å¾å€¼ 2048byte
        ///// </summary>
        ///// <param name="filePath"></param>
        ///// <returns></returns>
        //public string GetFaceFeatureByBuffer(string filePath)
        //{
        //    byte[] fea = new byte[2048];
        //    string result = "";
        //    System.Drawing.Image img = System.Drawing.Image.FromFile(filePath);
        //    byte[] img_bytes = ImageUtil.img2byte(img);
        //    int len = 0;
        //    IntPtr ptr = get_face_feature_by_buf(img_bytes, img_bytes.Length, ref len);
        //    if (ptr == IntPtr.Zero)
        //    {
        //        result = ("get face feature error");
        //    }
        //    else
        //    {
        //        if (len == 2048)
        //        {
        //            result = ("get face feature success");
        //            Marshal.Copy(ptr, fea, 0, 2048);
        //            // å¯ä¿å­˜ç‰¹å¾å€¼2048个字节的fea到文件中
        //            //  FileUtil.byte2file("G:\\Development\\Application\\testface\\img\\beckham\\fea2.txt",fea, 2048);
        //        }
        //        else
        //        {
        //            result = ("get face feature error");
        //        }
        //    }
        //    return result;
        //}
//        ///// <summary>
//        ///// èŽ·å–äººè„¸ç‰¹å¾å€¼ 2048byte
//        ///// </summary>
//        ///// <param name="filePath"></param>
//        ///// <returns></returns>
//        //public string GetFaceFeatureByBuffer(string filePath)
//        //{
//        //    byte[] fea = new byte[2048];
//        //    string result = "";
//        //    System.Drawing.Image img = System.Drawing.Image.FromFile(filePath);
//        //    byte[] img_bytes = ImageUtil.img2byte(img);
//        //    int len = 0;
//        //    IntPtr ptr = get_face_feature_by_buf(img_bytes, img_bytes.Length, ref len);
//        //    if (ptr == IntPtr.Zero)
//        //    {
//        //        result = ("get face feature error");
//        //    }
//        //    else
//        //    {
//        //        if (len == 2048)
//        //        {
//        //            result = ("get face feature success");
//        //            Marshal.Copy(ptr, fea, 0, 2048);
//        //            // å¯ä¿å­˜ç‰¹å¾å€¼2048个字节的fea到文件中
//        //            //  FileUtil.byte2file("G:\\Development\\Application\\testface\\img\\beckham\\fea2.txt",fea, 2048);
//        //        }
//        //        else
//        //        {
//        //            result = ("get face feature error");
//        //        }
//        //    }
//        //    return result;
//        //}
        // æµ‹è¯•1:1比较,传入图片文件路径
        public void test_match()
        {
            string file1 = "G:\\Development\\Application\\testface\\img\\beckham\\1.jpg";
            string file2 = "G:\\Development\\Application\\testface\\img\\beckham\\9.jpg";
            IntPtr ptr = match(file1, file2);
            string buf = Marshal.PtrToStringAnsi(ptr);
            Console.WriteLine("match res is:" + buf);
        }
        /// <summary>
        /// 1:1比较 ä¼ å…¥å›¾ç‰‡æ–‡ä»¶è·¯å¾„
        /// </summary>
        /// <param name="file1"></param>
        /// <param name="file2"></param>
        /// <returns></returns>
        public string FaceMatch(string file1, string file2)
        {
            IntPtr ptr = match(file1, file2);
            string buf = Marshal.PtrToStringAnsi(ptr);
            Console.WriteLine("match res is:" + buf);
            return buf;
        }
        // æµ‹è¯•1:1比较,传入图片文件二进制buffer
        //public void test_match_by_buf()
        //{
        //    System.Drawing.Image img1 = System.Drawing.Image.FromFile("d:\\444.bmp");
        //    byte[] img_bytes1 = ImageUtil.img2byte(img1);
//        // æµ‹è¯•1:1比较,传入图片文件路径
//        public void test_match()
//        {
//            string file1 = "G:\\Development\\Application\\testface\\img\\beckham\\1.jpg";
//            string file2 = "G:\\Development\\Application\\testface\\img\\beckham\\9.jpg";
//            IntPtr ptr = match(file1, file2);
//            string buf = Marshal.PtrToStringAnsi(ptr);
//            Console.WriteLine("match res is:" + buf);
//        }
//        /// <summary>
//        /// 1:1比较 ä¼ å…¥å›¾ç‰‡æ–‡ä»¶è·¯å¾„
//        /// </summary>
//        /// <param name="file1"></param>
//        /// <param name="file2"></param>
//        /// <returns></returns>
//        public string FaceMatch(string file1, string file2)
//        {
//            IntPtr ptr = match(file1, file2);
//            string buf = Marshal.PtrToStringAnsi(ptr);
//            Console.WriteLine("match res is:" + buf);
//            return buf;
//        }
//        // æµ‹è¯•1:1比较,传入图片文件二进制buffer
//        //public void test_match_by_buf()
//        //{
//        //    System.Drawing.Image img1 = System.Drawing.Image.FromFile("d:\\444.bmp");
//        //    byte[] img_bytes1 = ImageUtil.img2byte(img1);
        //    System.Drawing.Image img2 = System.Drawing.Image.FromFile("d:\\555.png");
        //    byte[] img_bytes2 = ImageUtil.img2byte(img2);
        //    Console.WriteLine("IntPtr ptr = match_by_buf");
        //    IntPtr ptr = match_by_buf(img_bytes1, img_bytes1.Length, img_bytes2, img_bytes2.Length);
        //    string buf = Marshal.PtrToStringAnsi(ptr);
        //    Console.WriteLine("match_by_buf res is:" + buf);
        //}
        /// <summary>
        /// 1:1比较 ä¼ å›¾ç‰‡äºŒè¿›åˆ¶Buffer
        /// </summary>
        /// <param name="file1"></param>
        /// <param name="file2"></param>
        /// <returns></returns>
        public string FaceMatchByBuffer(byte[] file1, byte[] file2)
        {
            // System.Drawing.Image img1 = System.Drawing.Image.FromFile(file1);
            byte[] img_bytes1 = file1; // ImageUtil.img2byte(img1);
//        //    System.Drawing.Image img2 = System.Drawing.Image.FromFile("d:\\555.png");
//        //    byte[] img_bytes2 = ImageUtil.img2byte(img2);
//        //    Console.WriteLine("IntPtr ptr = match_by_buf");
//        //    IntPtr ptr = match_by_buf(img_bytes1, img_bytes1.Length, img_bytes2, img_bytes2.Length);
//        //    string buf = Marshal.PtrToStringAnsi(ptr);
//        //    Console.WriteLine("match_by_buf res is:" + buf);
//        //}
//        /// <summary>
//        /// 1:1比较 ä¼ å›¾ç‰‡äºŒè¿›åˆ¶Buffer
//        /// </summary>
//        /// <param name="file1"></param>
//        /// <param name="file2"></param>
//        /// <returns></returns>
//        public string FaceMatchByBuffer(byte[] file1, byte[] file2)
//        {
//            // System.Drawing.Image img1 = System.Drawing.Image.FromFile(file1);
//            byte[] img_bytes1 = file1; // ImageUtil.img2byte(img1);
            // System.Drawing.Image img2 = System.Drawing.Image.FromFile(file2);
            byte[] img_bytes2 = file2; // ImageUtil.img2byte(img2);
            Console.WriteLine("IntPtr ptr = match_by_buf");
            IntPtr ptr = match_by_buf(img_bytes1, img_bytes1.Length, img_bytes2, img_bytes2.Length);
            string buf = Marshal.PtrToStringAnsi(ptr);
            return ("match_by_buf res is:" + buf);
        }
        // æµ‹è¯•1:1比较,传入opencv视频帧
        public void test_match_by_mat()
        {
            Mat img1 = Cv2.ImRead("d:\\444.bmp");
            Mat img2 = Cv2.ImRead("d:\\555.png");
            IntPtr ptr = match_by_mat(img1.CvPtr, img2.CvPtr);// img_bytes1, img_bytes1.Length, img_bytes2, img_bytes2.Length);
            string buf = Marshal.PtrToStringAnsi(ptr);
            Console.WriteLine("match_by_buf res is:" + buf);
        }
        /// <summary>
        /// 1:1比较,传入opencv视频帧
        /// </summary>
        /// <param name="file1"></param>
        /// <param name="file2"></param>
        /// <returns></returns>
        public string FaceMatchByMat(string file1, string file2)
        {
            Mat img1 = Cv2.ImRead(file1);
            Mat img2 = Cv2.ImRead(file2);
            IntPtr ptr = match_by_mat(img1.CvPtr, img2.CvPtr);// img_bytes1, img_bytes1.Length, img_bytes2, img_bytes2.Length);
            string buf = Marshal.PtrToStringAnsi(ptr);
            return ("match_by_buf res is:" + buf);
//            // System.Drawing.Image img2 = System.Drawing.Image.FromFile(file2);
//            byte[] img_bytes2 = file2; // ImageUtil.img2byte(img2);
//            Console.WriteLine("IntPtr ptr = match_by_buf");
//            IntPtr ptr = match_by_buf(img_bytes1, img_bytes1.Length, img_bytes2, img_bytes2.Length);
//            string buf = Marshal.PtrToStringAnsi(ptr);
//            return ("match_by_buf res is:" + buf);
//        }
//        // æµ‹è¯•1:1比较,传入opencv视频帧
//        public void test_match_by_mat()
//        {
//            Mat img1 = Cv2.ImRead("d:\\444.bmp");
//            Mat img2 = Cv2.ImRead("d:\\555.png");
//            IntPtr ptr = match_by_mat(img1.CvPtr, img2.CvPtr);// img_bytes1, img_bytes1.Length, img_bytes2, img_bytes2.Length);
//            string buf = Marshal.PtrToStringAnsi(ptr);
//            Console.WriteLine("match_by_buf res is:" + buf);
//        }
//        /// <summary>
//        /// 1:1比较,传入opencv视频帧
//        /// </summary>
//        /// <param name="file1"></param>
//        /// <param name="file2"></param>
//        /// <returns></returns>
//        public string FaceMatchByMat(string file1, string file2)
//        {
//            Mat img1 = Cv2.ImRead(file1);
//            Mat img2 = Cv2.ImRead(file2);
//            IntPtr ptr = match_by_mat(img1.CvPtr, img2.CvPtr);// img_bytes1, img_bytes1.Length, img_bytes2, img_bytes2.Length);
//            string buf = Marshal.PtrToStringAnsi(ptr);
//            return ("match_by_buf res is:" + buf);
        }
        // æµ‹è¯•根据特征值和图片二进制buf比较
        //public void test_match_by_feature()
        //{
        //    // èŽ·å–ç‰¹å¾å€¼2048个字节
        //    byte[] fea = new byte[2048];
        //    string file_name = "G:\\Development\\Application\\testface\\img\\beckham\\2.jpg";
        //    int len = 0;
        //    IntPtr ptr = get_face_feature(file_name, ref len);
        //    if (len != 2048)
        //    {
        //        Console.WriteLine("get face feature error!");
        //        return;
        //    }
        //    Marshal.Copy(ptr, fea, 0, 2048);
        //    // èŽ·å–å›¾ç‰‡äºŒè¿›åˆ¶buffer
        //    System.Drawing.Image img2 = System.Drawing.Image.FromFile("G:\\Development\\Application\\testface\\img\\beckham\\8.jpg");
        //    byte[] img_bytes2 = ImageUtil.img2byte(img2);
//        }
//        // æµ‹è¯•根据特征值和图片二进制buf比较
//        //public void test_match_by_feature()
//        //{
//        //    // èŽ·å–ç‰¹å¾å€¼2048个字节
//        //    byte[] fea = new byte[2048];
//        //    string file_name = "G:\\Development\\Application\\testface\\img\\beckham\\2.jpg";
//        //    int len = 0;
//        //    IntPtr ptr = get_face_feature(file_name, ref len);
//        //    if (len != 2048)
//        //    {
//        //        Console.WriteLine("get face feature error!");
//        //        return;
//        //    }
//        //    Marshal.Copy(ptr, fea, 0, 2048);
//        //    // èŽ·å–å›¾ç‰‡äºŒè¿›åˆ¶buffer
//        //    System.Drawing.Image img2 = System.Drawing.Image.FromFile("G:\\Development\\Application\\testface\\img\\beckham\\8.jpg");
//        //    byte[] img_bytes2 = ImageUtil.img2byte(img2);
        //    IntPtr ptr_res = match_by_feature(fea, fea.Length, img_bytes2, img_bytes2.Length);
        //    string buf = Marshal.PtrToStringAnsi(ptr_res);
        //    Console.WriteLine("match_by_feature res is:" + buf);
//        //    IntPtr ptr_res = match_by_feature(fea, fea.Length, img_bytes2, img_bytes2.Length);
//        //    string buf = Marshal.PtrToStringAnsi(ptr_res);
//        //    Console.WriteLine("match_by_feature res is:" + buf);
        //}
        /// <summary>
        /// æ ¹æ®ç‰¹å¾å€¼å’Œå›¾ç‰‡äºŒè¿›åˆ¶buf比较
        /// </summary>
        /// <param name="file_name">需要对比的特征值</param>
        /// <param name="file_buffer">需要对比的第二张图片,小于10M</param>
        /// <returns></returns>
        public string FaceMatchByFeature(byte[] file_name, byte[] file_buffer)
        {
            // èŽ·å–ç‰¹å¾å€¼2048个字节
            byte[] fea = file_name; // new byte[2048];
            //int len = 0;
            //IntPtr ptr = get_face_feature(file_name, ref len);
            //if (len != 2048)
            //{
            //    return ("get face feature error!");
            //}
            //Marshal.Copy(ptr, fea, 0, 2048);
            //// èŽ·å–å›¾ç‰‡äºŒè¿›åˆ¶buffer
            //System.Drawing.Image img2 = System.Drawing.Image.FromFile(file_buffer);
            byte[] img_bytes2 = file_buffer; // ImageUtil.img2byte(img2);
//        //}
//        /// <summary>
//        /// æ ¹æ®ç‰¹å¾å€¼å’Œå›¾ç‰‡äºŒè¿›åˆ¶buf比较
//        /// </summary>
//        /// <param name="file_name">需要对比的特征值</param>
//        /// <param name="file_buffer">需要对比的第二张图片,小于10M</param>
//        /// <returns></returns>
//        public string FaceMatchByFeature(byte[] file_name, byte[] file_buffer)
//        {
//            // èŽ·å–ç‰¹å¾å€¼2048个字节
//            byte[] fea = file_name; // new byte[2048];
//            //int len = 0;
//            //IntPtr ptr = get_face_feature(file_name, ref len);
//            //if (len != 2048)
//            //{
//            //    return ("get face feature error!");
//            //}
//            //Marshal.Copy(ptr, fea, 0, 2048);
//            //// èŽ·å–å›¾ç‰‡äºŒè¿›åˆ¶buffer
//            //System.Drawing.Image img2 = System.Drawing.Image.FromFile(file_buffer);
//            byte[] img_bytes2 = file_buffer; // ImageUtil.img2byte(img2);
            IntPtr ptr_res = match_by_feature(fea, fea.Length, img_bytes2, img_bytes2.Length);
            string buf = Marshal.PtrToStringAnsi(ptr_res);
            Console.WriteLine("match_by_feature res is:" + buf);
            return buf;
//            IntPtr ptr_res = match_by_feature(fea, fea.Length, img_bytes2, img_bytes2.Length);
//            string buf = Marshal.PtrToStringAnsi(ptr_res);
//            Console.WriteLine("match_by_feature res is:" + buf);
//            return buf;
        }
//        }
        // æµ‹è¯•1:N比较,传入图片文件路径
        public /*void*/string test_identify(string str, string usr_grp, string usr_id)
        {
            string file1 = str;//"G:\\Development\\Application\\testface\\img\\beckham\\6.jpg";
            string user_group = usr_grp;//"test_group";
            string user_id = usr_id;//"test_user";
            IntPtr ptr = identify(file1, user_group, user_id);
            string buf = Marshal.PtrToStringAnsi(ptr);
            Console.WriteLine("identify res is:" + buf);
            return buf;
        }
        /// <summary>
        /// 1:N比较,传入图片文件路径
        /// </summary>
        /// <param name="file">图片信息,数据大小小于10M,传入图片文件路径</param>
        /// <param name="user_group">组id列表。默认至少填写一个group_id,从指定的group中进行查找。需要同时查询多个group,用逗号分隔,上限10个</param>
        /// <param name="user_id">用户id,若指定了某个user,则只会与指定group下的这个user进行对比;若user_id传空字符串” â€ï¼Œåˆ™ä¼šä¸Žæ­¤group下的所有user进行1:N识别</param>
        /// <returns></returns>
        public static string FaceIdentify(string file, string user_group, string user_id)
        {
            string file1 = file;
            IntPtr ptr = identify(file1, user_group, user_id);
            string buf = Marshal.PtrToStringAnsi(ptr);
            Console.WriteLine("identify res is:" + buf);
            return buf;
        }
//        // æµ‹è¯•1:N比较,传入图片文件路径
//        public /*void*/string test_identify(string str, string usr_grp, string usr_id)
//        {
//            string file1 = str;//"G:\\Development\\Application\\testface\\img\\beckham\\6.jpg";
//            string user_group = usr_grp;//"test_group";
//            string user_id = usr_id;//"test_user";
//            IntPtr ptr = identify(file1, user_group, user_id);
//            string buf = Marshal.PtrToStringAnsi(ptr);
//            Console.WriteLine("identify res is:" + buf);
//            return buf;
//        }
//        /// <summary>
//        /// 1:N比较,传入图片文件路径
//        /// </summary>
//        /// <param name="file">图片信息,数据大小小于10M,传入图片文件路径</param>
//        /// <param name="user_group">组id列表。默认至少填写一个group_id,从指定的group中进行查找。需要同时查询多个group,用逗号分隔,上限10个</param>
//        /// <param name="user_id">用户id,若指定了某个user,则只会与指定group下的这个user进行对比;若user_id传空字符串” â€ï¼Œåˆ™ä¼šä¸Žæ­¤group下的所有user进行1:N识别</param>
//        /// <returns></returns>
//        public static string FaceIdentify(string file, string user_group, string user_id)
//        {
//            string file1 = file;
//            IntPtr ptr = identify(file1, user_group, user_id);
//            string buf = Marshal.PtrToStringAnsi(ptr);
//            Console.WriteLine("identify res is:" + buf);
//            return buf;
//        }
        // æµ‹è¯•1:N比较,传入图片文件二进制buffer
        //public void test_identify_by_buf(string str, string usr_grp, string usr_id)
        //{
        //    System.Drawing.Image img = System.Drawing.Image.FromFile(str);//"G:\\Development\\Application\\testface\\img\\beckham\\2.jpg");
        //    byte[] img_bytes = ImageUtil.img2byte(img);
//        // æµ‹è¯•1:N比较,传入图片文件二进制buffer
//        //public void test_identify_by_buf(string str, string usr_grp, string usr_id)
//        //{
//        //    System.Drawing.Image img = System.Drawing.Image.FromFile(str);//"G:\\Development\\Application\\testface\\img\\beckham\\2.jpg");
//        //    byte[] img_bytes = ImageUtil.img2byte(img);
        //    string user_group = usr_grp;//"test_group";
        //    string user_id = usr_id;// "test_user";
        //    IntPtr ptr = identify_by_buf(img_bytes, img_bytes.Length, user_group, user_id);
        //    string buf = Marshal.PtrToStringAnsi(ptr);
        //    Console.WriteLine("identify_by_buf res is:" + buf);
        //}
        /// <summary>
        /// 1:N比较,传入图片文件二进制buffer
        /// </summary>
        /// <param name="str">二进制图片信息,数据大小小于10M</param>
        /// <param name="usr_grp">组id列表。默认至少填写一个group_id,从指定的group中进行查找。需要同时查询多个group,用逗号分隔,上限10个</param>
        /// <param name="usr_id">用户id,若指定了某个user,则只会与指定group下的这个user进行对比;若user_id传空字符串” â€ï¼Œåˆ™ä¼šä¸Žæ­¤group下的所有user进行1:N识别</param>
        /// <returns></returns>
        public string FaceIdentifyByBuffer(byte[] str, string usr_grp, string usr_id)
        {
            // System.Drawing.Image img = System.Drawing.Image.FromFile(str);
            byte[] img_bytes = str; // ImageUtil.img2byte(img);
//        //    string user_group = usr_grp;//"test_group";
//        //    string user_id = usr_id;// "test_user";
//        //    IntPtr ptr = identify_by_buf(img_bytes, img_bytes.Length, user_group, user_id);
//        //    string buf = Marshal.PtrToStringAnsi(ptr);
//        //    Console.WriteLine("identify_by_buf res is:" + buf);
//        //}
//        /// <summary>
//        /// 1:N比较,传入图片文件二进制buffer
//        /// </summary>
//        /// <param name="str">二进制图片信息,数据大小小于10M</param>
//        /// <param name="usr_grp">组id列表。默认至少填写一个group_id,从指定的group中进行查找。需要同时查询多个group,用逗号分隔,上限10个</param>
//        /// <param name="usr_id">用户id,若指定了某个user,则只会与指定group下的这个user进行对比;若user_id传空字符串” â€ï¼Œåˆ™ä¼šä¸Žæ­¤group下的所有user进行1:N识别</param>
//        /// <returns></returns>
//        public string FaceIdentifyByBuffer(byte[] str, string usr_grp, string usr_id)
//        {
//            // System.Drawing.Image img = System.Drawing.Image.FromFile(str);
//            byte[] img_bytes = str; // ImageUtil.img2byte(img);
            string user_group = usr_grp;//"test_group";
            string user_id = usr_id;// "test_user";
            IntPtr ptr = identify_by_buf(img_bytes, img_bytes.Length, user_group, user_id);
            string buf = Marshal.PtrToStringAnsi(ptr);
            Console.WriteLine("identify_by_buf res is:" + buf);
            return buf;
        }
//            string user_group = usr_grp;//"test_group";
//            string user_id = usr_id;// "test_user";
//            IntPtr ptr = identify_by_buf(img_bytes, img_bytes.Length, user_group, user_id);
//            string buf = Marshal.PtrToStringAnsi(ptr);
//            Console.WriteLine("identify_by_buf res is:" + buf);
//            return buf;
//        }
        // æµ‹è¯•1:N比较,传入提取的人脸特征值
        public void test_identify_by_feature()
        {
            // èŽ·å–ç‰¹å¾å€¼2048个字节
            byte[] fea = new byte[2048];
            string file_name = "G:\\Development\\Application\\testface\\img\\beckham\\2.jpg";
            int len = 0;
            IntPtr ptr = get_face_feature(file_name, ref len);
            if (len != 2048)
            {
                Console.WriteLine("get face feature error!");
                return;
            }
            Marshal.Copy(ptr, fea, 0, 2048);
//        // æµ‹è¯•1:N比较,传入提取的人脸特征值
//        public void test_identify_by_feature()
//        {
//            // èŽ·å–ç‰¹å¾å€¼2048个字节
//            byte[] fea = new byte[2048];
//            string file_name = "G:\\Development\\Application\\testface\\img\\beckham\\2.jpg";
//            int len = 0;
//            IntPtr ptr = get_face_feature(file_name, ref len);
//            if (len != 2048)
//            {
//                Console.WriteLine("get face feature error!");
//                return;
//            }
//            Marshal.Copy(ptr, fea, 0, 2048);
            string user_group = "test_group";
            string user_id = "test_user";
            IntPtr ptr_res = identify_by_feature(fea, fea.Length, user_group, user_id);
            string buf = Marshal.PtrToStringAnsi(ptr_res);
            Console.WriteLine("identify_by_feature res is:" + buf);
        }
        /// <summary>
        /// 1:N比较,传入提取的人脸特征值
        /// </summary>
        /// <param name="file_name">传入图片特征</param>
        /// <param name="userGroup">组id列表。默认至少填写一个group_id,从指定的group中进行查找。需要同时查询多个group,用逗号分隔,上限10个</param>
        /// <param name="userId">用户id,若指定了某个user,则只会与指定group下的这个user进行对比;若user_id传空字符串” â€ï¼Œåˆ™ä¼šä¸Žæ­¤group下的所有user进行1:N识别</param>
        ///
        public static string FaceIdentifyByFeature(string file_name, string userGroup, string userId)
        {
            // èŽ·å–ç‰¹å¾å€¼2048个字节
            byte[] fea = new byte[2048];
            int len = 0;
            IntPtr ptr = get_face_feature(file_name, ref len);
            if (len != 2048)
            {
                return ("get face feature error!");
            }
            Marshal.Copy(ptr, fea, 0, 2048);
//            string user_group = "test_group";
//            string user_id = "test_user";
//            IntPtr ptr_res = identify_by_feature(fea, fea.Length, user_group, user_id);
//            string buf = Marshal.PtrToStringAnsi(ptr_res);
//            Console.WriteLine("identify_by_feature res is:" + buf);
//        }
//        /// <summary>
//        /// 1:N比较,传入提取的人脸特征值
//        /// </summary>
//        /// <param name="file_name">传入图片特征</param>
//        /// <param name="userGroup">组id列表。默认至少填写一个group_id,从指定的group中进行查找。需要同时查询多个group,用逗号分隔,上限10个</param>
//        /// <param name="userId">用户id,若指定了某个user,则只会与指定group下的这个user进行对比;若user_id传空字符串” â€ï¼Œåˆ™ä¼šä¸Žæ­¤group下的所有user进行1:N识别</param>
//        ///
//        public static string FaceIdentifyByFeature(string file_name, string userGroup, string userId)
//        {
//            // èŽ·å–ç‰¹å¾å€¼2048个字节
//            byte[] fea = new byte[2048];
//            int len = 0;
//            IntPtr ptr = get_face_feature(file_name, ref len);
//            if (len != 2048)
//            {
//                return ("get face feature error!");
//            }
//            Marshal.Copy(ptr, fea, 0, 2048);
            string user_group = userGroup == null ? "test_group" : userGroup;
            string user_id = userId == null ? "test_user" : userId;
            IntPtr ptr_res = identify_by_feature(fea, fea.Length, user_group, user_id);
            string buf = Marshal.PtrToStringAnsi(ptr_res);
            Console.WriteLine("identify_by_feature res is:" + buf);
            return buf;
        }
//            string user_group = userGroup == null ? "test_group" : userGroup;
//            string user_id = userId == null ? "test_user" : userId;
//            IntPtr ptr_res = identify_by_feature(fea, fea.Length, user_group, user_id);
//            string buf = Marshal.PtrToStringAnsi(ptr_res);
//            Console.WriteLine("identify_by_feature res is:" + buf);
//            return buf;
//        }
        // é€šè¿‡ç‰¹å¾å€¼æ¯”对(1:1)
        public void test_compare_feature()
        {
            // èŽ·å–ç‰¹å¾å€¼1   å…±2048个字节
            byte[] fea1 = new byte[2048];
            string file_name1 = "G:\\Development\\Application\\testface\\img\\beckham\\2.jpg";
            int len1 = 0;
            IntPtr ptr1 = get_face_feature(file_name1, ref len1);
            if (len1 != 2048)
            {
                Console.WriteLine("get face feature error!");
                return;
            }
            Marshal.Copy(ptr1, fea1, 0, 2048);
//        // é€šè¿‡ç‰¹å¾å€¼æ¯”对(1:1)
//        public void test_compare_feature()
//        {
//            // èŽ·å–ç‰¹å¾å€¼1   å…±2048个字节
//            byte[] fea1 = new byte[2048];
//            string file_name1 = "G:\\Development\\Application\\testface\\img\\beckham\\2.jpg";
//            int len1 = 0;
//            IntPtr ptr1 = get_face_feature(file_name1, ref len1);
//            if (len1 != 2048)
//            {
//                Console.WriteLine("get face feature error!");
//                return;
//            }
//            Marshal.Copy(ptr1, fea1, 0, 2048);
            // èŽ·å–ç‰¹å¾å€¼2   å…±2048个字节
            byte[] fea2 = new byte[2048];
            string file_name2 = "G:\\Development\\Application\\testface\\img\\beckham\\8.jpg";
            int len2 = 0;
            IntPtr ptr2 = get_face_feature(file_name2, ref len2);
            if (len2 != 2048)
            {
                Console.WriteLine("get face feature error!");
                return;
            }
            Marshal.Copy(ptr2, fea2, 0, 2048);
            // æ¯”对
            float score = compare_feature(fea1, len1, fea2, len2);
            Console.WriteLine("compare_feature score is:" + score);
        }
        /// <summary>
        /// é€šè¿‡ç‰¹å¾å€¼æ¯”对(1:1) å¯¹äººè„¸ç‰¹å¾å€¼è¿›è¡Œæ¯”较,可返回人脸特征相似分值(百分制)
        /// </summary>
        /// <param name="file_name1">2048个byte数组的特征值(传图片路径)</param>
        /// <param name="file_name2">2048个byte数组的特征值(传图片路径)</param>
        /// <returns></returns>
        public static string FaceCompareFeature(string file_name1, string file_name2)
        {
            string mes = "入:";
            try
            {
//            // èŽ·å–ç‰¹å¾å€¼2   å…±2048个字节
//            byte[] fea2 = new byte[2048];
//            string file_name2 = "G:\\Development\\Application\\testface\\img\\beckham\\8.jpg";
//            int len2 = 0;
//            IntPtr ptr2 = get_face_feature(file_name2, ref len2);
//            if (len2 != 2048)
//            {
//                Console.WriteLine("get face feature error!");
//                return;
//            }
//            Marshal.Copy(ptr2, fea2, 0, 2048);
//            // æ¯”对
//            float score = compare_feature(fea1, len1, fea2, len2);
//            Console.WriteLine("compare_feature score is:" + score);
//        }
//        /// <summary>
//        /// é€šè¿‡ç‰¹å¾å€¼æ¯”对(1:1) å¯¹äººè„¸ç‰¹å¾å€¼è¿›è¡Œæ¯”较,可返回人脸特征相似分值(百分制)
//        /// </summary>
//        /// <param name="file_name1">2048个byte数组的特征值(传图片路径)</param>
//        /// <param name="file_name2">2048个byte数组的特征值(传图片路径)</param>
//        /// <returns></returns>
//        public static string FaceCompareFeature(string file_name1, string file_name2)
//        {
//            string mes = "入:";
//            try
//            {
                // èŽ·å–ç‰¹å¾å€¼1   å…±2048个字节
                byte[] fea1 = new byte[2048];
                int len1 = 0;
                IntPtr ptr1 = get_face_feature(file_name1, ref len1);
                if (len1 != 2048)
                {
                    return mes += "get face feature error!";
                }
                Marshal.Copy(ptr1, fea1, 0, 2048);
//                // èŽ·å–ç‰¹å¾å€¼1   å…±2048个字节
//                byte[] fea1 = new byte[2048];
//                int len1 = 0;
//                IntPtr ptr1 = get_face_feature(file_name1, ref len1);
//                if (len1 != 2048)
//                {
//                    return mes += "get face feature error!";
//                }
//                Marshal.Copy(ptr1, fea1, 0, 2048);
                // èŽ·å–ç‰¹å¾å€¼2   å…±2048个字节
                byte[] fea2 = new byte[2048];
                int len2 = 0;
                IntPtr ptr2 = get_face_feature(file_name2, ref len2);
                if (len2 != 2048)
                {
                    return mes += "get face feature error!";
                }
                Marshal.Copy(ptr2, fea2, 0, 2048);
                // æ¯”对
                // len1 ç‰¹å¾å€¼1的长度
                float score = compare_feature(fea1, len1, fea2, len2);
                Console.WriteLine("compare_feature score is:" + score);
                return mes += score.ToString();
//                // èŽ·å–ç‰¹å¾å€¼2   å…±2048个字节
//                byte[] fea2 = new byte[2048];
//                int len2 = 0;
//                IntPtr ptr2 = get_face_feature(file_name2, ref len2);
//                if (len2 != 2048)
//                {
//                    return mes += "get face feature error!";
//                }
//                Marshal.Copy(ptr2, fea2, 0, 2048);
//                // æ¯”对
//                // len1 ç‰¹å¾å€¼1的长度
//                float score = compare_feature(fea1, len1, fea2, len2);
//                Console.WriteLine("compare_feature score is:" + score);
//                return mes += score.ToString();
            }
            catch (Exception ex)
            {
                return mes += ex;
            }
        }
        /// <summary>
        /// é€šè¿‡ç‰¹å¾å€¼æ¯”对(1:1) å¯¹äººè„¸ç‰¹å¾å€¼è¿›è¡Œæ¯”较,可返回人脸特征相似分值(百分制)
        /// </summary>
        /// <param name="face1">2048个byte数组的特征值</param>
        /// <param name="face2">2048个byte数组的特征值</param>
        /// <returns></returns>
        public string FaceCompareFeatureByBuffer(byte[] face1, byte[] face2)
        {
            if (face1.Length == 2048 && face2.Length == 2048)
            {
                // èŽ·å–ç‰¹å¾å€¼1   å…±2048个字节
                byte[] fea1 = new byte[2048];
                fea1 = face1;
                int len1 = 0;
                // èŽ·å–ç‰¹å¾å€¼1   å…±2048个字节
                byte[] fea2 = new byte[2048];
                fea2 = face2;
                int len2 = 0;
                // æ¯”对
                // len1 ç‰¹å¾å€¼1的长度
                float score = compare_feature(fea1, len1, fea2, len2);
                Console.WriteLine("compare_feature score is:" + score);
                return score.ToString();
            }
            else
            {
                return "byte should be 2048";
            }
        }
//            }
//            catch (Exception ex)
//            {
//                return mes += ex;
//            }
//        }
//        /// <summary>
//        /// é€šè¿‡ç‰¹å¾å€¼æ¯”对(1:1) å¯¹äººè„¸ç‰¹å¾å€¼è¿›è¡Œæ¯”较,可返回人脸特征相似分值(百分制)
//        /// </summary>
//        /// <param name="face1">2048个byte数组的特征值</param>
//        /// <param name="face2">2048个byte数组的特征值</param>
//        /// <returns></returns>
//        public string FaceCompareFeatureByBuffer(byte[] face1, byte[] face2)
//        {
//            if (face1.Length == 2048 && face2.Length == 2048)
//            {
//                // èŽ·å–ç‰¹å¾å€¼1   å…±2048个字节
//                byte[] fea1 = new byte[2048];
//                fea1 = face1;
//                int len1 = 0;
//                // èŽ·å–ç‰¹å¾å€¼1   å…±2048个字节
//                byte[] fea2 = new byte[2048];
//                fea2 = face2;
//                int len2 = 0;
//                // æ¯”对
//                // len1 ç‰¹å¾å€¼1的长度
//                float score = compare_feature(fea1, len1, fea2, len2);
//                Console.WriteLine("compare_feature score is:" + score);
//                return score.ToString();
//            }
//            else
//            {
//                return "byte should be 2048";
//            }
//        }
        // æµ‹è¯•1:N比较,传入提取的人脸特征值和已加载的内存中整个库比较
        public void test_identify_by_feature_with_all()
        {
            // åŠ è½½æ•´ä¸ªæ•°æ®åº“åˆ°å†…å­˜ä¸­
            load_db_face();
            // èŽ·å–ç‰¹å¾å€¼2048个字节
            byte[] fea = new byte[2048];
            string file_name = "G:\\Development\\Application\\testface\\img\\beckham\\2.jpg";
            int len = 0;
            IntPtr ptr = get_face_feature(file_name, ref len);
            if (len != 2048)
            {
                Console.WriteLine("get face feature error!");
                return;
            }
            Marshal.Copy(ptr, fea, 0, 2048);
            IntPtr ptr_res = identify_by_feature_with_all(fea, fea.Length);
            string buf = Marshal.PtrToStringAnsi(ptr_res);
            Console.WriteLine("identify_by_feature_with_all res is:" + buf);
        }
        /// <summary>
        /// 1:N比较,传入提取的人脸特征值和已加载的内存中整个库比较
        /// </summary>
        /// <param name="file_name">传入人脸文件特征值</param>
        /// <returns></returns>
        public string FaceIdentifyByFeatureWithAll(byte[] file_name)
        {
            // åŠ è½½æ•´ä¸ªæ•°æ®åº“åˆ°å†…å­˜ä¸­
            load_db_face();
            // èŽ·å–ç‰¹å¾å€¼2048个字节
            byte[] fea = new byte[2048];
            fea = file_name;
            int len = 0;
            //IntPtr ptr = get_face_feature(file_name, ref len);
            //if (len != 2048)
            //{
            //    Console.WriteLine("get face feature error!");
            //    return "error";
            //}
            // Marshal.Copy(ptr, fea, 0, 2048);
            IntPtr ptr_res = identify_by_feature_with_all(fea, fea.Length);
            string buf = Marshal.PtrToStringAnsi(ptr_res);
            Console.WriteLine("identify_by_feature_with_all res is:" + buf);
            return buf;
        }
//        // æµ‹è¯•1:N比较,传入提取的人脸特征值和已加载的内存中整个库比较
//        public void test_identify_by_feature_with_all()
//        {
//            // åŠ è½½æ•´ä¸ªæ•°æ®åº“åˆ°å†…å­˜ä¸­
//            load_db_face();
//            // èŽ·å–ç‰¹å¾å€¼2048个字节
//            byte[] fea = new byte[2048];
//            string file_name = "G:\\Development\\Application\\testface\\img\\beckham\\2.jpg";
//            int len = 0;
//            IntPtr ptr = get_face_feature(file_name, ref len);
//            if (len != 2048)
//            {
//                Console.WriteLine("get face feature error!");
//                return;
//            }
//            Marshal.Copy(ptr, fea, 0, 2048);
//            IntPtr ptr_res = identify_by_feature_with_all(fea, fea.Length);
//            string buf = Marshal.PtrToStringAnsi(ptr_res);
//            Console.WriteLine("identify_by_feature_with_all res is:" + buf);
//        }
//        /// <summary>
//        /// 1:N比较,传入提取的人脸特征值和已加载的内存中整个库比较
//        /// </summary>
//        /// <param name="file_name">传入人脸文件特征值</param>
//        /// <returns></returns>
//        public string FaceIdentifyByFeatureWithAll(byte[] file_name)
//        {
//            // åŠ è½½æ•´ä¸ªæ•°æ®åº“åˆ°å†…å­˜ä¸­
//            load_db_face();
//            // èŽ·å–ç‰¹å¾å€¼2048个字节
//            byte[] fea = new byte[2048];
//            fea = file_name;
//            int len = 0;
//            //IntPtr ptr = get_face_feature(file_name, ref len);
//            //if (len != 2048)
//            //{
//            //    Console.WriteLine("get face feature error!");
//            //    return "error";
//            //}
//            // Marshal.Copy(ptr, fea, 0, 2048);
//            IntPtr ptr_res = identify_by_feature_with_all(fea, fea.Length);
//            string buf = Marshal.PtrToStringAnsi(ptr_res);
//            Console.WriteLine("identify_by_feature_with_all res is:" + buf);
//            return buf;
//        }
        // æµ‹è¯•1:N比较,传入图片文件路径和已加载的内存中整个库比较
        public void test_identify_with_all()
        {
            // åŠ è½½æ•´ä¸ªæ•°æ®åº“åˆ°å†…å­˜ä¸­
            load_db_face();
            // 1:N
            string file1 = "G:\\Development\\Application\\testface\\img\\beckham\\3.jpg";
            IntPtr ptr = identify_with_all(file1);
            string buf = Marshal.PtrToStringAnsi(ptr);
            Console.WriteLine("identify_with_all res is:" + buf);
        }
        /// <summary>
        /// 1:N比较,传入图片文件路径和已加载的内存中整个库比较
        /// </summary>
        /// <param name="file1">传入图片路径</param>
        /// <returns></returns>
        public string FaceIndentifyWithAll(string file1)
        {
            // åŠ è½½æ•´ä¸ªæ•°æ®åº“åˆ°å†…å­˜ä¸­
            load_db_face();
            // 1:N
            IntPtr ptr = identify_with_all(file1);
            string buf = Marshal.PtrToStringAnsi(ptr);
            Console.WriteLine("identify_with_all res is:" + buf);
            return buf;
        }
//        // æµ‹è¯•1:N比较,传入图片文件路径和已加载的内存中整个库比较
//        public void test_identify_with_all()
//        {
//            // åŠ è½½æ•´ä¸ªæ•°æ®åº“åˆ°å†…å­˜ä¸­
//            load_db_face();
//            // 1:N
//            string file1 = "G:\\Development\\Application\\testface\\img\\beckham\\3.jpg";
//            IntPtr ptr = identify_with_all(file1);
//            string buf = Marshal.PtrToStringAnsi(ptr);
//            Console.WriteLine("identify_with_all res is:" + buf);
//        }
//        /// <summary>
//        /// 1:N比较,传入图片文件路径和已加载的内存中整个库比较
//        /// </summary>
//        /// <param name="file1">传入图片路径</param>
//        /// <returns></returns>
//        public string FaceIndentifyWithAll(string file1)
//        {
//            // åŠ è½½æ•´ä¸ªæ•°æ®åº“åˆ°å†…å­˜ä¸­
//            load_db_face();
//            // 1:N
//            IntPtr ptr = identify_with_all(file1);
//            string buf = Marshal.PtrToStringAnsi(ptr);
//            Console.WriteLine("identify_with_all res is:" + buf);
//            return buf;
//        }
       
        /// <summary>
        /// 1:N比较,传入图片文件二进制buffer和已加载的内存中整个库比较
        /// </summary>
        /// <param name="file_name"></param>
        /// <returns></returns>
        public string FaceIdentifyByBufferWithAll(byte[] file_name)
        {
            // åŠ è½½æ•´ä¸ªæ•°æ®åº“åˆ°å†…å­˜ä¸­
            load_db_face();
            // 1:N
            // System.Drawing.Image img = System.Drawing.Image.FromFile(file_name);
            byte[] img_bytes = file_name;// ImageUtil.img2byte(img);
//        /// <summary>
//        /// 1:N比较,传入图片文件二进制buffer和已加载的内存中整个库比较
//        /// </summary>
//        /// <param name="file_name"></param>
//        /// <returns></returns>
//        public string FaceIdentifyByBufferWithAll(byte[] file_name)
//        {
//            // åŠ è½½æ•´ä¸ªæ•°æ®åº“åˆ°å†…å­˜ä¸­
//            load_db_face();
//            // 1:N
//            // System.Drawing.Image img = System.Drawing.Image.FromFile(file_name);
//            byte[] img_bytes = file_name;// ImageUtil.img2byte(img);
            IntPtr ptr = identify_by_buf_with_all(img_bytes, img_bytes.Length);
            string buf = Marshal.PtrToStringAnsi(ptr);
            Console.WriteLine("identify_by_buf_with_all res is:" + buf);
            return buf;
        }
//            IntPtr ptr = identify_by_buf_with_all(img_bytes, img_bytes.Length);
//            string buf = Marshal.PtrToStringAnsi(ptr);
//            Console.WriteLine("identify_by_buf_with_all res is:" + buf);
//            return buf;
//        }
    }
}
//    }
//}
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/FaceAI/FaceDraw.cs
@@ -1,151 +1,151 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenCvSharp;
// ç»˜åˆ¶ç±»ï¼Œç”»äººè„¸æ¡†ï¼Œç”»å…³é”®ç‚¹ç­‰
namespace FaceAI
{
    class FaceDraw
    {
        // ç”»äººè„¸æ¡†
        public static int draw_rects(ref Mat img, int face_num, BDFaceBBox[] info)
        {
            if (face_num <= 0)
            {
                return 0;
            }
            Scalar color = new Scalar(0, 255, 0);
            for (int i = 0; i < face_num; i++)
            {
                int x = Convert.ToInt32(info[i].center_x - info[i].width / 2.0);
                int y = Convert.ToInt32(info[i].center_y - info[i].height / 2.0);
                int w = Convert.ToInt32(info[i].width);
                int h = Convert.ToInt32(info[i].height);
                Rect rect = new Rect(x, y, w, h);
                Cv2.Rectangle(img, rect, color);
            }
            return 0;
        }
        // ç”»äººè„¸æ¡†
        public static int draw_rects(ref Mat img, int face_num, BDFaceTrackInfo[] track_info)
        {
            if (face_num <= 0)
            {
                return 0;
            }
            Scalar color = new Scalar(0, 255, 0);
            for(int i = 0; i < face_num; i++)
            {
                int x = Convert.ToInt32(track_info[i].box.center_x- track_info[i].box.width / 2.0);
                int y = Convert.ToInt32(track_info[i].box.center_y - track_info[i].box.height / 2.0);
                int w = Convert.ToInt32(track_info[i].box.width);
                int h = Convert.ToInt32(track_info[i].box.height);
                Rect rect = new Rect(x,y,w,h);
                Cv2.Rectangle(img, rect, color);
            }
            return 0;
        }
        // ç”»äººè„¸å…³é”®ç‚¹
        public static int draw_shape(ref Mat img, int face_num, BDFaceTrackInfo[] track_info)
        {
            if (face_num <= 0)
            {
                return 0;
            }
            int face_id = 0;
            Scalar color = new Scalar(0, 255, 255);
            Scalar color2 = new Scalar(0, 0, 255);
            for (int i = 0; i < face_num; ++i)
            {
                int point_size = track_info[i].landmark.size / 2;
                int radius = 2;
                face_id = track_info[i].face_id;
                for (int j = 0; j < point_size; ++j)
                {
                    Cv2.Circle(img, (int)track_info[i].landmark.data[j * 2], (int)track_info[i].landmark.data[j * 2 + 1], radius, color);
                }
                if (point_size == 72)
                {
                    const int components = 9;
                    int[] comp1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
                    int[] comp2 = { 13, 14, 15, 16, 17, 18, 19, 20, 13, 21 };
                    int[] comp3 = { 22, 23, 24, 25, 26, 27, 28, 29, 22 };
                    int[] comp4 = { 30, 31, 32, 33, 34, 35, 36, 37, 30, 38 };
                    int[] comp5 = { 39, 40, 41, 42, 43, 44, 45, 46, 39 };
                    int[] comp6 = { 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 47 };
                    int[] comp7 = { 51, 57, 52 };
                    int[] comp8 = { 58, 59, 60, 61, 62, 63, 64, 65, 58 };
                    int[] comp9 = { 58, 66, 67, 68, 62, 69, 70, 71, 58 };
                    int[][] idx = { comp1, comp2, comp3, comp4, comp5, comp6, comp7, comp8, comp9 };
                    int[] npoints = { 13, 10, 9, 10, 9, 11, 3, 9, 9 };
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using System.Threading.Tasks;
//using OpenCvSharp;
//// ç»˜åˆ¶ç±»ï¼Œç”»äººè„¸æ¡†ï¼Œç”»å…³é”®ç‚¹ç­‰
//namespace FaceAI
//{
//    class FaceDraw
//    {
//        // ç”»äººè„¸æ¡†
//        public static int draw_rects(ref Mat img, int face_num, BDFaceBBox[] info)
//        {
//            if (face_num <= 0)
//            {
//                return 0;
//            }
//            Scalar color = new Scalar(0, 255, 0);
//            for (int i = 0; i < face_num; i++)
//            {
//                int x = Convert.ToInt32(info[i].center_x - info[i].width / 2.0);
//                int y = Convert.ToInt32(info[i].center_y - info[i].height / 2.0);
//                int w = Convert.ToInt32(info[i].width);
//                int h = Convert.ToInt32(info[i].height);
//                Rect rect = new Rect(x, y, w, h);
//                Cv2.Rectangle(img, rect, color);
//            }
//            return 0;
//        }
//        // ç”»äººè„¸æ¡†
//        public static int draw_rects(ref Mat img, int face_num, BDFaceTrackInfo[] track_info)
//        {
//            if (face_num <= 0)
//            {
//                return 0;
//            }
//            Scalar color = new Scalar(0, 255, 0);
//            for(int i = 0; i < face_num; i++)
//            {
//                int x = Convert.ToInt32(track_info[i].box.center_x- track_info[i].box.width / 2.0);
//                int y = Convert.ToInt32(track_info[i].box.center_y - track_info[i].box.height / 2.0);
//                int w = Convert.ToInt32(track_info[i].box.width);
//                int h = Convert.ToInt32(track_info[i].box.height);
//                Rect rect = new Rect(x,y,w,h);
//                Cv2.Rectangle(img, rect, color);
//            }
//            return 0;
//        }
//        // ç”»äººè„¸å…³é”®ç‚¹
//        public static int draw_shape(ref Mat img, int face_num, BDFaceTrackInfo[] track_info)
//        {
//            if (face_num <= 0)
//            {
//                return 0;
//            }
//            int face_id = 0;
//            Scalar color = new Scalar(0, 255, 255);
//            Scalar color2 = new Scalar(0, 0, 255);
//            for (int i = 0; i < face_num; ++i)
//            {
//                int point_size = track_info[i].landmark.size / 2;
//                int radius = 2;
//                face_id = track_info[i].face_id;
//                for (int j = 0; j < point_size; ++j)
//                {
//                    Cv2.Circle(img, (int)track_info[i].landmark.data[j * 2], (int)track_info[i].landmark.data[j * 2 + 1], radius, color);
//                }
//                if (point_size == 72)
//                {
//                    const int components = 9;
//                    int[] comp1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
//                    int[] comp2 = { 13, 14, 15, 16, 17, 18, 19, 20, 13, 21 };
//                    int[] comp3 = { 22, 23, 24, 25, 26, 27, 28, 29, 22 };
//                    int[] comp4 = { 30, 31, 32, 33, 34, 35, 36, 37, 30, 38 };
//                    int[] comp5 = { 39, 40, 41, 42, 43, 44, 45, 46, 39 };
//                    int[] comp6 = { 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 47 };
//                    int[] comp7 = { 51, 57, 52 };
//                    int[] comp8 = { 58, 59, 60, 61, 62, 63, 64, 65, 58 };
//                    int[] comp9 = { 58, 66, 67, 68, 62, 69, 70, 71, 58 };
//                    int[][] idx = { comp1, comp2, comp3, comp4, comp5, comp6, comp7, comp8, comp9 };
//                    int[] npoints = { 13, 10, 9, 10, 9, 11, 3, 9, 9 };
                    for (int m = 0; m < components; ++m)
                    {
                        for (int n = 0; n < npoints[m] - 1; ++n)
                        {
                            Point p1 = new Point(track_info[i].landmark.data[idx[m][n] * 2], track_info[i].landmark.data[idx[m][n] * 2 + 1]);
                            Point p2 = new Point(track_info[i].landmark.data[idx[m][n + 1] * 2], track_info[i].landmark.data[idx[m][n + 1] * 2 + 1]);
                            Cv2.Line(img, p1, p2, color2);
                        }
                    }
                }
                string s_face_id = face_id.ToString();
                double font_scale = 2;
                Point pos = new Point(track_info[i].box.center_x, track_info[i].box.center_y);
                Cv2.PutText(img, s_face_id, pos, HersheyFonts.HersheyComplex, font_scale, new Scalar(0, 255, 255));
            }
//                    for (int m = 0; m < components; ++m)
//                    {
//                        for (int n = 0; n < npoints[m] - 1; ++n)
//                        {
//                            Point p1 = new Point(track_info[i].landmark.data[idx[m][n] * 2], track_info[i].landmark.data[idx[m][n] * 2 + 1]);
//                            Point p2 = new Point(track_info[i].landmark.data[idx[m][n + 1] * 2], track_info[i].landmark.data[idx[m][n + 1] * 2 + 1]);
//                            Cv2.Line(img, p1, p2, color2);
//                        }
//                    }
//                }
//                string s_face_id = face_id.ToString();
//                double font_scale = 2;
//                Point pos = new Point(track_info[i].box.center_x, track_info[i].box.center_y);
//                Cv2.PutText(img, s_face_id, pos, HersheyFonts.HersheyComplex, font_scale, new Scalar(0, 255, 255));
//            }
           
            return 0;
        }
//            return 0;
//        }
        // ç”»äººè„¸å…³é”®ç‚¹
        public static int draw_landmark(ref Mat img, int face_num, BDFaceLandmark[] landmark)
        {
            if (face_num <= 0)
            {
                return 0;
            }
            Scalar color = new Scalar(0, 255, 255);
            Scalar color2 = new Scalar(0, 0, 255);
            for (int i = 0; i < face_num; ++i)
            {
                int point_size = landmark[i].size / 2;
                int radius = 2;
                for (int j = 0; j < point_size; ++j)
                {
                    Cv2.Circle(img, (int)landmark[i].data[j * 2], (int)landmark[i].data[j * 2 + 1], radius, color);
                }
                if (point_size == 72)
                {
                    const int components = 9;
                    int[] comp1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
                    int[] comp2 = { 13, 14, 15, 16, 17, 18, 19, 20, 13, 21 };
                    int[] comp3 = { 22, 23, 24, 25, 26, 27, 28, 29, 22 };
                    int[] comp4 = { 30, 31, 32, 33, 34, 35, 36, 37, 30, 38 };
                    int[] comp5 = { 39, 40, 41, 42, 43, 44, 45, 46, 39 };
                    int[] comp6 = { 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 47 };
                    int[] comp7 = { 51, 57, 52 };
                    int[] comp8 = { 58, 59, 60, 61, 62, 63, 64, 65, 58 };
                    int[] comp9 = { 58, 66, 67, 68, 62, 69, 70, 71, 58 };
                    int[][] idx = { comp1, comp2, comp3, comp4, comp5, comp6, comp7, comp8, comp9 };
                    int[] npoints = { 13, 10, 9, 10, 9, 11, 3, 9, 9 };
//        // ç”»äººè„¸å…³é”®ç‚¹
//        public static int draw_landmark(ref Mat img, int face_num, BDFaceLandmark[] landmark)
//        {
//            if (face_num <= 0)
//            {
//                return 0;
//            }
//            Scalar color = new Scalar(0, 255, 255);
//            Scalar color2 = new Scalar(0, 0, 255);
//            for (int i = 0; i < face_num; ++i)
//            {
//                int point_size = landmark[i].size / 2;
//                int radius = 2;
//                for (int j = 0; j < point_size; ++j)
//                {
//                    Cv2.Circle(img, (int)landmark[i].data[j * 2], (int)landmark[i].data[j * 2 + 1], radius, color);
//                }
//                if (point_size == 72)
//                {
//                    const int components = 9;
//                    int[] comp1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
//                    int[] comp2 = { 13, 14, 15, 16, 17, 18, 19, 20, 13, 21 };
//                    int[] comp3 = { 22, 23, 24, 25, 26, 27, 28, 29, 22 };
//                    int[] comp4 = { 30, 31, 32, 33, 34, 35, 36, 37, 30, 38 };
//                    int[] comp5 = { 39, 40, 41, 42, 43, 44, 45, 46, 39 };
//                    int[] comp6 = { 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 47 };
//                    int[] comp7 = { 51, 57, 52 };
//                    int[] comp8 = { 58, 59, 60, 61, 62, 63, 64, 65, 58 };
//                    int[] comp9 = { 58, 66, 67, 68, 62, 69, 70, 71, 58 };
//                    int[][] idx = { comp1, comp2, comp3, comp4, comp5, comp6, comp7, comp8, comp9 };
//                    int[] npoints = { 13, 10, 9, 10, 9, 11, 3, 9, 9 };
                    for (int m = 0; m < components; ++m)
                    {
                        for (int n = 0; n < npoints[m] - 1; ++n)
                        {
                            Point p1 = new Point(landmark[i].data[idx[m][n] * 2], landmark[i].data[idx[m][n] * 2 + 1]);
                            Point p2 = new Point(landmark[i].data[idx[m][n + 1] * 2], landmark[i].data[idx[m][n + 1] * 2 + 1]);
                            Cv2.Line(img, p1, p2, color2);
                        }
                    }
                }
//                    for (int m = 0; m < components; ++m)
//                    {
//                        for (int n = 0; n < npoints[m] - 1; ++n)
//                        {
//                            Point p1 = new Point(landmark[i].data[idx[m][n] * 2], landmark[i].data[idx[m][n] * 2 + 1]);
//                            Point p2 = new Point(landmark[i].data[idx[m][n + 1] * 2], landmark[i].data[idx[m][n + 1] * 2 + 1]);
//                            Cv2.Line(img, p1, p2, color2);
//                        }
//                    }
//                }
            }
            return 0;
        }
    }
}
//            }
//            return 0;
//        }
//    }
//}
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/FaceAI/FaceFeature.cs
@@ -1,133 +1,133 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.IO;
using OpenCvSharp;
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using System.Threading.Tasks;
//using System.Runtime.InteropServices;
//using System.IO;
////using OpenCvSharp;
// æå–人脸特征值
namespace FaceAI
{
    // äººè„¸ç‰¹å¾å€¼ç»“构体
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct BDFaceFeature
    {
        public int size;
        // äººè„¸çš„特征值,提取出来后是128个float的浮点值
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
        public float[] data;// = new float[128];
    }
    // äººè„¸ç‰¹å¾å€¼ç»“构体
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct BDDepthFeature
    {
        public int size;
        // äººè„¸çš„æ·±åº¦ç‰¹å¾å€¼ï¼Œæå–出来后是256个float的浮点值
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
        public float[] data;// = new float[256];
    }
    class FaceFeature
    {
        // æå–人脸特征值
        [DllImport("BaiduFaceApi.dll", EntryPoint = "face_feature", CharSet = CharSet.Ansi
            , CallingConvention = CallingConvention.Cdecl)]
        // è¿”回num为特征值的人数,type为0表示提取生活照的特征值,1表示nir的特征值
        public static extern int face_feature(IntPtr feature, IntPtr box, IntPtr mat, int type);
//// æå–人脸特征值
//namespace FaceAI
//{
//    // äººè„¸ç‰¹å¾å€¼ç»“构体
//    [StructLayout(LayoutKind.Sequential, Pack = 1)]
//    public struct BDFaceFeature
//    {
//        public int size;
//        // äººè„¸çš„特征值,提取出来后是128个float的浮点值
//        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
//        public float[] data;// = new float[128];
//    }
//    // äººè„¸ç‰¹å¾å€¼ç»“构体
//    [StructLayout(LayoutKind.Sequential, Pack = 1)]
//    public struct BDDepthFeature
//    {
//        public int size;
//        // äººè„¸çš„æ·±åº¦ç‰¹å¾å€¼ï¼Œæå–出来后是256个float的浮点值
//        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
//        public float[] data;// = new float[256];
//    }
//    class FaceFeature
//    {
//        // æå–人脸特征值
//        [DllImport("BaiduFaceApi.dll", EntryPoint = "face_feature", CharSet = CharSet.Ansi
//            , CallingConvention = CallingConvention.Cdecl)]
//        // è¿”回num为特征值的人数,type为0表示提取生活照的特征值,1表示nir的特征值
//        public static extern int face_feature(IntPtr feature, IntPtr box, IntPtr mat, int type);
       
        public void test_face_feature()
        {
            long t_begin = TimeUtil.get_time_stamp();
            BDFaceFeature[] fea1 = test_get_face_feature_by_path("../images/2.jpg");
            long t_end = TimeUtil.get_time_stamp();
            Console.WriteLine("get feature time cost is:" + (t_end - t_begin));
        }
//        public void test_face_feature()
//        {
//            long t_begin = TimeUtil.get_time_stamp();
//            BDFaceFeature[] fea1 = test_get_face_feature_by_path("../images/2.jpg");
//            long t_end = TimeUtil.get_time_stamp();
//            Console.WriteLine("get feature time cost is:" + (t_end - t_begin));
//        }
        // èŽ·å–ç‰¹å¾å€¼ï¼Œä¼ å…¥å›¾ç‰‡è·¯å¾„
        public BDFaceFeature[] test_get_face_feature_by_path(string img_path)
        {
            // ç‰¹å¾å€¼çš„长度,128个float值
            int dim_count = 128;
            Mat mat = Cv2.ImRead(img_path);
            // å‡è®¾æå–的人数,需要比实际的人数多,因为需要提取分配内存
            int faceNum = 5;
            BDFaceFeature[] feaList = new BDFaceFeature[faceNum];
            for(int i = 0; i < faceNum; i++)
            {
                feaList[i].data = new float[dim_count];
                feaList[i].size = 0;
            }
//        // èŽ·å–ç‰¹å¾å€¼ï¼Œä¼ å…¥å›¾ç‰‡è·¯å¾„
//        public BDFaceFeature[] test_get_face_feature_by_path(string img_path)
//        {
//            // ç‰¹å¾å€¼çš„长度,128个float值
//            int dim_count = 128;
//            Mat mat = Cv2.ImRead(img_path);
//            // å‡è®¾æå–的人数,需要比实际的人数多,因为需要提取分配内存
//            int faceNum = 5;
//            BDFaceFeature[] feaList = new BDFaceFeature[faceNum];
//            for(int i = 0; i < faceNum; i++)
//            {
//                feaList[i].data = new float[dim_count];
//                feaList[i].size = 0;
//            }
           
            if (mat.Empty())
            {
                return null;
            }
//            if (mat.Empty())
//            {
//                return null;
//            }
            int sizeFeature = Marshal.SizeOf(typeof(BDFaceFeature));
            IntPtr ptFea = Marshal.AllocHGlobal(sizeFeature * faceNum);
//            int sizeFeature = Marshal.SizeOf(typeof(BDFaceFeature));
//            IntPtr ptFea = Marshal.AllocHGlobal(sizeFeature * faceNum);
            // æž„造返回的人脸框数据
            BDFaceBBox[] info = new BDFaceBBox[faceNum];
            int sizeBox = Marshal.SizeOf(typeof(BDFaceBBox));
            IntPtr ptBox = Marshal.AllocHGlobal(sizeBox * faceNum);
            // è¿”回num为特征值的人数,type为0表示提取生活照的特征值,1表示证件照的特征值,2表示nir的特征值
            int type = 0;
            int num = face_feature(ptFea, ptBox, mat.CvPtr, type);
            if (num <= 0)
            {
                return null;
            }
            Console.WriteLine("face num is:{0}", num);
            // è¯·ç¡®ä¿faceNum大于num, faceNum为c#期望的检测人数,需要预先分配内存,否则无法获取
            if (num > faceNum)
            {
                num = faceNum;
            }
            for (int index = 0; index < num; index++)
            {
                IntPtr ptrF = new IntPtr();
                IntPtr ptrB = new IntPtr();
                if (8 == IntPtr.Size)
                {
                    ptrF = (IntPtr)(ptFea.ToInt64() + sizeFeature * index);
                    ptrB = (IntPtr)(ptBox.ToInt64() + sizeBox * index);
                }
                else if (4 == IntPtr.Size)
                {
                    ptrF = (IntPtr)(ptFea.ToInt32() + sizeFeature * index);
                    ptrB = (IntPtr)(ptBox.ToInt32() + sizeBox * index);
                }
                feaList[index] = (BDFaceFeature)Marshal.PtrToStructure(ptrF, typeof(BDFaceFeature));
                Console.WriteLine("feaList[index].size is:{0}", feaList[index].size);
//            // æž„造返回的人脸框数据
//            BDFaceBBox[] info = new BDFaceBBox[faceNum];
//            int sizeBox = Marshal.SizeOf(typeof(BDFaceBBox));
//            IntPtr ptBox = Marshal.AllocHGlobal(sizeBox * faceNum);
//            // è¿”回num为特征值的人数,type为0表示提取生活照的特征值,1表示证件照的特征值,2表示nir的特征值
//            int type = 0;
//            int num = face_feature(ptFea, ptBox, mat.CvPtr, type);
//            if (num <= 0)
//            {
//                return null;
//            }
//            Console.WriteLine("face num is:{0}", num);
//            // è¯·ç¡®ä¿faceNum大于num, faceNum为c#期望的检测人数,需要预先分配内存,否则无法获取
//            if (num > faceNum)
//            {
//                num = faceNum;
//            }
//            for (int index = 0; index < num; index++)
//            {
//                IntPtr ptrF = new IntPtr();
//                IntPtr ptrB = new IntPtr();
//                if (8 == IntPtr.Size)
//                {
//                    ptrF = (IntPtr)(ptFea.ToInt64() + sizeFeature * index);
//                    ptrB = (IntPtr)(ptBox.ToInt64() + sizeBox * index);
//                }
//                else if (4 == IntPtr.Size)
//                {
//                    ptrF = (IntPtr)(ptFea.ToInt32() + sizeFeature * index);
//                    ptrB = (IntPtr)(ptBox.ToInt32() + sizeBox * index);
//                }
//                feaList[index] = (BDFaceFeature)Marshal.PtrToStructure(ptrF, typeof(BDFaceFeature));
//                Console.WriteLine("feaList[index].size is:{0}", feaList[index].size);
                
                for (int k = 0; k < feaList[index].size; k++)
                {
                    Console.WriteLine("feature is {0}:", feaList[index].data[k]);
                }
//                for (int k = 0; k < feaList[index].size; k++)
//                {
//                    Console.WriteLine("feature is {0}:", feaList[index].data[k]);
//                }
                info[index] = (BDFaceBBox)Marshal.PtrToStructure(ptrB, typeof(BDFaceBBox));
//                info[index] = (BDFaceBBox)Marshal.PtrToStructure(ptrB, typeof(BDFaceBBox));
                // ç´¢å¼•值
                Console.WriteLine("detect score is:{0}", info[index].index);
                // ç½®ä¿¡åº¦
                Console.WriteLine("detect score is:{0}", info[index].score);
                // äººè„¸å®½åº¦
                Console.WriteLine("detect mWidth is:{0}", info[index].width);
                // ä¸­å¿ƒç‚¹X,Y坐标
                Console.WriteLine("detect mCenter_x is:{0}", info[index].center_x);
                Console.WriteLine("detect mCenter_y is:{0}", info[index].center_y);
            }
            // ç»˜åˆ¶äººè„¸æ¡†
            FaceDraw.draw_rects(ref mat, faceNum, info);
//                // ç´¢å¼•值
//                Console.WriteLine("detect score is:{0}", info[index].index);
//                // ç½®ä¿¡åº¦
//                Console.WriteLine("detect score is:{0}", info[index].score);
//                // äººè„¸å®½åº¦
//                Console.WriteLine("detect mWidth is:{0}", info[index].width);
//                // ä¸­å¿ƒç‚¹X,Y坐标
//                Console.WriteLine("detect mCenter_x is:{0}", info[index].center_x);
//                Console.WriteLine("detect mCenter_y is:{0}", info[index].center_y);
//            }
//            // ç»˜åˆ¶äººè„¸æ¡†
//            FaceDraw.draw_rects(ref mat, faceNum, info);
            //mat.ImWrite("detect.jpg");
            mat.Release();
            return feaList;
        }
//            //mat.ImWrite("detect.jpg");
//            mat.Release();
//            return feaList;
//        }
       
    }
}
//    }
//}
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/FaceAI/FaceLiveness.cs
@@ -1,548 +1,548 @@
using System;
using System.IO;
using System.Threading;
using System.Collections;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using OpenCvSharp;
//using System;
//using System.IO;
//using System.Threading;
//using System.Collections;
//using System.Runtime.InteropServices;
//using System.Collections.Generic;
//using OpenCvSharp;
namespace FaceAI
{
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    // æ´»ä½“分值
    struct BDLivenessScore
    {
        public float score; //分值
    };
    // æ´»ä½“检测
    class FaceLiveness
    {
        // å•ç›®RGB静默活体检测
        [DllImport("BaiduFaceApi.dll", EntryPoint = "rgb_liveness", CharSet = CharSet.Ansi
           , CallingConvention = CallingConvention.Cdecl)]
        public static extern int rgb_liveness(IntPtr ptr_boxinfo, IntPtr ptr_score, IntPtr mat);
//namespace FaceAI
//{
//    [StructLayout(LayoutKind.Sequential, Pack = 1)]
//    // æ´»ä½“分值
//    struct BDLivenessScore
//    {
//        public float score; //分值
//    };
//    // æ´»ä½“检测
//    class FaceLiveness
//    {
//        // å•ç›®RGB静默活体检测
//        [DllImport("BaiduFaceApi.dll", EntryPoint = "rgb_liveness", CharSet = CharSet.Ansi
//           , CallingConvention = CallingConvention.Cdecl)]
//        public static extern int rgb_liveness(IntPtr ptr_boxinfo, IntPtr ptr_score, IntPtr mat);
        // å•目近红外静默活体检测
        [DllImport("BaiduFaceApi.dll", EntryPoint = "nir_liveness", CharSet = CharSet.Ansi
           , CallingConvention = CallingConvention.Cdecl)]
        public static extern int nir_liveness(IntPtr ptr_boxinfo, IntPtr ptr_score, IntPtr mat);
//        // å•目近红外静默活体检测
//        [DllImport("BaiduFaceApi.dll", EntryPoint = "nir_liveness", CharSet = CharSet.Ansi
//           , CallingConvention = CallingConvention.Cdecl)]
//        public static extern int nir_liveness(IntPtr ptr_boxinfo, IntPtr ptr_score, IntPtr mat);
        // åŒç›®æ·±åº¦é™é»˜æ´»ä½“检测
        [DllImport("BaiduFaceApi.dll", EntryPoint = "rgb_depth_liveness", CharSet = CharSet.Ansi
           , CallingConvention = CallingConvention.Cdecl)]
        public static extern int rgb_depth_liveness(IntPtr ptr_boxinfo, IntPtr ptr_rgbscore, IntPtr ptr_depthcore, IntPtr rgb_mat, IntPtr depth_mat);
//        // åŒç›®æ·±åº¦é™é»˜æ´»ä½“检测
//        [DllImport("BaiduFaceApi.dll", EntryPoint = "rgb_depth_liveness", CharSet = CharSet.Ansi
//           , CallingConvention = CallingConvention.Cdecl)]
//        public static extern int rgb_depth_liveness(IntPtr ptr_boxinfo, IntPtr ptr_rgbscore, IntPtr ptr_depthcore, IntPtr rgb_mat, IntPtr depth_mat);
              
        public void test_liveness_by_image()
        {
            // rgb æ´»ä½“检测
            string img_rgb = "../images/rgb.png";
            liveness_check(img_rgb, 0);
            // nir æ´»ä½“检测
            string img_nir = "../images/nir.png";
           // liveness_check(img_nir, 1);
//        public void test_liveness_by_image()
//        {
//            // rgb æ´»ä½“检测
//            string img_rgb = "../images/rgb.png";
//            liveness_check(img_rgb, 0);
//            // nir æ´»ä½“检测
//            string img_nir = "../images/nir.png";
//           // liveness_check(img_nir, 1);
           
        }
//        }
        // æµ‹è¯•单目RGB静默活体检测(传入图片文件路径,活体类型)
        public void liveness_check(string img_path, int live_type)
        {
            Mat mat = Cv2.ImRead(img_path);
            int max_face_num = 1; // æ´»ä½“仅返回一个人脸,多人取最大人脸
//        // æµ‹è¯•单目RGB静默活体检测(传入图片文件路径,活体类型)
//        public void liveness_check(string img_path, int live_type)
//        {
//            Mat mat = Cv2.ImRead(img_path);
//            int max_face_num = 1; // æ´»ä½“仅返回一个人脸,多人取最大人脸
            BDFaceBBox[] box_info = new BDFaceBBox[max_face_num];
//            BDFaceBBox[] box_info = new BDFaceBBox[max_face_num];
            
            int sizeBox = Marshal.SizeOf(typeof(BDFaceBBox));
            IntPtr ptT = Marshal.AllocHGlobal(sizeBox * max_face_num);
//            int sizeBox = Marshal.SizeOf(typeof(BDFaceBBox));
//            IntPtr ptT = Marshal.AllocHGlobal(sizeBox * max_face_num);
           
            BDLivenessScore[] score_info = new BDLivenessScore[max_face_num];
            int sizeScore = Marshal.SizeOf(typeof(BDLivenessScore));
            IntPtr ptS = Marshal.AllocHGlobal(sizeScore * max_face_num);
            // faceNum为返回的检测到的人脸个数
            int faceNum = 0;
            if (live_type == 0)
            {
                faceNum = rgb_liveness(ptT, ptS, mat.CvPtr);
            }
            else if (live_type == 1)
            {
                faceNum = nir_liveness(ptT, ptS, mat.CvPtr);
            }
            mat.Release();
//            BDLivenessScore[] score_info = new BDLivenessScore[max_face_num];
//            int sizeScore = Marshal.SizeOf(typeof(BDLivenessScore));
//            IntPtr ptS = Marshal.AllocHGlobal(sizeScore * max_face_num);
//            // faceNum为返回的检测到的人脸个数
//            int faceNum = 0;
//            if (live_type == 0)
//            {
//                faceNum = rgb_liveness(ptT, ptS, mat.CvPtr);
//            }
//            else if (live_type == 1)
//            {
//                faceNum = nir_liveness(ptT, ptS, mat.CvPtr);
//            }
//            mat.Release();
            Console.WriteLine("faceSize is:" + faceNum);
            for (int index = 0; index < faceNum; index++)
            {
//            Console.WriteLine("faceSize is:" + faceNum);
//            for (int index = 0; index < faceNum; index++)
//            {
                IntPtr ptr = new IntPtr();
                IntPtr ptrScore = new IntPtr();
                if (8 == IntPtr.Size)
                {
                    ptr = (IntPtr)(ptT.ToInt64() + sizeBox * index);
                    ptrScore = (IntPtr)(ptS.ToInt64() + sizeScore * index);
                }
                else if (4 == IntPtr.Size)
                {
                    ptr = (IntPtr)(ptT.ToInt32() + sizeBox * index);
                    ptrScore = (IntPtr)(ptS.ToInt32() + sizeScore * index);
                }
//                IntPtr ptr = new IntPtr();
//                IntPtr ptrScore = new IntPtr();
//                if (8 == IntPtr.Size)
//                {
//                    ptr = (IntPtr)(ptT.ToInt64() + sizeBox * index);
//                    ptrScore = (IntPtr)(ptS.ToInt64() + sizeScore * index);
//                }
//                else if (4 == IntPtr.Size)
//                {
//                    ptr = (IntPtr)(ptT.ToInt32() + sizeBox * index);
//                    ptrScore = (IntPtr)(ptS.ToInt32() + sizeScore * index);
//                }
                box_info[index] = (BDFaceBBox)Marshal.PtrToStructure(ptr, typeof(BDFaceBBox));
//                box_info[index] = (BDFaceBBox)Marshal.PtrToStructure(ptr, typeof(BDFaceBBox));
                score_info[index] = (BDLivenessScore)Marshal.PtrToStructure(ptrScore, typeof(BDLivenessScore));
//                score_info[index] = (BDLivenessScore)Marshal.PtrToStructure(ptrScore, typeof(BDLivenessScore));
              
                // ç´¢å¼•值
                Console.WriteLine("track index is:{0}", box_info[index].index);
                // ç½®ä¿¡åº¦
                Console.WriteLine("track score is:{0}", box_info[index].score);
                // äººè„¸å®½åº¦
                Console.WriteLine("track mWidth is:{0}", box_info[index].width);
                // ä¸­å¿ƒç‚¹X,Y坐标
                Console.WriteLine("track mCenter_x is:{0}", box_info[index].center_x);
                Console.WriteLine("track mCenter_y is:{0}", box_info[index].center_y);
                // rgb æ´»ä½“分值
                Console.WriteLine("liveness score is:{0}", score_info[index].score);
//                // ç´¢å¼•值
//                Console.WriteLine("track index is:{0}", box_info[index].index);
//                // ç½®ä¿¡åº¦
//                Console.WriteLine("track score is:{0}", box_info[index].score);
//                // äººè„¸å®½åº¦
//                Console.WriteLine("track mWidth is:{0}", box_info[index].width);
//                // ä¸­å¿ƒç‚¹X,Y坐标
//                Console.WriteLine("track mCenter_x is:{0}", box_info[index].center_x);
//                Console.WriteLine("track mCenter_y is:{0}", box_info[index].center_y);
//                // rgb æ´»ä½“分值
//                Console.WriteLine("liveness score is:{0}", score_info[index].score);
            }
            Marshal.FreeHGlobal(ptT);
        }
//            }
//            Marshal.FreeHGlobal(ptT);
//        }
        // é€‰æ‹©usb视频摄像头id,方法里面有获取连接的摄像头列表,包括id,名称和路径等
        public int select_usb_device_id()
        {
            ArrayList capDevs = new ArrayList();
            int device_id = 0;
            try
            {
                if (!File.Exists(Path.Combine(Environment.SystemDirectory, @"dpnhpast.dll")))
                {
                    Console.WriteLine("DirectX NOT installed!");
                    return - 1;
                }
                if (!DevEnum.GetDevicesOfCat(FilterCategory.VideoInputDevice, out capDevs))
                {
                    Console.WriteLine("No video capture devices found!");
                    return -1;
                }
                if (capDevs.Count < 2)
                {
                    Console.WriteLine("ir and rgb camera devices needed");
                    return -1;
                }
                foreach (DsDevice d in capDevs) {
                    Console.WriteLine("== VIDEO DEVICE (id:{0}) ==", d.id);
                    Console.WriteLine("Name: {0}", d.Name);
                    Console.WriteLine("Path: {0}", d.Path);
                }
//        // é€‰æ‹©usb视频摄像头id,方法里面有获取连接的摄像头列表,包括id,名称和路径等
//        public int select_usb_device_id()
//        {
//            ArrayList capDevs = new ArrayList();
//            int device_id = 0;
//            try
//            {
//                if (!File.Exists(Path.Combine(Environment.SystemDirectory, @"dpnhpast.dll")))
//                {
//                    Console.WriteLine("DirectX NOT installed!");
//                    return - 1;
//                }
//                if (!DevEnum.GetDevicesOfCat(FilterCategory.VideoInputDevice, out capDevs))
//                {
//                    Console.WriteLine("No video capture devices found!");
//                    return -1;
//                }
//                if (capDevs.Count < 2)
//                {
//                    Console.WriteLine("ir and rgb camera devices needed");
//                    return -1;
//                }
//                foreach (DsDevice d in capDevs) {
//                    Console.WriteLine("== VIDEO DEVICE (id:{0}) ==", d.id);
//                    Console.WriteLine("Name: {0}", d.Name);
//                    Console.WriteLine("Path: {0}", d.Path);
//                }
                if (capDevs.Count > 0)
                {
                    device_id = ((DsDevice)capDevs[0]).id;
                    Console.WriteLine("select device id is:{0}", device_id);
                }
            }
            catch(Exception)
            {
                if (capDevs != null)
                {
                    foreach (DsDevice d in capDevs)
                        d.Dispose();
                    capDevs = null;
                }
                return -1;
            }
            return device_id;
        }
//                if (capDevs.Count > 0)
//                {
//                    device_id = ((DsDevice)capDevs[0]).id;
//                    Console.WriteLine("select device id is:{0}", device_id);
//                }
//            }
//            catch(Exception)
//            {
//                if (capDevs != null)
//                {
//                    foreach (DsDevice d in capDevs)
//                        d.Dispose();
//                    capDevs = null;
//                }
//                return -1;
//            }
//            return device_id;
//        }
        // åŒç›®RGB和IR静默活体检测(可使用迪威泰或视派尔等rgb+nir双目摄像头),rgb和nir的分值都通过如0.8才算活体通过
        public bool rgb_ir_liveness_check_mat()
        {
            int max_face_num = 1;//取最大人脸的活体
            BDLivenessScore[] rgb_score_info = new BDLivenessScore[max_face_num];
            BDLivenessScore[] nir_score_info = new BDLivenessScore[max_face_num];
            int sizeScore = Marshal.SizeOf(typeof(BDLivenessScore));
            IntPtr ptSRGB = Marshal.AllocHGlobal(sizeScore * max_face_num);
            IntPtr ptSNIR = Marshal.AllocHGlobal(sizeScore * max_face_num);
//        // åŒç›®RGB和IR静默活体检测(可使用迪威泰或视派尔等rgb+nir双目摄像头),rgb和nir的分值都通过如0.8才算活体通过
//        public bool rgb_ir_liveness_check_mat()
//        {
//            int max_face_num = 1;//取最大人脸的活体
//            BDLivenessScore[] rgb_score_info = new BDLivenessScore[max_face_num];
//            BDLivenessScore[] nir_score_info = new BDLivenessScore[max_face_num];
//            int sizeScore = Marshal.SizeOf(typeof(BDLivenessScore));
//            IntPtr ptSRGB = Marshal.AllocHGlobal(sizeScore * max_face_num);
//            IntPtr ptSNIR = Marshal.AllocHGlobal(sizeScore * max_face_num);
            // åˆå§‹åŒ–rgb è¿”回的人脸数据
            BDFaceBBox[] rgb_box_info = new BDFaceBBox[max_face_num];
//            // åˆå§‹åŒ–rgb è¿”回的人脸数据
//            BDFaceBBox[] rgb_box_info = new BDFaceBBox[max_face_num];
            
            int sizeBox = Marshal.SizeOf(typeof(BDFaceBBox));
            IntPtr ptTRGB = Marshal.AllocHGlobal(sizeBox * max_face_num);
//            int sizeBox = Marshal.SizeOf(typeof(BDFaceBBox));
//            IntPtr ptTRGB = Marshal.AllocHGlobal(sizeBox * max_face_num);
            // åˆå§‹åŒ–nir è¿”回的人脸数据
            BDFaceBBox[] nir_box_info = new BDFaceBBox[max_face_num];
//            // åˆå§‹åŒ–nir è¿”回的人脸数据
//            BDFaceBBox[] nir_box_info = new BDFaceBBox[max_face_num];
            
            sizeBox = Marshal.SizeOf(typeof(BDFaceBBox));
            IntPtr ptTNIR = Marshal.AllocHGlobal(sizeBox * max_face_num);
//            sizeBox = Marshal.SizeOf(typeof(BDFaceBBox));
//            IntPtr ptTNIR = Marshal.AllocHGlobal(sizeBox * max_face_num);
            // åºå·0为电脑识别的usb摄像头编号,本demo中0为ir红外摄像头
            // ä¸åŒæ‘„像头和电脑识别可能有区别
            // ç¼–号一般从0-10   */
            int device = select_usb_device_id();
            VideoCapture camera1 = VideoCapture.FromCamera(device);
            if(!camera1.IsOpened())
            {
                Console.WriteLine("camera1 open error");
                return false;
            }
//            // åºå·0为电脑识别的usb摄像头编号,本demo中0为ir红外摄像头
//            // ä¸åŒæ‘„像头和电脑识别可能有区别
//            // ç¼–号一般从0-10   */
//            int device = select_usb_device_id();
//            VideoCapture camera1 = VideoCapture.FromCamera(device);
//            if(!camera1.IsOpened())
//            {
//                Console.WriteLine("camera1 open error");
//                return false;
//            }
            VideoCapture camera2 = VideoCapture.FromCamera(device+1);
            if (!camera2.IsOpened())
            {
                Console.WriteLine("camera2 open error");
                return false;
            }
//            VideoCapture camera2 = VideoCapture.FromCamera(device+1);
//            if (!camera2.IsOpened())
//            {
//                Console.WriteLine("camera2 open error");
//                return false;
//            }
            Mat frame1 = new Mat();
            Mat frame2 = new Mat();
            Mat rgb_mat = new Mat();
            Mat ir_mat = new Mat();
            var window_ir = new Window("ir_face");
            var window_rgb = new Window("rgb_face");
            while (true)
            {
                camera1.Read(frame1);
                camera2.Read(frame2);
                if(!frame1.Empty() && !frame2.Empty())
                {
                    if (frame1.Channels() == 3)
                    {
                        rgb_mat = frame1;
                        ir_mat = frame2;
                    }
                    else
                    {
                        rgb_mat = frame2;
                        ir_mat = frame1;
                    }
                    float rgb_score = 0;
                    float ir_score = 0;
//            Mat frame1 = new Mat();
//            Mat frame2 = new Mat();
//            Mat rgb_mat = new Mat();
//            Mat ir_mat = new Mat();
//            var window_ir = new Window("ir_face");
//            var window_rgb = new Window("rgb_face");
//            while (true)
//            {
//                camera1.Read(frame1);
//                camera2.Read(frame2);
//                if(!frame1.Empty() && !frame2.Empty())
//                {
//                    if (frame1.Channels() == 3)
//                    {
//                        rgb_mat = frame1;
//                        ir_mat = frame2;
//                    }
//                    else
//                    {
//                        rgb_mat = frame2;
//                        ir_mat = frame1;
//                    }
//                    float rgb_score = 0;
//                    float ir_score = 0;
                    int face_size = 0;
                    int nir_size = nir_liveness(ptTNIR, ptSNIR, ir_mat.CvPtr);
                    int rgb_size = rgb_liveness(ptTRGB, ptSRGB, rgb_mat.CvPtr);
//                    int face_size = 0;
//                    int nir_size = nir_liveness(ptTNIR, ptSNIR, ir_mat.CvPtr);
//                    int rgb_size = rgb_liveness(ptTRGB, ptSRGB, rgb_mat.CvPtr);
                    
                    face_size = nir_size <= rgb_size?nir_size:rgb_size;
                    // èŽ·å–çš„äººè„¸æ•°
                    Console.WriteLine("faceNum is:{0}", face_size);
                    for (int index = 0; index < face_size; index++)
                    {
//                    face_size = nir_size <= rgb_size?nir_size:rgb_size;
//                    // èŽ·å–çš„äººè„¸æ•°
//                    Console.WriteLine("faceNum is:{0}", face_size);
//                    for (int index = 0; index < face_size; index++)
//                    {
                        
                        IntPtr ptrBox = new IntPtr();
                        IntPtr ptrRGBScore = new IntPtr();
                        IntPtr ptrNIRScore = new IntPtr();
                        if (8 == IntPtr.Size)
                        {
                            ptrBox = (IntPtr)(ptTRGB.ToInt64() + sizeBox * index);
                            ptrRGBScore = (IntPtr)(ptSRGB.ToInt64() + sizeScore * index);
                            ptrNIRScore = (IntPtr)(ptSNIR.ToInt64() + sizeScore * index);
                        }
                        else if (4 == IntPtr.Size)
                        {
                            ptrBox = (IntPtr)(ptTRGB.ToInt32() + sizeBox * index);
                            ptrRGBScore = (IntPtr)(ptSRGB.ToInt32() + sizeScore * index);
                            ptrNIRScore = (IntPtr)(ptSNIR.ToInt32() + sizeScore * index);
                        }
//                        IntPtr ptrBox = new IntPtr();
//                        IntPtr ptrRGBScore = new IntPtr();
//                        IntPtr ptrNIRScore = new IntPtr();
//                        if (8 == IntPtr.Size)
//                        {
//                            ptrBox = (IntPtr)(ptTRGB.ToInt64() + sizeBox * index);
//                            ptrRGBScore = (IntPtr)(ptSRGB.ToInt64() + sizeScore * index);
//                            ptrNIRScore = (IntPtr)(ptSNIR.ToInt64() + sizeScore * index);
//                        }
//                        else if (4 == IntPtr.Size)
//                        {
//                            ptrBox = (IntPtr)(ptTRGB.ToInt32() + sizeBox * index);
//                            ptrRGBScore = (IntPtr)(ptSRGB.ToInt32() + sizeScore * index);
//                            ptrNIRScore = (IntPtr)(ptSNIR.ToInt32() + sizeScore * index);
//                        }
                        
                        rgb_box_info[index] = (BDFaceBBox)Marshal.PtrToStructure(ptrBox, typeof(BDFaceBBox));
//                        rgb_box_info[index] = (BDFaceBBox)Marshal.PtrToStructure(ptrBox, typeof(BDFaceBBox));
                        
                        rgb_score_info[index] = (BDLivenessScore)Marshal.PtrToStructure(ptrRGBScore, typeof(BDLivenessScore));
                        nir_score_info[index] = (BDLivenessScore)Marshal.PtrToStructure(ptrNIRScore, typeof(BDLivenessScore));
                        rgb_score = rgb_score_info[index].score;
                        ir_score = nir_score_info[index].score;
                        if (rgb_score <= 0.1f)
                        {
                            rgb_score = 0;
                        }
                        if (ir_score <= 0.1f)
                        {
                            ir_score = 0;
                        }
                        Console.WriteLine("demo ccccc");
                        // äººè„¸å®½åº¦
                        Console.WriteLine("mWidth is:{0:f}", rgb_box_info[index].width);
                        // ä¸­å¿ƒç‚¹X,Y坐标
                        Console.WriteLine("mCenter_x is:{0:f}", rgb_box_info[index].center_x);
                        Console.WriteLine("mCenter_y is:{0:f}", rgb_box_info[index].center_y);
//                        rgb_score_info[index] = (BDLivenessScore)Marshal.PtrToStructure(ptrRGBScore, typeof(BDLivenessScore));
//                        nir_score_info[index] = (BDLivenessScore)Marshal.PtrToStructure(ptrNIRScore, typeof(BDLivenessScore));
//                        rgb_score = rgb_score_info[index].score;
//                        ir_score = nir_score_info[index].score;
//                        if (rgb_score <= 0.1f)
//                        {
//                            rgb_score = 0;
//                        }
//                        if (ir_score <= 0.1f)
//                        {
//                            ir_score = 0;
//                        }
//                        Console.WriteLine("demo ccccc");
//                        // äººè„¸å®½åº¦
//                        Console.WriteLine("mWidth is:{0:f}", rgb_box_info[index].width);
//                        // ä¸­å¿ƒç‚¹X,Y坐标
//                        Console.WriteLine("mCenter_x is:{0:f}", rgb_box_info[index].center_x);
//                        Console.WriteLine("mCenter_y is:{0:f}", rgb_box_info[index].center_y);
                                          
                    }
//                    }
                    
                    string msg_depth = "ir score is:" + ir_score.ToString();
//                    string msg_depth = "ir score is:" + ir_score.ToString();
                   
                    Cv2.PutText(ir_mat, msg_depth, new Point(20, 50), HersheyFonts.HersheyComplex, 1, new Scalar(255, 100, 0));
//                    Cv2.PutText(ir_mat, msg_depth, new Point(20, 50), HersheyFonts.HersheyComplex, 1, new Scalar(255, 100, 0));
                   
                    string msg_rgb = "rgb score is:" + rgb_score.ToString();
                    Cv2.PutText(rgb_mat, msg_rgb, new Point(20, 50), HersheyFonts.HersheyComplex, 1, new Scalar(255, 100, 0));
                    if (face_size > 0)
                    {
                        // ç”»äººè„¸æ¡†
                        FaceDraw.draw_rects(ref rgb_mat, face_size, rgb_box_info);
                        // ç”»å…³é”®ç‚¹
                        // FaceDraw.draw_shape(ref rgb_mat, face_size, rgb_track_info);
                    }
                    window_rgb.ShowImage(rgb_mat);
                    window_ir.ShowImage(ir_mat);
                    Cv2.WaitKey(1);
                }
            }
            Marshal.FreeHGlobal(ptTRGB);
            Marshal.FreeHGlobal(ptTNIR);
            rgb_mat.Release();
            ir_mat.Release();
            frame1.Release();
            frame2.Release();
            Cv2.DestroyWindow("ir_face");
            Cv2.DestroyWindow("rgb_face");
            return true;
        }
        // åŒç›®æ‘„像头进行rgb,depth活体检测(此处适配了华杰艾米的双目摄像头)rgb和depth的分值都通过如0.8才算活体通过
        public bool rgb_depth_liveness_check_hjimi()
        {
            int max_face_num = 1;//取最大人脸的活体
//                    string msg_rgb = "rgb score is:" + rgb_score.ToString();
//                    Cv2.PutText(rgb_mat, msg_rgb, new Point(20, 50), HersheyFonts.HersheyComplex, 1, new Scalar(255, 100, 0));
//                    if (face_size > 0)
//                    {
//                        // ç”»äººè„¸æ¡†
//                        FaceDraw.draw_rects(ref rgb_mat, face_size, rgb_box_info);
//                        // ç”»å…³é”®ç‚¹
//                        // FaceDraw.draw_shape(ref rgb_mat, face_size, rgb_track_info);
//                    }
//                    window_rgb.ShowImage(rgb_mat);
//                    window_ir.ShowImage(ir_mat);
//                    Cv2.WaitKey(1);
//                }
//            }
//            Marshal.FreeHGlobal(ptTRGB);
//            Marshal.FreeHGlobal(ptTNIR);
//            rgb_mat.Release();
//            ir_mat.Release();
//            frame1.Release();
//            frame2.Release();
//            Cv2.DestroyWindow("ir_face");
//            Cv2.DestroyWindow("rgb_face");
//            return true;
//        }
//        // åŒç›®æ‘„像头进行rgb,depth活体检测(此处适配了华杰艾米的双目摄像头)rgb和depth的分值都通过如0.8才算活体通过
//        public bool rgb_depth_liveness_check_hjimi()
//        {
//            int max_face_num = 1;//取最大人脸的活体
          
            BDLivenessScore[] rgb_score_info = new BDLivenessScore[max_face_num];
            BDLivenessScore[] depth_score_info = new BDLivenessScore[max_face_num];
            int sizeScore = Marshal.SizeOf(typeof(BDLivenessScore));
            IntPtr ptRGBS = Marshal.AllocHGlobal(sizeScore * max_face_num);
            IntPtr ptDepthS = Marshal.AllocHGlobal(sizeScore * max_face_num);
//            BDLivenessScore[] rgb_score_info = new BDLivenessScore[max_face_num];
//            BDLivenessScore[] depth_score_info = new BDLivenessScore[max_face_num];
//            int sizeScore = Marshal.SizeOf(typeof(BDLivenessScore));
//            IntPtr ptRGBS = Marshal.AllocHGlobal(sizeScore * max_face_num);
//            IntPtr ptDepthS = Marshal.AllocHGlobal(sizeScore * max_face_num);
            BDFaceBBox[] box_info = new BDFaceBBox[max_face_num];
//            BDFaceBBox[] box_info = new BDFaceBBox[max_face_num];
           
            int sizeBox = Marshal.SizeOf(typeof(BDFaceBBox));
            IntPtr ptT = Marshal.AllocHGlobal(sizeBox * max_face_num);
            IntPtr phjimi = HjimiCamera.new_hjimi();
            var rgb_win = new Window("rgb", WindowMode.AutoSize);
            var depth_win = new Window("depth", WindowMode.Normal);
            float rgb_score = 0;
            float depth_score = 0;
            Mat cv_depth = new Mat();
            Mat cv_rgb = new Mat();
            while (true)
            {
                bool ok = HjimiCamera.open_hjimimat(phjimi, cv_rgb.CvPtr, cv_depth.CvPtr);
                if (!ok)
                {
                    depth_score = 0;
                    rgb_score = depth_score;
                    Console.WriteLine("open camera faile");
                    continue;
                }
                if(cv_rgb.Empty())
                {
                    continue;
                }
                if (cv_depth.Empty())
                {
                    continue;
                }
                // è¿”回人脸个数
                int face_size = rgb_depth_liveness(ptT, ptRGBS, ptDepthS, cv_rgb.CvPtr, cv_depth.CvPtr);
//            int sizeBox = Marshal.SizeOf(typeof(BDFaceBBox));
//            IntPtr ptT = Marshal.AllocHGlobal(sizeBox * max_face_num);
//            IntPtr phjimi = HjimiCamera.new_hjimi();
//            var rgb_win = new Window("rgb", WindowMode.AutoSize);
//            var depth_win = new Window("depth", WindowMode.Normal);
//            float rgb_score = 0;
//            float depth_score = 0;
//            Mat cv_depth = new Mat();
//            Mat cv_rgb = new Mat();
//            while (true)
//            {
//                bool ok = HjimiCamera.open_hjimimat(phjimi, cv_rgb.CvPtr, cv_depth.CvPtr);
//                if (!ok)
//                {
//                    depth_score = 0;
//                    rgb_score = depth_score;
//                    Console.WriteLine("open camera faile");
//                    continue;
//                }
//                if(cv_rgb.Empty())
//                {
//                    continue;
//                }
//                if (cv_depth.Empty())
//                {
//                    continue;
//                }
//                // è¿”回人脸个数
//                int face_size = rgb_depth_liveness(ptT, ptRGBS, ptDepthS, cv_rgb.CvPtr, cv_depth.CvPtr);
                
                Console.WriteLine("res is:{0}", face_size);
                depth_score = 0;
                rgb_score = depth_score;
                for (int index = 0; index < face_size; index++)
                {
                    IntPtr ptrBox = new IntPtr();
                    IntPtr ptrRGBScore = new IntPtr();
                    IntPtr ptrDepthScore = new IntPtr();
                    if (8 == IntPtr.Size)
                    {
                        ptrBox = (IntPtr)(ptT.ToInt64() + sizeBox * index);
                        ptrRGBScore = (IntPtr)(ptRGBS.ToInt64() + sizeScore * index);
                        ptrDepthScore = (IntPtr)(ptDepthS.ToInt64() + sizeScore * index);
                    }
                    else if (4 == IntPtr.Size)
                    {
                        ptrBox = (IntPtr)(ptT.ToInt32() + sizeBox * index);
                        ptrRGBScore = (IntPtr)(ptRGBS.ToInt32() + sizeScore * index);
                        ptrDepthScore = (IntPtr)(ptDepthS.ToInt32() + sizeScore * index);
                    }
//                Console.WriteLine("res is:{0}", face_size);
//                depth_score = 0;
//                rgb_score = depth_score;
//                for (int index = 0; index < face_size; index++)
//                {
//                    IntPtr ptrBox = new IntPtr();
//                    IntPtr ptrRGBScore = new IntPtr();
//                    IntPtr ptrDepthScore = new IntPtr();
//                    if (8 == IntPtr.Size)
//                    {
//                        ptrBox = (IntPtr)(ptT.ToInt64() + sizeBox * index);
//                        ptrRGBScore = (IntPtr)(ptRGBS.ToInt64() + sizeScore * index);
//                        ptrDepthScore = (IntPtr)(ptDepthS.ToInt64() + sizeScore * index);
//                    }
//                    else if (4 == IntPtr.Size)
//                    {
//                        ptrBox = (IntPtr)(ptT.ToInt32() + sizeBox * index);
//                        ptrRGBScore = (IntPtr)(ptRGBS.ToInt32() + sizeScore * index);
//                        ptrDepthScore = (IntPtr)(ptDepthS.ToInt32() + sizeScore * index);
//                    }
                    
                    box_info[index] = (BDFaceBBox)Marshal.PtrToStructure(ptrBox, typeof(BDFaceBBox));
//                    box_info[index] = (BDFaceBBox)Marshal.PtrToStructure(ptrBox, typeof(BDFaceBBox));
                    
                    rgb_score_info[index] = (BDLivenessScore)Marshal.PtrToStructure(ptrRGBScore, typeof(BDLivenessScore));
                    rgb_score = rgb_score_info[index].score;
                    depth_score_info[index] = (BDLivenessScore)Marshal.PtrToStructure(ptrDepthScore, typeof(BDLivenessScore));
                    depth_score = depth_score_info[index].score;
                    // åˆ†å€¼å¤ªä½Žï¼Œä¼šæ˜¾ç¤ºå°æ•°ç‚¹å¤ªé•¿ï¼Œç›´æŽ¥èµ‹å€¼0
                    if (depth_score <= 0.1f)
                    {
                        depth_score = 0;
                    }
                    if (rgb_score <= 0.1f)
                    {
                        rgb_score = 0;
                    }
                    // äººè„¸å®½åº¦
                    Console.WriteLine("mWidth is:{0:f}", box_info[index].width);
                    // ä¸­å¿ƒç‚¹X,Y坐标
                    Console.WriteLine("mCenter_x is:{0:f}", box_info[index].center_x);
                    Console.WriteLine("mCenter_y is:{0:f}", box_info[index].center_y);
//                    rgb_score_info[index] = (BDLivenessScore)Marshal.PtrToStructure(ptrRGBScore, typeof(BDLivenessScore));
//                    rgb_score = rgb_score_info[index].score;
//                    depth_score_info[index] = (BDLivenessScore)Marshal.PtrToStructure(ptrDepthScore, typeof(BDLivenessScore));
//                    depth_score = depth_score_info[index].score;
//                    // åˆ†å€¼å¤ªä½Žï¼Œä¼šæ˜¾ç¤ºå°æ•°ç‚¹å¤ªé•¿ï¼Œç›´æŽ¥èµ‹å€¼0
//                    if (depth_score <= 0.1f)
//                    {
//                        depth_score = 0;
//                    }
//                    if (rgb_score <= 0.1f)
//                    {
//                        rgb_score = 0;
//                    }
//                    // äººè„¸å®½åº¦
//                    Console.WriteLine("mWidth is:{0:f}", box_info[index].width);
//                    // ä¸­å¿ƒç‚¹X,Y坐标
//                    Console.WriteLine("mCenter_x is:{0:f}", box_info[index].center_x);
//                    Console.WriteLine("mCenter_y is:{0:f}", box_info[index].center_y);
                   
                }
//                }
              
                Mat depth_img = new Mat();
                cv_depth.ConvertTo(depth_img, MatType.CV_8UC1, 255.0 / 4500);
                string msg_depth = "depth score is:" + depth_score.ToString();
                Cv2.PutText(depth_img, msg_depth, new Point(20, 50), HersheyFonts.HersheyComplex, 1, new Scalar(255, 100, 0));
//                Mat depth_img = new Mat();
//                cv_depth.ConvertTo(depth_img, MatType.CV_8UC1, 255.0 / 4500);
//                string msg_depth = "depth score is:" + depth_score.ToString();
//                Cv2.PutText(depth_img, msg_depth, new Point(20, 50), HersheyFonts.HersheyComplex, 1, new Scalar(255, 100, 0));
                string msg_rgb = "rgb score is:" + rgb_score.ToString();
                Cv2.PutText(cv_rgb, msg_rgb, new Point(20, 50), HersheyFonts.HersheyComplex, 1, new Scalar(255, 100, 0));
                if (face_size > 0)
                {
                    // ç”»äººè„¸æ¡†
                    FaceDraw.draw_rects(ref cv_rgb, face_size, box_info);
//                string msg_rgb = "rgb score is:" + rgb_score.ToString();
//                Cv2.PutText(cv_rgb, msg_rgb, new Point(20, 50), HersheyFonts.HersheyComplex, 1, new Scalar(255, 100, 0));
//                if (face_size > 0)
//                {
//                    // ç”»äººè„¸æ¡†
//                    FaceDraw.draw_rects(ref cv_rgb, face_size, box_info);
                    
                }
//                }
                
                rgb_win.ShowImage(cv_rgb);
                depth_win.ShowImage(depth_img);
                Cv2.WaitKey(1);
                depth_img.Release();
            }
            Marshal.FreeHGlobal(ptT);
            cv_rgb.Release();
            cv_depth.Release();
            Cv2.DestroyWindow("rgb");
            Cv2.DestroyWindow("depth");
            HjimiCamera.hjimi_release(phjimi);
            return true;
        }
        //双目RGB和DEPTH静默活体检测(传入opencv视频帧)适配奥比中光海燕等双目摄像头
        public bool rgb_depth_liveness_check_orbe()
        {
            int max_face_num = 1;//取最大人脸的活体
//                rgb_win.ShowImage(cv_rgb);
//                depth_win.ShowImage(depth_img);
//                Cv2.WaitKey(1);
//                depth_img.Release();
//            }
//            Marshal.FreeHGlobal(ptT);
//            cv_rgb.Release();
//            cv_depth.Release();
//            Cv2.DestroyWindow("rgb");
//            Cv2.DestroyWindow("depth");
//            HjimiCamera.hjimi_release(phjimi);
//            return true;
//        }
//        //双目RGB和DEPTH静默活体检测(传入opencv视频帧)适配奥比中光海燕等双目摄像头
//        public bool rgb_depth_liveness_check_orbe()
//        {
//            int max_face_num = 1;//取最大人脸的活体
            BDLivenessScore[] rgb_score_info = new BDLivenessScore[max_face_num];
            BDLivenessScore[] depth_score_info = new BDLivenessScore[max_face_num];
            int sizeScore = Marshal.SizeOf(typeof(BDLivenessScore));
            IntPtr ptRGBS = Marshal.AllocHGlobal(sizeScore * max_face_num);
            IntPtr ptDepthS = Marshal.AllocHGlobal(sizeScore * max_face_num);
//            BDLivenessScore[] rgb_score_info = new BDLivenessScore[max_face_num];
//            BDLivenessScore[] depth_score_info = new BDLivenessScore[max_face_num];
//            int sizeScore = Marshal.SizeOf(typeof(BDLivenessScore));
//            IntPtr ptRGBS = Marshal.AllocHGlobal(sizeScore * max_face_num);
//            IntPtr ptDepthS = Marshal.AllocHGlobal(sizeScore * max_face_num);
            BDFaceBBox[] box_info = new BDFaceBBox[max_face_num];
//            BDFaceBBox[] box_info = new BDFaceBBox[max_face_num];
            
            int sizeBox = Marshal.SizeOf(typeof(BDFaceTrackInfo));
            IntPtr ptT = Marshal.AllocHGlobal(sizeBox * max_face_num);
//            int sizeBox = Marshal.SizeOf(typeof(BDFaceTrackInfo));
//            IntPtr ptT = Marshal.AllocHGlobal(sizeBox * max_face_num);
            IntPtr porbe = OrbeCamera.new_orbe();
            var rgb_win = new Window("rgb", WindowMode.AutoSize);
            var depth_win = new Window("depth", WindowMode.Normal);
            float rgb_score = 0;
            float depth_score = 0;
            Mat cv_depth = new Mat();
            Mat cv_rgb = new Mat();
            while (true)
            {
                int res_ok = OrbeCamera.open_orbe(porbe, cv_rgb.CvPtr, cv_depth.CvPtr);
                if (res_ok != 0)
                {
                    depth_score = 0;
                    rgb_score = depth_score;
                    Console.WriteLine("open camera faile");
                    continue;
                }
                if (cv_rgb.Empty())
                {
                    continue;
                }
                if (cv_depth.Empty())
                {
                    continue;
                }
                // è¿”回人脸个数
                int face_size = rgb_depth_liveness(ptT, ptRGBS, ptDepthS, cv_rgb.CvPtr, cv_depth.CvPtr);
//            IntPtr porbe = OrbeCamera.new_orbe();
//            var rgb_win = new Window("rgb", WindowMode.AutoSize);
//            var depth_win = new Window("depth", WindowMode.Normal);
//            float rgb_score = 0;
//            float depth_score = 0;
//            Mat cv_depth = new Mat();
//            Mat cv_rgb = new Mat();
//            while (true)
//            {
//                int res_ok = OrbeCamera.open_orbe(porbe, cv_rgb.CvPtr, cv_depth.CvPtr);
//                if (res_ok != 0)
//                {
//                    depth_score = 0;
//                    rgb_score = depth_score;
//                    Console.WriteLine("open camera faile");
//                    continue;
//                }
//                if (cv_rgb.Empty())
//                {
//                    continue;
//                }
//                if (cv_depth.Empty())
//                {
//                    continue;
//                }
//                // è¿”回人脸个数
//                int face_size = rgb_depth_liveness(ptT, ptRGBS, ptDepthS, cv_rgb.CvPtr, cv_depth.CvPtr);
                Console.WriteLine("res is:{0}", face_size);
                depth_score = 0;
                rgb_score = depth_score;
                for (int index = 0; index < face_size; index++)
                {
                    IntPtr ptrBox = new IntPtr();
                    IntPtr ptrRGBScore = new IntPtr();
                    IntPtr ptrDepthScore = new IntPtr();
                    if (8 == IntPtr.Size)
                    {
                        ptrBox = (IntPtr)(ptT.ToInt64() + sizeBox * index);
                        ptrRGBScore = (IntPtr)(ptRGBS.ToInt64() + sizeScore * index);
                        ptrDepthScore = (IntPtr)(ptDepthS.ToInt64() + sizeScore * index);
                    }
                    else if (4 == IntPtr.Size)
                    {
                        ptrBox = (IntPtr)(ptT.ToInt32() + sizeBox * index);
                        ptrRGBScore = (IntPtr)(ptRGBS.ToInt32() + sizeScore * index);
                        ptrDepthScore = (IntPtr)(ptDepthS.ToInt32() + sizeScore * index);
                    }
//                Console.WriteLine("res is:{0}", face_size);
//                depth_score = 0;
//                rgb_score = depth_score;
//                for (int index = 0; index < face_size; index++)
//                {
//                    IntPtr ptrBox = new IntPtr();
//                    IntPtr ptrRGBScore = new IntPtr();
//                    IntPtr ptrDepthScore = new IntPtr();
//                    if (8 == IntPtr.Size)
//                    {
//                        ptrBox = (IntPtr)(ptT.ToInt64() + sizeBox * index);
//                        ptrRGBScore = (IntPtr)(ptRGBS.ToInt64() + sizeScore * index);
//                        ptrDepthScore = (IntPtr)(ptDepthS.ToInt64() + sizeScore * index);
//                    }
//                    else if (4 == IntPtr.Size)
//                    {
//                        ptrBox = (IntPtr)(ptT.ToInt32() + sizeBox * index);
//                        ptrRGBScore = (IntPtr)(ptRGBS.ToInt32() + sizeScore * index);
//                        ptrDepthScore = (IntPtr)(ptDepthS.ToInt32() + sizeScore * index);
//                    }
                    box_info[index] = (BDFaceBBox)Marshal.PtrToStructure(ptrBox, typeof(BDFaceBBox));
//                    box_info[index] = (BDFaceBBox)Marshal.PtrToStructure(ptrBox, typeof(BDFaceBBox));
                    rgb_score_info[index] = (BDLivenessScore)Marshal.PtrToStructure(ptrRGBScore, typeof(BDLivenessScore));
                    rgb_score = rgb_score_info[index].score;
                    depth_score_info[index] = (BDLivenessScore)Marshal.PtrToStructure(ptrDepthScore, typeof(BDLivenessScore));
                    depth_score = depth_score_info[index].score;
                    // åˆ†å€¼å¤ªä½Žï¼Œä¼šæ˜¾ç¤ºå°æ•°ç‚¹å¤ªé•¿ï¼Œç›´æŽ¥èµ‹å€¼0
                    if (depth_score <= 0.1f)
                    {
                        depth_score = 0;
                    }
                    if (rgb_score <= 0.1f)
                    {
                        rgb_score = 0;
                    }
                    // äººè„¸å®½åº¦
                    Console.WriteLine("mWidth is:{0:f}", box_info[index].width);
                    // ä¸­å¿ƒç‚¹X,Y坐标
                    Console.WriteLine("mCenter_x is:{0:f}", box_info[index].center_x);
                    Console.WriteLine("mCenter_y is:{0:f}", box_info[index].center_y);
//                    rgb_score_info[index] = (BDLivenessScore)Marshal.PtrToStructure(ptrRGBScore, typeof(BDLivenessScore));
//                    rgb_score = rgb_score_info[index].score;
//                    depth_score_info[index] = (BDLivenessScore)Marshal.PtrToStructure(ptrDepthScore, typeof(BDLivenessScore));
//                    depth_score = depth_score_info[index].score;
//                    // åˆ†å€¼å¤ªä½Žï¼Œä¼šæ˜¾ç¤ºå°æ•°ç‚¹å¤ªé•¿ï¼Œç›´æŽ¥èµ‹å€¼0
//                    if (depth_score <= 0.1f)
//                    {
//                        depth_score = 0;
//                    }
//                    if (rgb_score <= 0.1f)
//                    {
//                        rgb_score = 0;
//                    }
//                    // äººè„¸å®½åº¦
//                    Console.WriteLine("mWidth is:{0:f}", box_info[index].width);
//                    // ä¸­å¿ƒç‚¹X,Y坐标
//                    Console.WriteLine("mCenter_x is:{0:f}", box_info[index].center_x);
//                    Console.WriteLine("mCenter_y is:{0:f}", box_info[index].center_y);
                }
//                }
                Mat depth_img = new Mat();
                cv_depth.ConvertTo(depth_img, MatType.CV_8UC1, 255.0 / 4500);
                string msg_depth = "depth score is:" + depth_score.ToString();
                Cv2.PutText(depth_img, msg_depth, new Point(20, 50), HersheyFonts.HersheyComplex, 1, new Scalar(255, 100, 0));
//                Mat depth_img = new Mat();
//                cv_depth.ConvertTo(depth_img, MatType.CV_8UC1, 255.0 / 4500);
//                string msg_depth = "depth score is:" + depth_score.ToString();
//                Cv2.PutText(depth_img, msg_depth, new Point(20, 50), HersheyFonts.HersheyComplex, 1, new Scalar(255, 100, 0));
                string msg_rgb = "rgb score is:" + rgb_score.ToString();
                Cv2.PutText(cv_rgb, msg_rgb, new Point(20, 50), HersheyFonts.HersheyComplex, 1, new Scalar(255, 100, 0));
                if (face_size > 0)
                {
                    // ç”»äººè„¸æ¡†
                    FaceDraw.draw_rects(ref cv_rgb, face_size, box_info);
                }
                rgb_win.ShowImage(cv_rgb);
                depth_win.ShowImage(depth_img);
                Cv2.WaitKey(1);
                depth_img.Release();
            }
            Marshal.FreeHGlobal(ptT);
            cv_rgb.Release();
            cv_depth.Release();
            Cv2.DestroyWindow("rgb");
            Cv2.DestroyWindow("depth");
            OrbeCamera.orbe_release(porbe);
            return true;
        }
//                string msg_rgb = "rgb score is:" + rgb_score.ToString();
//                Cv2.PutText(cv_rgb, msg_rgb, new Point(20, 50), HersheyFonts.HersheyComplex, 1, new Scalar(255, 100, 0));
//                if (face_size > 0)
//                {
//                    // ç”»äººè„¸æ¡†
//                    FaceDraw.draw_rects(ref cv_rgb, face_size, box_info);
//                }
//                rgb_win.ShowImage(cv_rgb);
//                depth_win.ShowImage(depth_img);
//                Cv2.WaitKey(1);
//                depth_img.Release();
//            }
//            Marshal.FreeHGlobal(ptT);
//            cv_rgb.Release();
//            cv_depth.Release();
//            Cv2.DestroyWindow("rgb");
//            Cv2.DestroyWindow("depth");
//            OrbeCamera.orbe_release(porbe);
//            return true;
//        }
             
        public void test_rgb_ir_liveness_check_by_opencv()
        {
            rgb_ir_liveness_check_mat();
        }
//        public void test_rgb_ir_liveness_check_by_opencv()
//        {
//            rgb_ir_liveness_check_mat();
//        }
        // åŒç›®RGB和DEPTH静默活体检测,适配奥比中光海燕等双目摄像头
        public void test_rgb_depth_liveness_check_by_orbe()
        {
            rgb_depth_liveness_check_orbe();
        }
//        // åŒç›®RGB和DEPTH静默活体检测,适配奥比中光海燕等双目摄像头
//        public void test_rgb_depth_liveness_check_by_orbe()
//        {
//            rgb_depth_liveness_check_orbe();
//        }
      
        // åŒç›®æ‘„像头进行rgb,depth活体检测(此处适配了华杰艾米的双目摄像头)
        public void test_rgb_depth_liveness_check_by_hjimi()
        {
            rgb_depth_liveness_check_hjimi();
        }
    }
}
//        // åŒç›®æ‘„像头进行rgb,depth活体检测(此处适配了华杰艾米的双目摄像头)
//        public void test_rgb_depth_liveness_check_by_hjimi()
//        {
//            rgb_depth_liveness_check_hjimi();
//        }
//    }
//}
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/FaceAI/FaceManager.cs
@@ -1,209 +1,209 @@
using OpenCvSharp;
using System;
using System.Runtime.InteropServices;
/**
 *  å¤‡æ³¨ï¼ˆäººè„¸æ•°æ®åº“管理说明):
 *  äººè„¸æ•°æ®åº“为采用sqlite3的数据库,会自动生成一个db目录夹,下面有数据库face.db文件保存数据库
 *  å¯ç”¨sqliteExpert之类的可视化工具打开查看,亦可用命令行,方法请自行百度。
 *  è¯¥æ•°æ®åº“仅仅可适应于5w人左右的人脸库,且设计表格等属于小型通用化。
 *  è‹¥ä¸èƒ½æ»¡è¶³å®¢æˆ·ä¸ªæ€§åŒ–需求,客户可自行设计数据库保存数据。宗旨就是每个人脸图片提取一个特征值保存。
 *  äººè„¸1:1,1:N比对及识别实际就是特征值的比对。1:1只要提取2张不同的图片特征值调用compare_feature比对。
 *  1:N是提取一个特征值和数据库中已保存的N个特征值一一比对(比对速度很快,不用担心效率问题),
 *  æœ€ç»ˆå–分数高的值为最高相似度。
 *  ç›¸ä¼¼åº¦è¯†åˆ«çš„分数可自行测试根据实验结果拟定,一般推荐相似度大于80分为同一人。
 *
 */
namespace FaceAI
{
    class FaceManager
    {
        // äººè„¸æ³¨å†Œ(传特征值,特征值可参考FaceFeature.cs提取,亦可参考FaceCompare.cs查看特征值的比对)
        [DllImport("BaiduFaceApi.dll", EntryPoint = "user_add", CharSet = CharSet.Ansi
            , CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr user_add(ref BDFaceFeature f1, string user_id, string group_id,
            string user_info="");
//using OpenCvSharp;
//using System;
//using System.Runtime.InteropServices;
///**
// *  å¤‡æ³¨ï¼ˆäººè„¸æ•°æ®åº“管理说明):
// *  äººè„¸æ•°æ®åº“为采用sqlite3的数据库,会自动生成一个db目录夹,下面有数据库face.db文件保存数据库
// *  å¯ç”¨sqliteExpert之类的可视化工具打开查看,亦可用命令行,方法请自行百度。
// *  è¯¥æ•°æ®åº“仅仅可适应于5w人左右的人脸库,且设计表格等属于小型通用化。
// *  è‹¥ä¸èƒ½æ»¡è¶³å®¢æˆ·ä¸ªæ€§åŒ–需求,客户可自行设计数据库保存数据。宗旨就是每个人脸图片提取一个特征值保存。
// *  äººè„¸1:1,1:N比对及识别实际就是特征值的比对。1:1只要提取2张不同的图片特征值调用compare_feature比对。
// *  1:N是提取一个特征值和数据库中已保存的N个特征值一一比对(比对速度很快,不用担心效率问题),
// *  æœ€ç»ˆå–分数高的值为最高相似度。
// *  ç›¸ä¼¼åº¦è¯†åˆ«çš„分数可自行测试根据实验结果拟定,一般推荐相似度大于80分为同一人。
// *
// */
//namespace FaceAI
//{
//    class FaceManager
//    {
//        // äººè„¸æ³¨å†Œ(传特征值,特征值可参考FaceFeature.cs提取,亦可参考FaceCompare.cs查看特征值的比对)
//        [DllImport("BaiduFaceApi.dll", EntryPoint = "user_add", CharSet = CharSet.Ansi
//            , CallingConvention = CallingConvention.Cdecl)]
//        public static extern IntPtr user_add(ref BDFaceFeature f1, string user_id, string group_id,
//            string user_info="");
        // äººè„¸æ³¨å†Œ(ä¼ opencv图片帧,特征值可参考FaceFeature.cs提取,亦可参考FaceCompare.cs查看特征值的比对)
        [DllImport("BaiduFaceApi.dll", EntryPoint = "user_add_by_mat", CharSet = CharSet.Ansi
            , CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr user_add_by_mat(IntPtr mat, string user_id, string group_id,
            string user_info = "");
//        // äººè„¸æ³¨å†Œ(ä¼ opencv图片帧,特征值可参考FaceFeature.cs提取,亦可参考FaceCompare.cs查看特征值的比对)
//        [DllImport("BaiduFaceApi.dll", EntryPoint = "user_add_by_mat", CharSet = CharSet.Ansi
//            , CallingConvention = CallingConvention.Cdecl)]
//        public static extern IntPtr user_add_by_mat(IntPtr mat, string user_id, string group_id,
//            string user_info = "");
        // äººè„¸æ›´æ–°(传图片帧)
        [DllImport("BaiduFaceApi.dll", EntryPoint = "user_update", CharSet = CharSet.Ansi
            , CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr user_update(IntPtr mat, string user_id, string group_id,
            string user_info = "");
//        // äººè„¸æ›´æ–°(传图片帧)
//        [DllImport("BaiduFaceApi.dll", EntryPoint = "user_update", CharSet = CharSet.Ansi
//            , CallingConvention = CallingConvention.Cdecl)]
//        public static extern IntPtr user_update(IntPtr mat, string user_id, string group_id,
//            string user_info = "");
      
        // ç”¨æˆ·åˆ é™¤
        [DllImport("BaiduFaceApi.dll", EntryPoint = "user_delete", CharSet = CharSet.Ansi
           , CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr user_delete(string user_id, string group_id);
        // ç»„添加
        [DllImport("BaiduFaceApi.dll", EntryPoint = "group_add", CharSet = CharSet.Ansi
           , CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr group_add(string group_id);
        // ç»„删除
        [DllImport("BaiduFaceApi.dll", EntryPoint = "group_delete", CharSet = CharSet.Ansi
           , CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr group_delete(string group_id);
        // æŸ¥è¯¢ç”¨æˆ·ä¿¡æ¯
        [DllImport("BaiduFaceApi.dll", EntryPoint = "get_user_info", CharSet = CharSet.Ansi
           , CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr get_user_info(string user_id, string group_id);
//        // ç”¨æˆ·åˆ é™¤
//        [DllImport("BaiduFaceApi.dll", EntryPoint = "user_delete", CharSet = CharSet.Ansi
//           , CallingConvention = CallingConvention.Cdecl)]
//        public static extern IntPtr user_delete(string user_id, string group_id);
//        // ç»„添加
//        [DllImport("BaiduFaceApi.dll", EntryPoint = "group_add", CharSet = CharSet.Ansi
//           , CallingConvention = CallingConvention.Cdecl)]
//        public static extern IntPtr group_add(string group_id);
//        // ç»„删除
//        [DllImport("BaiduFaceApi.dll", EntryPoint = "group_delete", CharSet = CharSet.Ansi
//           , CallingConvention = CallingConvention.Cdecl)]
//        public static extern IntPtr group_delete(string group_id);
//        // æŸ¥è¯¢ç”¨æˆ·ä¿¡æ¯
//        [DllImport("BaiduFaceApi.dll", EntryPoint = "get_user_info", CharSet = CharSet.Ansi
//           , CallingConvention = CallingConvention.Cdecl)]
//        public static extern IntPtr get_user_info(string user_id, string group_id);
        // æŸ¥è¯¢ç”¨æˆ·å›¾ç‰‡
        [DllImport("BaiduFaceApi.dll", EntryPoint = "get_user_image", CharSet = CharSet.Ansi
           , CallingConvention = CallingConvention.Cdecl)]
        public static extern int get_user_image(IntPtr out_mat, string user_id, string group_id);
//        // æŸ¥è¯¢ç”¨æˆ·å›¾ç‰‡
//        [DllImport("BaiduFaceApi.dll", EntryPoint = "get_user_image", CharSet = CharSet.Ansi
//           , CallingConvention = CallingConvention.Cdecl)]
//        public static extern int get_user_image(IntPtr out_mat, string user_id, string group_id);
        // ç”¨æˆ·ç»„列表查询
        [DllImport("BaiduFaceApi.dll", EntryPoint = "get_user_list", CharSet = CharSet.Ansi
           , CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr get_user_list(string group_id, int start = 0, int length = 100);
        // ç»„列表查询
        [DllImport("BaiduFaceApi.dll", EntryPoint = "get_group_list", CharSet = CharSet.Ansi
           , CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr get_group_list(int start = 0, int length = 100);
//        // ç”¨æˆ·ç»„列表查询
//        [DllImport("BaiduFaceApi.dll", EntryPoint = "get_user_list", CharSet = CharSet.Ansi
//           , CallingConvention = CallingConvention.Cdecl)]
//        public static extern IntPtr get_user_list(string group_id, int start = 0, int length = 100);
//        // ç»„列表查询
//        [DllImport("BaiduFaceApi.dll", EntryPoint = "get_group_list", CharSet = CharSet.Ansi
//           , CallingConvention = CallingConvention.Cdecl)]
//        public static extern IntPtr get_group_list(int start = 0, int length = 100);
        // æ•°æ®åº“人脸数量查询
        [DllImport("BaiduFaceApi.dll", EntryPoint = "db_face_count", CharSet = CharSet.Ansi
           , CallingConvention = CallingConvention.Cdecl)]
        public static extern int db_face_count(string group_id);
//        // æ•°æ®åº“人脸数量查询
//        [DllImport("BaiduFaceApi.dll", EntryPoint = "db_face_count", CharSet = CharSet.Ansi
//           , CallingConvention = CallingConvention.Cdecl)]
//        public static extern int db_face_count(string group_id);
        // æµ‹è¯•人脸注册
        public void test_user_add()
        {
            // äººè„¸æ³¨å†Œ
            string user_id = "test_user";
            string group_id = "test_group";
            string file_name = "../images/1.jpg";
//        // æµ‹è¯•人脸注册
//        public void test_user_add()
//        {
//            // äººè„¸æ³¨å†Œ
//            string user_id = "test_user";
//            string group_id = "test_group";
//            string file_name = "../images/1.jpg";
           
            string user_info = "user_info";
            // æå–人脸特征值数组(多人会提取多个人的特征值)
/*
            FaceFeature feature = new FaceFeature();
            BDFaceFeature[] feaList1 = feature.test_get_face_feature_by_path(file_name
            if (feaList1 == null)
            {
                Console.WriteLine("get feature fail");
                return;
            }
            // å‡è®¾æµ‹è¯•的图片是1个人,
            BDFaceFeature f1 = feaList1[0];
            // äººè„¸æ³¨å†Œ (传特征值人脸注册,该方法注册不保存人脸图片入库)
            IntPtr ptr = user_add(ref f1, user_id, group_id, user_info);
            string buf = Marshal.PtrToStringAnsi(ptr);
            Console.WriteLine("user_add res is:" + buf);
*/
            // é€šè¿‡å›¾ç‰‡å¸§äººè„¸æ³¨å†Œï¼ˆåªæœ‰è¯¥æ–¹æ³•进行的人脸注册,人脸库才会保存人脸图片)
            Mat mat = Cv2.ImRead(file_name);
            IntPtr mptr = user_add_by_mat(mat.CvPtr, user_id, group_id, user_info);
            string mbuf = Marshal.PtrToStringAnsi(mptr);
            Console.WriteLine("user_add_by_mat res is:" + mbuf);
        }
//            string user_info = "user_info";
//            // æå–人脸特征值数组(多人会提取多个人的特征值)
///*
//            FaceFeature feature = new FaceFeature();
//            BDFaceFeature[] feaList1 = feature.test_get_face_feature_by_path(file_name
//            if (feaList1 == null)
//            {
//                Console.WriteLine("get feature fail");
//                return;
//            }
//            // å‡è®¾æµ‹è¯•的图片是1个人,
//            BDFaceFeature f1 = feaList1[0];
//            // äººè„¸æ³¨å†Œ (传特征值人脸注册,该方法注册不保存人脸图片入库)
//            IntPtr ptr = user_add(ref f1, user_id, group_id, user_info);
//            string buf = Marshal.PtrToStringAnsi(ptr);
//            Console.WriteLine("user_add res is:" + buf);
//*/
//            // é€šè¿‡å›¾ç‰‡å¸§äººè„¸æ³¨å†Œï¼ˆåªæœ‰è¯¥æ–¹æ³•进行的人脸注册,人脸库才会保存人脸图片)
//            Mat mat = Cv2.ImRead(file_name);
//            IntPtr mptr = user_add_by_mat(mat.CvPtr, user_id, group_id, user_info);
//            string mbuf = Marshal.PtrToStringAnsi(mptr);
//            Console.WriteLine("user_add_by_mat res is:" + mbuf);
//        }
      
        // æµ‹è¯•人脸更新
        public void test_user_update()
        {
            string user_id = "test_user";
            string group_id = "test_group";
            string file_name = "../images/1.jpg";
            Mat mat = Cv2.ImRead(file_name);
            string user_info = "user_info";
            // äººè„¸æ›´æ–°
            IntPtr ptr = user_update(mat.CvPtr, user_id, group_id, user_info);
            string buf = Marshal.PtrToStringAnsi(ptr);
            Console.WriteLine("user_update res is:" + buf);
        }
//        // æµ‹è¯•人脸更新
//        public void test_user_update()
//        {
//            string user_id = "test_user";
//            string group_id = "test_group";
//            string file_name = "../images/1.jpg";
//            Mat mat = Cv2.ImRead(file_name);
//            string user_info = "user_info";
//            // äººè„¸æ›´æ–°
//            IntPtr ptr = user_update(mat.CvPtr, user_id, group_id, user_info);
//            string buf = Marshal.PtrToStringAnsi(ptr);
//            Console.WriteLine("user_update res is:" + buf);
//        }
        // æµ‹è¯•用户删除 ï¼ˆç”¨æˆ·åˆ é™¤åŽï¼Œäººè„¸æ•°æ®ä¹Ÿè¢«åˆ é™¤ï¼‰
        public void test_user_delete()
        {
            string user_id = "test_user";
            string group_id = "test_group";
            IntPtr ptr = user_delete(user_id, group_id);
            string buf = Marshal.PtrToStringAnsi(ptr);
            Console.WriteLine("user_delete res is:" + buf);
        }
//        // æµ‹è¯•用户删除 ï¼ˆç”¨æˆ·åˆ é™¤åŽï¼Œäººè„¸æ•°æ®ä¹Ÿè¢«åˆ é™¤ï¼‰
//        public void test_user_delete()
//        {
//            string user_id = "test_user";
//            string group_id = "test_group";
//            IntPtr ptr = user_delete(user_id, group_id);
//            string buf = Marshal.PtrToStringAnsi(ptr);
//            Console.WriteLine("user_delete res is:" + buf);
//        }
        // ç»„添加
        public void test_group_add()
        {
            string group_id = "test_group2";
            IntPtr ptr = group_add(group_id);
            string buf = Marshal.PtrToStringAnsi(ptr);
            Console.WriteLine("group_add res is:" + buf);
        }
//        // ç»„添加
//        public void test_group_add()
//        {
//            string group_id = "test_group2";
//            IntPtr ptr = group_add(group_id);
//            string buf = Marshal.PtrToStringAnsi(ptr);
//            Console.WriteLine("group_add res is:" + buf);
//        }
        // ç»„删除
        public void test_group_delete()
        {
            string group_id = "test_group2";
            IntPtr ptr = group_delete(group_id);
            string buf = Marshal.PtrToStringAnsi(ptr);
            Console.WriteLine("group_delete res is:" + buf);
        }
//        // ç»„删除
//        public void test_group_delete()
//        {
//            string group_id = "test_group2";
//            IntPtr ptr = group_delete(group_id);
//            string buf = Marshal.PtrToStringAnsi(ptr);
//            Console.WriteLine("group_delete res is:" + buf);
//        }
        // æŸ¥è¯¢ç”¨æˆ·ä¿¡æ¯
        public void test_get_user_info()
        {
            string user_id = "test_user";
            string group_id = "test_group";
            IntPtr ptr = get_user_info(user_id , group_id);
            string buf = Marshal.PtrToStringAnsi(ptr);
            Console.WriteLine("get_user_info res is:" + buf);
        }
//        // æŸ¥è¯¢ç”¨æˆ·ä¿¡æ¯
//        public void test_get_user_info()
//        {
//            string user_id = "test_user";
//            string group_id = "test_group";
//            IntPtr ptr = get_user_info(user_id , group_id);
//            string buf = Marshal.PtrToStringAnsi(ptr);
//            Console.WriteLine("get_user_info res is:" + buf);
//        }
        // æŸ¥è¯¢ç”¨æˆ·å›¾ç‰‡
        public void test_get_user_image()
        {
            string user_id = "test_user";
            string group_id = "test_group";
            Mat out_mat = new Mat();
            int res = get_user_image(out_mat.CvPtr, user_id, group_id);
            if (res == 0)
            {
                Console.WriteLine("get_user_image success");
                // å›¾ç‰‡ä¿å­˜åˆ°æœ¬åœ°
                out_mat.ImWrite("user.jpg");
            }
            else
            {
                Console.WriteLine("get_user_image error{0}:", res);
            }
//        // æŸ¥è¯¢ç”¨æˆ·å›¾ç‰‡
//        public void test_get_user_image()
//        {
//            string user_id = "test_user";
//            string group_id = "test_group";
//            Mat out_mat = new Mat();
//            int res = get_user_image(out_mat.CvPtr, user_id, group_id);
//            if (res == 0)
//            {
//                Console.WriteLine("get_user_image success");
//                // å›¾ç‰‡ä¿å­˜åˆ°æœ¬åœ°
//                out_mat.ImWrite("user.jpg");
//            }
//            else
//            {
//                Console.WriteLine("get_user_image error{0}:", res);
//            }
          
        }
//        }
        // ç”¨æˆ·ç»„列表查询
        public void test_get_user_list()
        {
            string group_id = "test_group";
            IntPtr ptr = get_user_list(group_id);
            string buf = Marshal.PtrToStringAnsi(ptr);
            Console.WriteLine("get_user_list res is:" + buf);
        }
//        // ç”¨æˆ·ç»„列表查询
//        public void test_get_user_list()
//        {
//            string group_id = "test_group";
//            IntPtr ptr = get_user_list(group_id);
//            string buf = Marshal.PtrToStringAnsi(ptr);
//            Console.WriteLine("get_user_list res is:" + buf);
//        }
        // ç»„列表查询
        public void test_get_group_list()
        {
            IntPtr ptr = get_group_list();
            string buf = Marshal.PtrToStringAnsi(ptr);
            Console.WriteLine("get_group_list res is:" + buf);
        }
//        // ç»„列表查询
//        public void test_get_group_list()
//        {
//            IntPtr ptr = get_group_list();
//            string buf = Marshal.PtrToStringAnsi(ptr);
//            Console.WriteLine("get_group_list res is:" + buf);
//        }
        // äººè„¸åº“数量查询
        public void test_db_face_count()
        {
            string group_id = "test_group";
            // å‚数传组id表示查该组都人脸数量
            int count = db_face_count(group_id);
            Console.WriteLine("count  is:" + count);
            string group_id2 = null;
            // å‚æ•°ä¼ null表示查整个库
            int count2 = db_face_count(group_id2);
            Console.WriteLine("all count is:" + count2);
        }
    }
}
//        // äººè„¸åº“数量查询
//        public void test_db_face_count()
//        {
//            string group_id = "test_group";
//            // å‚数传组id表示查该组都人脸数量
//            int count = db_face_count(group_id);
//            Console.WriteLine("count  is:" + count);
//            string group_id2 = null;
//            // å‚æ•°ä¼ null表示查整个库
//            int count2 = db_face_count(group_id2);
//            Console.WriteLine("all count is:" + count2);
//        }
//    }
//}
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/FaceAI/FaceTrack.cs
@@ -1,221 +1,221 @@
using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using OpenCvSharp;
//using System;
//using System.Runtime.InteropServices;
//using System.Collections.Generic;
//using OpenCvSharp;
// äººè„¸è·Ÿè¸ª
namespace FaceAI
{
    // äººè„¸è·Ÿè¸ªé…ç½®ç»“构体
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    struct BDFaceTrackConf
    {
        public float detect_intv_before_track;     // æœªè·Ÿè¸ªåˆ°äººè„¸å‰çš„æ£€æµ‹æ—¶é—´é—´éš”
        public float detect_intv_during_track;     // å·²è·Ÿè¸ªåˆ°äººè„¸åŽçš„æ£€æµ‹æ—¶é—´é—´éš”
    };
//// äººè„¸è·Ÿè¸ª
//namespace FaceAI
//{
//    // äººè„¸è·Ÿè¸ªé…ç½®ç»“构体
//    [StructLayout(LayoutKind.Sequential, Pack = 1)]
//    struct BDFaceTrackConf
//    {
//        public float detect_intv_before_track;     // æœªè·Ÿè¸ªåˆ°äººè„¸å‰çš„æ£€æµ‹æ—¶é—´é—´éš”
//        public float detect_intv_during_track;     // å·²è·Ÿè¸ªåˆ°äººè„¸åŽçš„æ£€æµ‹æ—¶é—´é—´éš”
//    };
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
     public struct BDFaceBBox
     {
         public int index;  // äººè„¸ç´¢å¼•值
         public float center_x; // äººè„¸ä¸­å¿ƒç‚¹x坐标
         public float center_y; // äººè„¸ä¸­å¿ƒç‚¹y坐标
         public float width; // äººè„¸å®½åº¦
         public float height; // äººè„¸é«˜åº¦
         public float score;  // äººè„¸ç½®ä¿¡åº¦
     }
//    [StructLayout(LayoutKind.Sequential, Pack = 1)]
//     public struct BDFaceBBox
//     {
//         public int index;  // äººè„¸ç´¢å¼•值
//         public float center_x; // äººè„¸ä¸­å¿ƒç‚¹x坐标
//         public float center_y; // äººè„¸ä¸­å¿ƒç‚¹y坐标
//         public float width; // äººè„¸å®½åº¦
//         public float height; // äººè„¸é«˜åº¦
//         public float score;  // äººè„¸ç½®ä¿¡åº¦
//     }
   
     [StructLayout(LayoutKind.Sequential, Pack = 1)]
     public struct BDFaceLandmark
    {
         public int index; // äººè„¸å…³é”®ç‚¹ç´¢å¼•值
         public int size; // äººè„¸å…³é”®ç‚¹æ•°é‡
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 144)]
         public float[] data;// = new float[144];
         public float score; // äººè„¸å…³é”®ç‚¹ç½®ä¿¡åº¦
    }
     [StructLayout(LayoutKind.Sequential, Pack = 1)]
     public struct BDFaceTrackInfo
     {
         public int face_id;
         [MarshalAs(UnmanagedType.Struct)]
         public BDFaceBBox box;
         [MarshalAs(UnmanagedType.Struct)]
         public BDFaceLandmark landmark;
     }
//     [StructLayout(LayoutKind.Sequential, Pack = 1)]
//     public struct BDFaceLandmark
//    {
//         public int index; // äººè„¸å…³é”®ç‚¹ç´¢å¼•值
//         public int size; // äººè„¸å…³é”®ç‚¹æ•°é‡
//        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 144)]
//         public float[] data;// = new float[144];
//         public float score; // äººè„¸å…³é”®ç‚¹ç½®ä¿¡åº¦
//    }
//     [StructLayout(LayoutKind.Sequential, Pack = 1)]
//     public struct BDFaceTrackInfo
//     {
//         public int face_id;
//         [MarshalAs(UnmanagedType.Struct)]
//         public BDFaceBBox box;
//         [MarshalAs(UnmanagedType.Struct)]
//         public BDFaceLandmark landmark;
//     }
   
    // äººè„¸è·Ÿè¸ª
    class FaceTrack
    {
        [DllImport("BaiduFaceApi.dll", EntryPoint = "track", CharSet = CharSet.Ansi
           , CallingConvention = CallingConvention.Cdecl)]
        // type ä¸º0时候执行RGB人脸跟踪,1时候执行NIR人脸跟踪
        public static extern int track(IntPtr ptr, IntPtr mat, int type);
//    // äººè„¸è·Ÿè¸ª
//    class FaceTrack
//    {
//        [DllImport("BaiduFaceApi.dll", EntryPoint = "track", CharSet = CharSet.Ansi
//           , CallingConvention = CallingConvention.Cdecl)]
//        // type ä¸º0时候执行RGB人脸跟踪,1时候执行NIR人脸跟踪
//        public static extern int track(IntPtr ptr, IntPtr mat, int type);
        [DllImport("BaiduFaceApi.dll", EntryPoint = "clear_track_history", CharSet = CharSet.Ansi
         , CallingConvention = CallingConvention.Cdecl)]
        // type ä¸º0时候执行RGB人脸跟踪,1时候执行NIR人脸跟踪
        public static extern void clear_track_history(int type);
//        [DllImport("BaiduFaceApi.dll", EntryPoint = "clear_track_history", CharSet = CharSet.Ansi
//         , CallingConvention = CallingConvention.Cdecl)]
//        // type ä¸º0时候执行RGB人脸跟踪,1时候执行NIR人脸跟踪
//        public static extern void clear_track_history(int type);
        // æµ‹è¯•人脸跟踪
        public void image_track()
        {
            Console.WriteLine("test_track");
            int max_track_num = 50; // è®¾ç½®æœ€å¤šæ£€æµ‹è·Ÿè¸ªäººæ•°ï¼ˆå¤šäººè„¸æ£€æµ‹ï¼‰ï¼Œé»˜è®¤ä¸º1,最多可设为50
//        // æµ‹è¯•人脸跟踪
//        public void image_track()
//        {
//            Console.WriteLine("test_track");
//            int max_track_num = 50; // è®¾ç½®æœ€å¤šæ£€æµ‹è·Ÿè¸ªäººæ•°ï¼ˆå¤šäººè„¸æ£€æµ‹ï¼‰ï¼Œé»˜è®¤ä¸º1,最多可设为50
            BDFaceTrackInfo[] track_info = new BDFaceTrackInfo[max_track_num];
            for (int i = 0; i < max_track_num; i++)
            {
                track_info[i] = new BDFaceTrackInfo();
                track_info[i].box = new BDFaceBBox();
                track_info[i].box.score = 0;
                track_info[i].box.width = 0;
                track_info[i].landmark.data = new float[144];
                track_info[i].face_id = 0;
            }
            int sizeTrack = Marshal.SizeOf(typeof(BDFaceTrackInfo));
            IntPtr ptT = Marshal.AllocHGlobal(sizeTrack * max_track_num);
            Mat mat = Cv2.ImRead("../images/2.jpg");
            // faceNum为返回的检测到的人脸个数
            int type = 0;
            int faceNum = track(ptT, mat.CvPtr, type);
            Console.WriteLine("faceSize is:" + faceNum);
            // å› ä¸ºéœ€é¢„分配内存,所以返回的人脸数若大于预先分配的内存数,则仅仅显示预分配的人脸数
            if (faceNum > max_track_num)
            {
                faceNum = max_track_num;
            }
            for (int index = 0; index < faceNum; index++) {
//            BDFaceTrackInfo[] track_info = new BDFaceTrackInfo[max_track_num];
//            for (int i = 0; i < max_track_num; i++)
//            {
//                track_info[i] = new BDFaceTrackInfo();
//                track_info[i].box = new BDFaceBBox();
//                track_info[i].box.score = 0;
//                track_info[i].box.width = 0;
//                track_info[i].landmark.data = new float[144];
//                track_info[i].face_id = 0;
//            }
//            int sizeTrack = Marshal.SizeOf(typeof(BDFaceTrackInfo));
//            IntPtr ptT = Marshal.AllocHGlobal(sizeTrack * max_track_num);
//            Mat mat = Cv2.ImRead("../images/2.jpg");
//            // faceNum为返回的检测到的人脸个数
//            int type = 0;
//            int faceNum = track(ptT, mat.CvPtr, type);
//            Console.WriteLine("faceSize is:" + faceNum);
//            // å› ä¸ºéœ€é¢„分配内存,所以返回的人脸数若大于预先分配的内存数,则仅仅显示预分配的人脸数
//            if (faceNum > max_track_num)
//            {
//                faceNum = max_track_num;
//            }
//            for (int index = 0; index < faceNum; index++) {
                IntPtr ptr = new IntPtr();
                if (8 == IntPtr.Size)
                {
                    ptr = (IntPtr)(ptT.ToInt64() + sizeTrack * index);
                }
                else if (4 == IntPtr.Size)
                {
                    ptr = (IntPtr)(ptT.ToInt32() + sizeTrack * index);
                }
//                IntPtr ptr = new IntPtr();
//                if (8 == IntPtr.Size)
//                {
//                    ptr = (IntPtr)(ptT.ToInt64() + sizeTrack * index);
//                }
//                else if (4 == IntPtr.Size)
//                {
//                    ptr = (IntPtr)(ptT.ToInt32() + sizeTrack * index);
//                }
                track_info[index] = (BDFaceTrackInfo)Marshal.PtrToStructure(ptr, typeof(BDFaceTrackInfo));
                Console.WriteLine("track face_id is {0}:", track_info[index].face_id);
                Console.WriteLine("track landmarks is:");
//                track_info[index] = (BDFaceTrackInfo)Marshal.PtrToStructure(ptr, typeof(BDFaceTrackInfo));
//                Console.WriteLine("track face_id is {0}:", track_info[index].face_id);
//                Console.WriteLine("track landmarks is:");
                for(int i = 0; i < 144; i++)
                {
                    Console.WriteLine("lanmark data is {0}:", track_info[index].landmark.data[i]);
                }
                Console.WriteLine("track landmarks score is:{0}", track_info[index].landmark.score);
                Console.WriteLine("track landmarks index is:{0}", track_info[index].landmark.index);
//                for(int i = 0; i < 144; i++)
//                {
//                    Console.WriteLine("lanmark data is {0}:", track_info[index].landmark.data[i]);
//                }
//                Console.WriteLine("track landmarks score is:{0}", track_info[index].landmark.score);
//                Console.WriteLine("track landmarks index is:{0}", track_info[index].landmark.index);
                // ç´¢å¼•值
                Console.WriteLine("track score is:{0}", track_info[index].box.index);
                // ç½®ä¿¡åº¦
                Console.WriteLine("track score is:{0}", track_info[index].box.score);
                // äººè„¸å®½åº¦
                Console.WriteLine("track mWidth is:{0}", track_info[index].box.width);
                // ä¸­å¿ƒç‚¹X,Y坐标
                Console.WriteLine("track mCenter_x is:{0}", track_info[index].box.center_x);
                Console.WriteLine("track mCenter_y is:{0}", track_info[index].box.center_y);
            }
            // ç”»äººè„¸æ¡†
            FaceDraw.draw_rects(ref mat, faceNum, track_info);
            // å›¾ç‰‡ç”»æ¡†ä¿å­˜
            mat.ImWrite("track.jpg");
            Marshal.FreeHGlobal(ptT);
        }
//                // ç´¢å¼•值
//                Console.WriteLine("track score is:{0}", track_info[index].box.index);
//                // ç½®ä¿¡åº¦
//                Console.WriteLine("track score is:{0}", track_info[index].box.score);
//                // äººè„¸å®½åº¦
//                Console.WriteLine("track mWidth is:{0}", track_info[index].box.width);
//                // ä¸­å¿ƒç‚¹X,Y坐标
//                Console.WriteLine("track mCenter_x is:{0}", track_info[index].box.center_x);
//                Console.WriteLine("track mCenter_y is:{0}", track_info[index].box.center_y);
//            }
//            // ç”»äººè„¸æ¡†
//            FaceDraw.draw_rects(ref mat, faceNum, track_info);
//            // å›¾ç‰‡ç”»æ¡†ä¿å­˜
//            mat.ImWrite("track.jpg");
//            Marshal.FreeHGlobal(ptT);
//        }
       
        //usb摄像头实时人脸检测示例
        public void usb_video_track()
        {
            // é»˜è®¤ç”µè„‘自带摄像头,device可能为0,若外接usb摄像头,则device可能为1.
            int dev = 0;
            using (var window = new Window("face"))
            using (VideoCapture cap = VideoCapture.FromCamera(dev))
            {
                if (!cap.IsOpened())
                {
                    Console.WriteLine("open camera error");
                    return;
                }
                // Frame image buffer
                Mat image = new Mat();
                // When the movie playback reaches end, Mat.data becomes NULL.
                while (true)
                {
                    cap.Read(image); // same as cvQueryFrame
                    if (!image.Empty())
                    {
                        int ilen = 10;//传入的人脸数
                        BDFaceTrackInfo[] track_info = new BDFaceTrackInfo[ilen];
                        for (int i = 0; i < ilen; i++)
                        {
                            track_info[i].box = new BDFaceBBox();
                            track_info[i].box.score = 0;
                            track_info[i].box.width = 0;
                            track_info[i].landmark.data = new float[144];
                            track_info[i].face_id = 0;
                        }
                        int sizeTrack = Marshal.SizeOf(typeof(BDFaceTrackInfo));
                        IntPtr ptT = Marshal.AllocHGlobal(sizeTrack* ilen);
                        //Cv2.ImWrite("usb_track_Cv2.jpg", image);
                        /*  trackMat
                         *  ä¼ å…¥å‚æ•°: maxTrackObjNum:检测到的最大人脸数,传入外部分配人脸数,需要分配对应的内存大小。
                         *            ä¼ å‡ºæ£€æµ‹åˆ°çš„æœ€å¤§äººè„¸æ•°
                         *    è¿”回值: ä¼ å…¥çš„人脸数 å’Œ æ£€æµ‹åˆ°çš„人脸数 ä¸­çš„æœ€å°å€¼,实际返回的人脸。
                         ****/
                        int faceSize = ilen;//返回人脸数  åˆ†é…äººè„¸æ•°å’Œæ£€æµ‹åˆ°äººè„¸æ•°çš„æœ€å°å€¼
                        int curSize = ilen;//当前人脸数 è¾“入分配的人脸数,输出实际检测到的人脸数
                        int type = 0;
                        faceSize = track(ptT, image.CvPtr, type);
                        for (int index = 0; index < faceSize; index++)
                        {
                            IntPtr ptr = new IntPtr();
                            if( 8 == IntPtr.Size)
                            {
                                ptr = (IntPtr)(ptT.ToInt64() + sizeTrack * index);
                            }
                            else if(4 == IntPtr.Size)
                            {
                                ptr = (IntPtr)(ptT.ToInt32() + sizeTrack * index);
                            }
//        //usb摄像头实时人脸检测示例
//        public void usb_video_track()
//        {
//            // é»˜è®¤ç”µè„‘自带摄像头,device可能为0,若外接usb摄像头,则device可能为1.
//            int dev = 0;
//            using (var window = new Window("face"))
//            using (VideoCapture cap = VideoCapture.FromCamera(dev))
//            {
//                if (!cap.IsOpened())
//                {
//                    Console.WriteLine("open camera error");
//                    return;
//                }
//                // Frame image buffer
//                Mat image = new Mat();
//                // When the movie playback reaches end, Mat.data becomes NULL.
//                while (true)
//                {
//                    cap.Read(image); // same as cvQueryFrame
//                    if (!image.Empty())
//                    {
//                        int ilen = 10;//传入的人脸数
//                        BDFaceTrackInfo[] track_info = new BDFaceTrackInfo[ilen];
//                        for (int i = 0; i < ilen; i++)
//                        {
//                            track_info[i].box = new BDFaceBBox();
//                            track_info[i].box.score = 0;
//                            track_info[i].box.width = 0;
//                            track_info[i].landmark.data = new float[144];
//                            track_info[i].face_id = 0;
//                        }
//                        int sizeTrack = Marshal.SizeOf(typeof(BDFaceTrackInfo));
//                        IntPtr ptT = Marshal.AllocHGlobal(sizeTrack* ilen);
//                        //Cv2.ImWrite("usb_track_Cv2.jpg", image);
//                        /*  trackMat
//                         *  ä¼ å…¥å‚æ•°: maxTrackObjNum:检测到的最大人脸数,传入外部分配人脸数,需要分配对应的内存大小。
//                         *            ä¼ å‡ºæ£€æµ‹åˆ°çš„æœ€å¤§äººè„¸æ•°
//                         *    è¿”回值: ä¼ å…¥çš„人脸数 å’Œ æ£€æµ‹åˆ°çš„人脸数 ä¸­çš„æœ€å°å€¼,实际返回的人脸。
//                         ****/
//                        int faceSize = ilen;//返回人脸数  åˆ†é…äººè„¸æ•°å’Œæ£€æµ‹åˆ°äººè„¸æ•°çš„æœ€å°å€¼
//                        int curSize = ilen;//当前人脸数 è¾“入分配的人脸数,输出实际检测到的人脸数
//                        int type = 0;
//                        faceSize = track(ptT, image.CvPtr, type);
//                        for (int index = 0; index < faceSize; index++)
//                        {
//                            IntPtr ptr = new IntPtr();
//                            if( 8 == IntPtr.Size)
//                            {
//                                ptr = (IntPtr)(ptT.ToInt64() + sizeTrack * index);
//                            }
//                            else if(4 == IntPtr.Size)
//                            {
//                                ptr = (IntPtr)(ptT.ToInt32() + sizeTrack * index);
//                            }
                            
                            track_info[index] = (BDFaceTrackInfo)Marshal.PtrToStructure(ptr, typeof(BDFaceTrackInfo));
                            //face_info[index] = (BDFaceBBox)Marshal.PtrToStructure(info_ptr, typeof(BDFaceBBox));
                            Console.WriteLine("in Liveness::usb_track face_id is {0}:",track_info[index].face_id);
                            Console.WriteLine("in Liveness::usb_track landmarks is:");
//                            track_info[index] = (BDFaceTrackInfo)Marshal.PtrToStructure(ptr, typeof(BDFaceTrackInfo));
//                            //face_info[index] = (BDFaceBBox)Marshal.PtrToStructure(info_ptr, typeof(BDFaceBBox));
//                            Console.WriteLine("in Liveness::usb_track face_id is {0}:",track_info[index].face_id);
//                            Console.WriteLine("in Liveness::usb_track landmarks is:");
                                                                              
                            Console.WriteLine("in Liveness::usb_track score is:{0:f}", track_info[index].box.score);
                            // äººè„¸å®½åº¦
                            Console.WriteLine("in Liveness::usb_track mWidth is:{0:f}", track_info[index].box.width);
                            // ä¸­å¿ƒç‚¹X,Y坐标
                            Console.WriteLine("in Liveness::usb_track mCenter_x is:{0:f}", track_info[index].box.center_x);
                            Console.WriteLine("in Liveness::usb_track mCenter_y is:{0:f}", track_info[index].box.center_y);
//                            Console.WriteLine("in Liveness::usb_track score is:{0:f}", track_info[index].box.score);
//                            // äººè„¸å®½åº¦
//                            Console.WriteLine("in Liveness::usb_track mWidth is:{0:f}", track_info[index].box.width);
//                            // ä¸­å¿ƒç‚¹X,Y坐标
//                            Console.WriteLine("in Liveness::usb_track mCenter_x is:{0:f}", track_info[index].box.center_x);
//                            Console.WriteLine("in Liveness::usb_track mCenter_y is:{0:f}", track_info[index].box.center_y);
                                                   
                        }
//                        }
                       
                        FaceDraw.draw_rects(ref image, faceSize, track_info);
                       // FaceDraw.draw_shape(ref image, faceSize, track_info);
                        Marshal.FreeHGlobal(ptT);
                        window.ShowImage(image);
                        Cv2.WaitKey(1);
                        Console.WriteLine("mat not empty");
                    }
                    else
                    {
                        Console.WriteLine("mat is empty");
                    }
                }
            }
        }
//                        FaceDraw.draw_rects(ref image, faceSize, track_info);
//                       // FaceDraw.draw_shape(ref image, faceSize, track_info);
//                        Marshal.FreeHGlobal(ptT);
//                        window.ShowImage(image);
//                        Cv2.WaitKey(1);
//                        Console.WriteLine("mat not empty");
//                    }
//                    else
//                    {
//                        Console.WriteLine("mat is empty");
//                    }
//                }
//            }
//        }
       
         // æ¸…除跟踪的人脸信息
         public void test_clear_tracked_faces()
         {
            int type = 0;
            clear_track_history(type);
            Console.WriteLine("after clear tracked faces");
        }
//         // æ¸…除跟踪的人脸信息
//         public void test_clear_tracked_faces()
//         {
//            int type = 0;
//            clear_track_history(type);
//            Console.WriteLine("after clear tracked faces");
//        }
     }
 }
//     }
// }
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_ISystemServices/ISys_UserFaceService.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using WIDESEAWCS_Core;
using WIDESEAWCS_Core.BaseServices;
using WIDESEAWCS_Model.Models;
using WIDESEAWCS_Model.Models.System;
namespace WIDESEAWCS_ISystemServices
{
    public interface ISys_UserFaceService : IService<Sys_UserFace>
    {
        WebResponseContent FaceRecognition(ImageModel model);
        WebResponseContent FaceEnter(ImageModel model);
    }
    public class ImageModel
    {
        public string Base64Image { get; set; }
    }
}
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Model/Models/System/Sys_Log.cs
@@ -44,13 +44,13 @@
        /// <summary>
        /// è¯·æ±‚参数
        /// </summary>
        [SugarColumn(IsNullable = true, Length = 2000, ColumnDescription = "请求参数")]
        [SugarColumn(IsNullable = true, Length = int.MaxValue, ColumnDescription = "请求参数")]
        public string RequestParam { get; set; }
        /// <summary>
        /// å“åº”参数
        /// </summary>
        [SugarColumn(IsNullable = true, Length = 2000, ColumnDescription = "响应参数")]
        [SugarColumn(IsNullable = true, Length = int.MaxValue, ColumnDescription = "响应参数")]
        public string ResponseParam { get; set; }
        /// <summary>
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Model/Models/System/Sys_UserFace.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WIDESEAWCS_Model.Models
{
    [SqlSugar.SugarTable("Sys_UserFace", "用户人脸识别表")]
    public class Sys_UserFace
    {
        [SqlSugar.SugarColumn(IsPrimaryKey = true, IsIdentity = true, ColumnDescription = "主键ID")]
        public int Id { get; set; }
        [SqlSugar.SugarColumn(ColumnDescription = "用户ID", IsNullable = false)]
        public int User_Id { get; set; }
        [SqlSugar.SugarColumn(Length = 100, IsNullable = false, ColumnDescription = "用户名")]
        public string UserName { get; set; }
        [SqlSugar.SugarColumn(Length = 500, IsNullable = false, ColumnDescription = "图片名称")]
        public string UserFaceImageName { get; set; }
        [SqlSugar.SugarColumn(Length = 2000, IsNullable = false, ColumnDescription = "图片路径")]
        public string UserFaceImagePath { get; set; }
    }
}
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Controllers/System/Sys_UserController.cs
@@ -176,8 +176,6 @@
        public WebResponseContent SaveFiles(IFormCollection files)
        {
            return Service.SaveFiles(files);
        }
        /// <summary>
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Controllers/System/Sys_UserFaceController.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,134 @@

using System.IO;
using System.Net.Mime;
using System.Text.RegularExpressions;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using Newtonsoft.Json;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Math;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Text;
using StackExchange.Profiling;
using WIDESEAWCS_Core;
using WIDESEAWCS_Core.Authorization;
using WIDESEAWCS_Core.BaseController;
using WIDESEAWCS_Core.Const;
using WIDESEAWCS_Core.Extensions;
using WIDESEAWCS_Core.Helper;
using WIDESEAWCS_Core.HttpContextUser;
using WIDESEAWCS_Core.Utilities;
using WIDESEAWCS_DTO.SerialPort;
using WIDESEAWCS_ISystemServices;
using WIDESEAWCS_Model;
using WIDESEAWCS_Model.Models;
using WIDESEAWCS_Model.Models.System;
using IOFile = System.IO.File;
namespace WIDESEAWCS_WCSServer.Controllers
{
    [Route("api/UserFace")]
    [ApiController]
    public class Sys_UserFaceController : ApiBaseController<ISys_UserFaceService, Sys_UserFace>
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
        public Sys_UserFaceController(ISys_UserFaceService userService, IHttpContextAccessor httpContextAccessor) : base(userService)
        {
            _httpContextAccessor = httpContextAccessor;
        }
        [HttpPost, Route("FaceRecognition"), AllowAnonymous]
        public WebResponseContent FaceRecognition([FromBody] ImageModel model)
        {
            return Service.FaceRecognition(model);
        }
        [HttpPost, Route("FaceEnter")]
        public WebResponseContent FaceEnter([FromBody] ImageModel model)
        {
            return Service.FaceEnter(model);
        }
        [HttpPost, HttpGet, Route("DownlodaFacePlugin"), AllowAnonymous]
        public ActionResult DownlodaFacePlugin()
        {
            try
            {
                string path = $"{AppDomain.CurrentDomain.BaseDirectory}DownLoad/";
                if (!Directory.Exists(path)) Directory.CreateDirectory(path);
                path += "face-plugin.zip";
                if (IOFile.Exists(path))
                {
                    byte[] fileBytes = IOFile.ReadAllBytes(path);
                    return File(
                            fileBytes,
                            MediaTypeNames.Application.Octet,
                            Path.GetFileName(path)
                        );
                }
                else
                {
                    return Json(WebResponseContent.Instance.Error($"未找到文件"));
                }
            }
            catch (Exception ex)
            {
                return Json(WebResponseContent.Instance.Error($"下载失败:{ex.Message}"));
            }
        }
        [HttpPost, HttpGet, Route("DownloadRegFile"), AllowAnonymous]
        public ActionResult DownloadRegFile([FromBody] PathModel model)
        {
            try
            {
                string folderPath = model.Path;
                foreach (var item in folderPath.ToCharArray())
                {
                    if (Regex.IsMatch(item.ToString(), @"[\u4e00-\u9fa5]"))
                    {
                        return Json(WebResponseContent.Instance.Error($"插件路径不能包含中文"));
                    }
                }
                string path = $"{AppDomain.CurrentDomain.BaseDirectory}DownLoad/";
                // å¦‚果文件夹不存在,则创建文件夹
                //if (!Directory.Exists(folderPath))
                //{
                //    return Json(WebResponseContent.Instance.Error($"插件路径不存在"));
                //}
                // èŽ·å–æ—¥å¿—æ–‡ä»¶è·¯å¾„
                string filePath = Path.Combine(path, "reg.reg");
                if (IOFile.Exists(filePath))
                {
                    IOFile.Delete(filePath); // åˆ é™¤å·²å­˜åœ¨çš„æ—¥å¿—文件
                }
                // æž„造日志内容
                string content = $"Windows Registry Editor Version 5.00\r\n[HKEY_CLASSES_ROOT\\myapp]\r\n@=\"URL:MyApp Protocol\"\r\n\"URL Protocol\"=\"\"\r\n[HKEY_CLASSES_ROOT\\myapp\\shell]\r\n[HKEY_CLASSES_ROOT\\myapp\\shell\\open]\r\n[HKEY_CLASSES_ROOT\\myapp\\shell\\open\\command]\r\n@=\"\\\"{model.Path.Replace(@"\", @"\\")}\\\\FaceSdkX64Register.exe\\\" \\\"%1\\\"\"";
                // å°†æ—¥å¿—内容追加到日志文件中
                IOFile.AppendAllText(filePath, content);
                byte[] fileBytes = IOFile.ReadAllBytes(filePath);
                return File(
                        fileBytes,
                        MediaTypeNames.Application.Octet,
                        Path.GetFileName(filePath)
                    );
            }
            catch (Exception ex)
            {
                return Json(WebResponseContent.Instance.Error($"下载失败:{ex.Message}"));
            }
        }
    }
    public class PathModel
    {
        public string Path { get; set; }
    }
}
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/DownLoad/face-plugin.zip
Binary files differ
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_Server.csproj
@@ -9,19 +9,6 @@
    </PropertyGroup>
    <ItemGroup>
        <Content Remove="wwwroot\WIDESEAWCS_DB.DBSeed.Json\Dt_DispatchInfo.tsv" />
        <Content Remove="wwwroot\WIDESEAWCS_DB.DBSeed.Json\Dt_Router.tsv" />
        <Content Remove="wwwroot\WIDESEAWCS_DB.DBSeed.Json\Dt_Task.tsv" />
        <Content Remove="wwwroot\WIDESEAWCS_DB.DBSeed.Json\Dt_TaskExecuteDetail.tsv" />
        <Content Remove="wwwroot\WIDESEAWCS_DB.DBSeed.Json\Sys_Dictionary.tsv" />
        <Content Remove="wwwroot\WIDESEAWCS_DB.DBSeed.Json\Sys_DictionaryList.tsv" />
        <Content Remove="wwwroot\WIDESEAWCS_DB.DBSeed.Json\Sys_Menu.tsv" />
        <Content Remove="wwwroot\WIDESEAWCS_DB.DBSeed.Json\Sys_Role.tsv" />
        <Content Remove="wwwroot\WIDESEAWCS_DB.DBSeed.Json\Sys_RoleAuth.tsv" />
        <Content Remove="wwwroot\WIDESEAWCS_DB.DBSeed.Json\Sys_User.tsv" />
    </ItemGroup>
    <ItemGroup>
        <None Remove="index.html" />
    </ItemGroup>
@@ -29,42 +16,11 @@
        <EmbeddedResource Include="index.html">
            <CopyToOutputDirectory>Always</CopyToOutputDirectory>
        </EmbeddedResource>
        <EmbeddedResource Include="wwwroot\WIDESEAWCS_DB.DBSeed.Json\Dt_DispatchInfo.tsv">
          <CopyToOutputDirectory>Always</CopyToOutputDirectory>
        </EmbeddedResource>
        <EmbeddedResource Include="wwwroot\WIDESEAWCS_DB.DBSeed.Json\Dt_Router.tsv">
          <CopyToOutputDirectory>Always</CopyToOutputDirectory>
        </EmbeddedResource>
        <EmbeddedResource Include="wwwroot\WIDESEAWCS_DB.DBSeed.Json\Dt_Task.tsv">
          <CopyToOutputDirectory>Always</CopyToOutputDirectory>
        </EmbeddedResource>
        <EmbeddedResource Include="wwwroot\WIDESEAWCS_DB.DBSeed.Json\Dt_TaskExecuteDetail.tsv">
          <CopyToOutputDirectory>Always</CopyToOutputDirectory>
        </EmbeddedResource>
        <EmbeddedResource Include="wwwroot\WIDESEAWCS_DB.DBSeed.Json\Sys_Dictionary.tsv">
          <CopyToOutputDirectory>Always</CopyToOutputDirectory>
        </EmbeddedResource>
        <EmbeddedResource Include="wwwroot\WIDESEAWCS_DB.DBSeed.Json\Sys_DictionaryList.tsv">
          <CopyToOutputDirectory>Always</CopyToOutputDirectory>
        </EmbeddedResource>
        <EmbeddedResource Include="wwwroot\WIDESEAWCS_DB.DBSeed.Json\Sys_Menu.tsv">
          <CopyToOutputDirectory>Always</CopyToOutputDirectory>
        </EmbeddedResource>
        <EmbeddedResource Include="wwwroot\WIDESEAWCS_DB.DBSeed.Json\Sys_Role.tsv">
          <CopyToOutputDirectory>Always</CopyToOutputDirectory>
        </EmbeddedResource>
        <EmbeddedResource Include="wwwroot\WIDESEAWCS_DB.DBSeed.Json\Sys_RoleAuth.tsv">
          <CopyToOutputDirectory>Always</CopyToOutputDirectory>
        </EmbeddedResource>
        <EmbeddedResource Include="wwwroot\WIDESEAWCS_DB.DBSeed.Json\Sys_User.tsv">
          <CopyToOutputDirectory>Always</CopyToOutputDirectory>
        </EmbeddedResource>
    </ItemGroup>
    <ItemGroup>
        <PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
        <PackageReference Include="System.IO.FileSystem" Version="4.3.0" />
    </ItemGroup>
    <ItemGroup>
@@ -88,4 +44,14 @@
        </Content>
    </ItemGroup>
    <ItemGroup>
      <Folder Include="wwwroot\WIDESEAWCS_DB.DBSeed.Json\" />
    </ItemGroup>
    <ItemGroup>
      <None Update="DownLoad\face-plugin.zip">
        <CopyToOutputDirectory>Always</CopyToOutputDirectory>
      </None>
    </ItemGroup>
</Project>
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/wwwroot/WIDESEAWCS_DB.DBSeed.Json/Dt_DeviceInfo.tsv
ÎļþÒÑɾ³ý
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/wwwroot/WIDESEAWCS_DB.DBSeed.Json/Dt_DeviceProtocol.tsv
ÎļþÒÑɾ³ý
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/wwwroot/WIDESEAWCS_DB.DBSeed.Json/Dt_DeviceProtocolDetail.tsv
ÎļþÒÑɾ³ý
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/wwwroot/WIDESEAWCS_DB.DBSeed.Json/Dt_DispatchInfo.tsv
ÎļþÒÑɾ³ý
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/wwwroot/WIDESEAWCS_DB.DBSeed.Json/Dt_Router.tsv
ÎļþÒÑɾ³ý
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/wwwroot/WIDESEAWCS_DB.DBSeed.Json/Dt_Task.tsv
ÎļþÒÑɾ³ý
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/wwwroot/WIDESEAWCS_DB.DBSeed.Json/Dt_TaskExecuteDetail.tsv
ÎļþÒÑɾ³ý
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/wwwroot/WIDESEAWCS_DB.DBSeed.Json/Sys_Dictionary.tsv
ÎļþÒÑɾ³ý
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/wwwroot/WIDESEAWCS_DB.DBSeed.Json/Sys_DictionaryList.tsv
ÎļþÒÑɾ³ý
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/wwwroot/WIDESEAWCS_DB.DBSeed.Json/Sys_Menu.tsv
ÎļþÒÑɾ³ý
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/wwwroot/WIDESEAWCS_DB.DBSeed.Json/Sys_Role.tsv
ÎļþÒÑɾ³ý
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/wwwroot/WIDESEAWCS_DB.DBSeed.Json/Sys_RoleAuth.tsv
ÎļþÒÑɾ³ý
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/wwwroot/WIDESEAWCS_DB.DBSeed.Json/Sys_User.tsv
ÎļþÒÑɾ³ý
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_SystemServices/Sys_UserFaceService.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,214 @@

using System.Drawing;
using System.Drawing.Imaging;
using WIDESEAWCS_Common.Face;
using WIDESEAWCS_Core;
using WIDESEAWCS_Core.Authorization;
using WIDESEAWCS_Core.BaseRepository;
using WIDESEAWCS_Core.BaseServices;
using WIDESEAWCS_Core.Caches;
using WIDESEAWCS_ISystemServices;
using WIDESEAWCS_Model.Models;
using File = System.IO.File;
namespace WIDESEAWCS_SystemServices
{
    public class Sys_UserFaceService : ServiceBase<Sys_UserFace, IRepository<Sys_UserFace>>, ISys_UserFaceService
    {
        public IRepository<Sys_UserFace> Repository => BaseDal;
        private readonly IRepository<Sys_User> _userRepository;
        private readonly ICacheService _cacheService;
        public Sys_UserFaceService(IRepository<Sys_UserFace> BaseDal, IRepository<Sys_User> userRepository, ICacheService cacheService) : base(BaseDal)
        {
            _userRepository = userRepository;
            _cacheService = cacheService;
        }
        public WebResponseContent FaceRecognition(ImageModel model)
        {
            string filePath = string.Empty;
            try
            {
                byte[] data = Convert.FromBase64String(model.Base64Image);
                string sourcePath = AppDomain.CurrentDomain.BaseDirectory + "Record\\";
                string basePath = AppDomain.CurrentDomain.BaseDirectory + "Current\\";
                if (!Directory.Exists(basePath))
                {
                    Directory.CreateDirectory(basePath);
                }
                filePath = basePath + $"face_{DateTime.Now.ToString("yyyyMMddHHmmssfff")}.jpg";
                // ä½¿ç”¨å­—节数组创建MemoryStream
                using (MemoryStream ms = new MemoryStream(data))
                {
                    // ä»ŽMemoryStream创建Image对象
                    Image image = Image.FromStream(ms);
                    image.Save(filePath, ImageFormat.Png);
                }
                var (flag, result) = FaceHelper.FaceRecognition(sourcePath, filePath);
                if (flag)
                {
                    Sys_UserFace userFace = BaseDal.QueryFirst(x => x.UserFaceImagePath.Contains(result));
                    if (userFace != null)
                    {
                        Sys_User user = _userRepository.QueryFirst(x => x.User_Id == userFace.User_Id && x.UserName == userFace.UserName);
                        if (user != null)
                        {
                            string token = JwtHelper.IssueJwt(new TokenModelJwt()
                            {
                                UserId = user.User_Id,
                                RoleId = user.Role_Id,
                                UserName = user.UserName,
                                TenantId = user.TenantId,
                            });
                            _cacheService.AddOrUpdate(user.User_Id.ToString(), token);
                            return WebResponseContent.Instance.OK(data: new { token, userName = user.UserTrueName, img = user.HeadImageUrl });
                        }
                        else
                        {
                            return WebResponseContent.Instance.Error("未找到匹配的用户信息");
                        }
                    }
                    else
                    {
                        return WebResponseContent.Instance.Error("未找到匹配的人脸信息");
                    }
                }
                else
                {
                    return WebResponseContent.Instance.Error(result);
                }
            }
            finally
            {
                // ç¡®ä¿é‡Šæ”¾èµ„源
                GC.Collect();
                GC.WaitForPendingFinalizers();
                if (File.Exists(filePath))
                {
                    File.Delete(filePath); // åˆ é™¤å½“前人脸图片
                }
            }
        }
        public WebResponseContent FaceEnter(ImageModel model)
        {
            try
            {
                if (App.User == null || string.IsNullOrEmpty(App.User.UserName) || App.User.UserId == 0)
                {
                    return new WebResponseContent
                    {
                        Status = false,
                        Message = "用户未登录"
                    };
                }
                byte[] data = Convert.FromBase64String(model.Base64Image);
                string basePath = AppDomain.CurrentDomain.BaseDirectory + "Record\\";
                if (!Directory.Exists(basePath))
                {
                    Directory.CreateDirectory(basePath);
                }
                string curPath = AppDomain.CurrentDomain.BaseDirectory + "Current\\";
                if (!Directory.Exists(basePath))
                {
                    Directory.CreateDirectory(basePath);
                }
                string fileName = $"face_{DateTime.Now.ToString("yyyyMMddHHmmssfff")}.jpg";
                string filePath = basePath + fileName;
                // ä½¿ç”¨å­—节数组创建MemoryStream
                using (MemoryStream ms = new MemoryStream(data))
                {
                    // ä»ŽMemoryStream创建Image对象
                    Image image = Image.FromStream(ms);
                    image.Save(curPath + fileName, ImageFormat.Png);
                    {
                        var (flag, result) = FaceHelper.FaceRecognition(basePath, curPath + fileName);
                        if (flag)
                        {
                            Sys_UserFace userFaceTemp = BaseDal.QueryFirst(x => x.UserFaceImagePath.Contains(result));
                            if (userFaceTemp != null && userFaceTemp.User_Id != App.User.UserId && userFaceTemp.UserName != App.User.UserName)
                            {
                                return new WebResponseContent
                                {
                                    Status = false,
                                    Message = "不可注册多个账号"
                                };
                            }
                        }
                    }
                    image.Save(filePath, ImageFormat.Png);
                }
                // èŽ·å–å½“å‰ç”¨æˆ·ä¿¡æ¯
                Sys_UserFace userFace = BaseDal.QueryFirst(x => x.UserName == App.User.UserName && x.User_Id == App.User.UserId);
                if (userFace != null)
                {
                    if (!string.IsNullOrEmpty(userFace.UserFaceImagePath))
                    {
                        string? firstImagePath = userFace.UserFaceImagePath.Split(',').FirstOrDefault();
                        if (!string.IsNullOrEmpty(firstImagePath))
                        {
                            var (flag, result) = FaceHelper.FaceRecognitionOne(firstImagePath, filePath);
                            if (flag)
                            {
                                userFace.UserFaceImagePath += "," + filePath;
                                base.UpdateData(userFace);
                                return WebResponseContent.Instance.OK("人脸录入成功", filePath);
                            }
                            else
                            {
                                return WebResponseContent.Instance.Error(result);
                            }
                        }
                    }
                    else
                    {
                        userFace.UserFaceImagePath = filePath;
                        base.UpdateData(userFace);
                        return WebResponseContent.Instance.OK("人脸录入成功", filePath);
                    }
                }
                userFace = new Sys_UserFace
                {
                    User_Id = App.User.UserId,
                    UserName = App.User.UserName,
                    UserFaceImageName = fileName,
                    UserFaceImagePath = filePath
                };
                base.AddData(userFace);
                return WebResponseContent.Instance.OK(data: filePath);
            }
            catch (Exception ex)
            {
                return new WebResponseContent
                {
                    Status = false,
                    Message = "人脸录入失败:" + ex.Message
                };
            }
        }
    }
}
project/WCS/WIDESEAWCS_Server/WIDESEAWCS_SystemServices/Sys_UserService.cs
@@ -260,10 +260,10 @@
                    //result = FaceCompare.FaceIdentifyByBuffer(image, groupIdList, userId);
                    break;
                case "url":
                    result = FaceCompare.FaceIdentify(image, groupIdList, userId);
                    //result = FaceCompare.FaceIdentify(image, groupIdList, userId);
                    break;
                case "token":
                    result = FaceCompare.FaceIdentifyByFeature(image, groupIdList, userId);
                    //result = FaceCompare.FaceIdentifyByFeature(image, groupIdList, userId);
                    break;
                default:
                    break;
@@ -281,9 +281,11 @@
        {
            try
            {
                var result = FaceCompare.match(file1, file2);
                string buf = Marshal.PtrToStringAnsi(result);
                return buf;
                //var result = FaceCompare.match(file1, file2);
                //string buf = Marshal.PtrToStringAnsi(result);
                //return buf;
                return string.Empty; // è¿™é‡Œéœ€è¦æ›¿æ¢ä¸ºå®žé™…的人脸比对逻辑
            }
            catch (Exception e)
            {