diff --git a/ArcSoftFace.Test/ArcSoftFace.Test.csproj b/ArcSoftFace.Test/ArcSoftFace.Test.csproj new file mode 100644 index 0000000..df24c6b --- /dev/null +++ b/ArcSoftFace.Test/ArcSoftFace.Test.csproj @@ -0,0 +1,12 @@ + + + + Exe + NET6.0;NET40 + + + + + + + diff --git a/ArcSoftFace.Test/Program.cs b/ArcSoftFace.Test/Program.cs new file mode 100644 index 0000000..95a1150 --- /dev/null +++ b/ArcSoftFace.Test/Program.cs @@ -0,0 +1,104 @@ +using System; +using System.IO; +using Yj.ArcSoftSDK._4_0; + +namespace ArcSoftFace.Test +{ + class Program + { + static void Main(string[] args) + { + ArcTestUtil arcTestUtil = new ArcTestUtil(); + arcTestUtil.InitEngines(); + } + } + + + public class ArcTestUtil + { + /// + /// 初始化引擎 + /// + public void InitEngines() + { + int retCode=-1; + try + { + IntPtr _pVideoRGBImageEngine = IntPtr.Zero; + + //retCode = ASFFunctions.Activation(appId: "11111" + // , x86SdkKey: "" + // , x64SdkKey: "22222" + // , sox64Key: "" + // , x64ProActiveKey: "33333" + // , x86ProActiveKey: ""); + //Console.WriteLine($"Activation: {retCode}"); + + retCode = ASFFunctions.InitEngine(pEngine: ref _pVideoRGBImageEngine, isImgMode: true, faceMaxNum: 5, + isAngleZeroOnly: false, needFaceInfo: true, needRgbLive: true, needIrLive: true, needFaceFeature: true); + Console.WriteLine($"Init pEngine: {retCode}"); + + var faceInfos = ASFFunctions.DetectFacesEx(_pVideoRGBImageEngine, File.ReadAllBytes("3.jpg"), + faceMinWith: 0, + needCheckImage: true, + needFaceInfo: true, + needRgbLive: true, + needIrLive: true, + needFeatures: true, + isRegister:false); + var faceInfos2 = ASFFunctions.DetectFacesEx(_pVideoRGBImageEngine, File.ReadAllBytes("003.jpg"), + faceMinWith: 0, + needCheckImage: true, + needFaceInfo: true, + needRgbLive: true, + needIrLive: true, + needFeatures: true, + isRegister: false); + + byte[] feature1 = null;// System.IO.File.ReadAllBytes("feature1.dat"); + foreach (var faceInfo in faceInfos) + { + if (faceInfo.Feature != null) + { + feature1 = new byte[faceInfo.Feature.Length]; + faceInfo.Feature.CopyTo(feature1, 0); + } + + Console.WriteLine($"pic1 FaceID:{faceInfo.FaceID} 角度: {faceInfo.FaceOrient}" + + $" 年龄: {faceInfo.Age} 性别: {faceInfo.Gender} 活体: {faceInfo.RgbLive}" + + $" Rect" + + $" 3DAngle"); + } + + byte[] feature2 = null;// System.IO.File.ReadAllBytes("feature2.dat"); + foreach (var faceInfo in faceInfos2) + { + if (faceInfo.Feature != null) + { + feature2 = new byte[faceInfo.Feature.Length]; + faceInfo.Feature.CopyTo(feature2, 0); + } + + Console.WriteLine($"pic2 FaceID:{faceInfo.FaceID} 角度: {faceInfo.FaceOrient}" + + $" 年龄: {faceInfo.Age} 性别: {faceInfo.Gender} 活体: {faceInfo.RgbLive}" + + $" Rect" + + $" 3DAngle"); + } + + if (feature1 != null + && feature1.Length > 0 + && feature2 != null + && feature2.Length > 0) + { + float similarity = ASFFunctions.FaceFeatureCompare(_pVideoRGBImageEngine, feature1, feature2); + Console.WriteLine($"bitmap1 similarity bitmap2: {similarity}"); + } + } + catch + { + + } + + } + } +} \ No newline at end of file diff --git a/README.md b/README.md index 0e0a64e..64895e9 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,9 @@ 版本: So64 v4.0
版本: x86 x64 v4.0
-商用授权 离线激活 将激活验证文件更名为 ArcFace64.dat ArcFace32.dat +Linux +SDK动态链接库路径 自行复制至 /usr/lib +cp -Rf /mnt/d/Linux_x64/ArcProLib/Sox64/* /usr/lib ```` diff --git a/Src/ASFFunctions.Private.cs b/Src/ASFFunctions.Private.cs index dfaa8ab..6508c64 100644 --- a/Src/ASFFunctions.Private.cs +++ b/Src/ASFFunctions.Private.cs @@ -1,5 +1,5 @@ using System; -#if NET5_0 +#if NET5_0_OR_GREATER using System.Runtime.InteropServices; #endif using Yj.ArcSoftSDK._4_0.Models; @@ -52,33 +52,28 @@ private static ASF_AgeInfo AgeEstimation(IntPtr pEngine) { IntPtr pInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf()); int retCode = -1; -#if NET5_0 - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { -#endif - if ( -#if NET5_0 - RuntimeInformation.ProcessArchitecture == Architecture.X64 + + if ( +#if NET5_0_OR_GREATER + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + && RuntimeInformation.ProcessArchitecture == Architecture.X64 #else - Environment.Is64BitProcess + Environment.Is64BitProcess #endif - ) - { - retCode = ASFFunctions_Pro_x64.ASFGetAge(pEngine, pInfo); - } - else -#if NET5_0 - if (RuntimeInformation.ProcessArchitecture == Architecture.X86) + ) + { + retCode = ASFFunctions_Pro_x64.ASFGetAge(pEngine, pInfo); + } + else +#if NET5_0_OR_GREATER + if ( + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + && RuntimeInformation.ProcessArchitecture == Architecture.X86) #endif - { - retCode = ASFFunctions_Pro_x86.ASFGetAge(pEngine, pInfo); - } -#if NET5_0 - else - { - throw new NotSupportedException("Only supported Windows x86 x64 and Linux x64"); - } + { + retCode = ASFFunctions_Pro_x86.ASFGetAge(pEngine, pInfo); } +#if NET5_0_OR_GREATER else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && RuntimeInformation.ProcessArchitecture == Architecture.X64) { @@ -107,33 +102,27 @@ private static ASF_GenderInfo GenderEstimation(IntPtr pEngine) { IntPtr pInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf()); int retCode = -1; -#if NETSTANDARD2_0 || NET5_0 - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { -#endif - if ( -#if NET5_0 - RuntimeInformation.ProcessArchitecture == Architecture.X64 + if ( +#if NET5_0_OR_GREATER + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + && RuntimeInformation.ProcessArchitecture == Architecture.X64 #else - Environment.Is64BitProcess + Environment.Is64BitProcess #endif - ) - { - retCode = ASFFunctions_Pro_x64.ASFGetGender(pEngine, pInfo); - } - else -#if NET5_0 - if (RuntimeInformation.ProcessArchitecture == Architecture.X86) + ) + { + retCode = ASFFunctions_Pro_x64.ASFGetGender(pEngine, pInfo); + } + else +#if NET5_0_OR_GREATER + if ( + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + && RuntimeInformation.ProcessArchitecture == Architecture.X86) #endif - { - retCode = ASFFunctions_Pro_x86.ASFGetGender(pEngine, pInfo); - } -#if NET5_0 - else - { - throw new NotSupportedException("Only supported Windows x86 x64 and Linux x64"); - } + { + retCode = ASFFunctions_Pro_x86.ASFGetGender(pEngine, pInfo); } +#if NET5_0_OR_GREATER else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && RuntimeInformation.ProcessArchitecture == Architecture.X64) { @@ -162,33 +151,27 @@ private static ASF_Face3DAngle Face3DAngleDetection(IntPtr pEngine) { IntPtr pInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf()); int retCode = -1; -#if NETSTANDARD2_0 || NET5_0 - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { -#endif - if ( -#if NET5_0 - RuntimeInformation.ProcessArchitecture == Architecture.X64 + if ( +#if NET5_0_OR_GREATER + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + && RuntimeInformation.ProcessArchitecture == Architecture.X64 #else - Environment.Is64BitProcess + Environment.Is64BitProcess #endif - ) - { - retCode = ASFFunctions_Pro_x64.ASFGetFace3DAngle(pEngine, pInfo); - } - else -#if NET5_0 - if (RuntimeInformation.ProcessArchitecture == Architecture.X86) + ) + { + retCode = ASFFunctions_Pro_x64.ASFGetFace3DAngle(pEngine, pInfo); + } + else +#if NET5_0_OR_GREATER + if ( + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + && RuntimeInformation.ProcessArchitecture == Architecture.X86) #endif - { - retCode = ASFFunctions_Pro_x86.ASFGetFace3DAngle(pEngine, pInfo); - } -#if NET5_0 - else - { - throw new NotSupportedException("Only supported Windows x86 x64 and Linux x64"); - } + { + retCode = ASFFunctions_Pro_x86.ASFGetFace3DAngle(pEngine, pInfo); } +#if NET5_0_OR_GREATER else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && RuntimeInformation.ProcessArchitecture == Architecture.X64) { @@ -217,33 +200,27 @@ private static ASF_LivenessInfo LivenessInfo_RGB(IntPtr pEngine) { IntPtr pInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf()); int retCode = -1; -#if NETSTANDARD2_0 || NET5_0 - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { -#endif - if ( -#if NET5_0 - RuntimeInformation.ProcessArchitecture == Architecture.X64 + if ( +#if NET5_0_OR_GREATER + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + && RuntimeInformation.ProcessArchitecture == Architecture.X64 #else - Environment.Is64BitProcess + Environment.Is64BitProcess #endif - ) - { - retCode = ASFFunctions_Pro_x64.ASFGetLivenessScore(pEngine, pInfo); - } - else -#if NET5_0 - if (RuntimeInformation.ProcessArchitecture == Architecture.X86) + ) + { + retCode = ASFFunctions_Pro_x64.ASFGetLivenessScore(pEngine, pInfo); + } + else +#if NET5_0_OR_GREATER + if ( + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + && RuntimeInformation.ProcessArchitecture == Architecture.X86) #endif - { - retCode = ASFFunctions_Pro_x86.ASFGetLivenessScore(pEngine, pInfo); - } -#if NET5_0 - else - { - throw new NotSupportedException("Only supported Windows x86 x64 and Linux x64"); - } + { + retCode = ASFFunctions_Pro_x86.ASFGetLivenessScore(pEngine, pInfo); } +#if NET5_0_OR_GREATER else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && RuntimeInformation.ProcessArchitecture == Architecture.X64) { @@ -272,33 +249,27 @@ private static ASF_MaskInfo MaskEstimation(IntPtr pEngine) { IntPtr pInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf()); int retCode = -1; -#if NET5_0 - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { -#endif - if ( -#if NET5_0 - RuntimeInformation.ProcessArchitecture == Architecture.X64 + if ( +#if NET5_0_OR_GREATER + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + && RuntimeInformation.ProcessArchitecture == Architecture.X64 #else - Environment.Is64BitProcess + Environment.Is64BitProcess #endif - ) - { - retCode = ASFFunctions_Pro_x64.ASFGetMask(pEngine, pInfo); - } - else -#if NET5_0 - if (RuntimeInformation.ProcessArchitecture == Architecture.X86) + ) + { + retCode = ASFFunctions_Pro_x64.ASFGetMask(pEngine, pInfo); + } + else +#if NET5_0_OR_GREATER + if ( + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + && RuntimeInformation.ProcessArchitecture == Architecture.X86) #endif - { - retCode = ASFFunctions_Pro_x86.ASFGetMask(pEngine, pInfo); - } -#if NET5_0 - else - { - throw new NotSupportedException("Only supported Windows x86 x64 and Linux x64"); - } + { + retCode = ASFFunctions_Pro_x86.ASFGetMask(pEngine, pInfo); } +#if NET5_0_OR_GREATER else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && RuntimeInformation.ProcessArchitecture == Architecture.X64) { @@ -327,33 +298,28 @@ private static ASF_LandMarkInfo FaceLandEstimation(IntPtr pEngine) { IntPtr pInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf()); int retCode = -1; -#if NETSTANDARD2_0 || NET5_0 - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { -#endif - if ( -#if NET5_0 - RuntimeInformation.ProcessArchitecture == Architecture.X64 + + if ( +#if NET5_0_OR_GREATER + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + && RuntimeInformation.ProcessArchitecture == Architecture.X64 #else - Environment.Is64BitProcess + Environment.Is64BitProcess #endif - ) - { - retCode = ASFFunctions_Pro_x64.ASFGetFaceLandMark(pEngine, pInfo); - } - else -#if NET5_0 - if (RuntimeInformation.ProcessArchitecture == Architecture.X86) + ) + { + retCode = ASFFunctions_Pro_x64.ASFGetFaceLandMark(pEngine, pInfo); + } + else +#if NET5_0_OR_GREATER + if ( + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + && RuntimeInformation.ProcessArchitecture == Architecture.X86) #endif - { - retCode = ASFFunctions_Pro_x86.ASFGetFaceLandMark(pEngine, pInfo); - } -#if NET5_0 - else - { - throw new NotSupportedException("Only supported Windows x86 x64 and Linux x64"); - } + { + retCode = ASFFunctions_Pro_x86.ASFGetFaceLandMark(pEngine, pInfo); } +#if NET5_0_OR_GREATER else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && RuntimeInformation.ProcessArchitecture == Architecture.X64) { diff --git a/Src/ASFFunctions.PrivateEx.cs b/Src/ASFFunctions.PrivateEx.cs index 4d100e7..d811e2e 100644 --- a/Src/ASFFunctions.PrivateEx.cs +++ b/Src/ASFFunctions.PrivateEx.cs @@ -1,5 +1,5 @@ using System; -#if NET5_0 +#if NET5_0_OR_GREATER using System.Runtime.InteropServices; #endif using Yj.ArcSoftSDK._4_0.Models; @@ -22,36 +22,31 @@ private static float ASFImageQualityDetectEx(IntPtr pEngine, ASF_SingleFaceInfo float result = -1; try { - IntPtr pSingleFaceInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf()); + IntPtr pSingleFaceInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf()); MemoryUtil.StructureToPtr(faceInfo, pSingleFaceInfo); int retCode = -1; -#if NET5_0 - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { -#endif - if ( -#if NET5_0 - RuntimeInformation.ProcessArchitecture == Architecture.X64 + + if ( +#if NET5_0_OR_GREATER + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + && RuntimeInformation.ProcessArchitecture == Architecture.X64 #else - Environment.Is64BitProcess + Environment.Is64BitProcess #endif - ) - { - retCode = ASFFunctions_Pro_x64.ASFImageQualityDetectEx(pEngine, imageInfo, pSingleFaceInfo, isMask ? 1 : 0, ref result, (int)ASF_DetectModel.ASF_DETECT_MODEL_RGB); - } - else -#if NET5_0 - if (RuntimeInformation.ProcessArchitecture == Architecture.X86) + ) + { + retCode = ASFFunctions_Pro_x64.ASFImageQualityDetectEx(pEngine, imageInfo, pSingleFaceInfo, isMask ? 1 : 0, ref result, (int)ASF_DetectModel.ASF_DETECT_MODEL_RGB); + } + else +#if NET5_0_OR_GREATER + if ( + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + && RuntimeInformation.ProcessArchitecture == Architecture.X86) #endif - { - retCode = ASFFunctions_Pro_x86.ASFImageQualityDetectEx(pEngine, imageInfo, pSingleFaceInfo, isMask ? 1 : 0, ref result, (int)ASF_DetectModel.ASF_DETECT_MODEL_RGB); - } -#if NET5_0 - else - { - throw new NotSupportedException("Only supported Windows x86 x64 and Linux x64"); - } + { + retCode = ASFFunctions_Pro_x86.ASFImageQualityDetectEx(pEngine, imageInfo, pSingleFaceInfo, isMask ? 1 : 0, ref result, (int)ASF_DetectModel.ASF_DETECT_MODEL_RGB); } +#if NET5_0_OR_GREATER else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && RuntimeInformation.ProcessArchitecture == Architecture.X64) { @@ -87,33 +82,28 @@ private static ASF_MultiFaceInfo DetectFaceEx(IntPtr pEngine, IntPtr imageInfo) IntPtr pMultiFaceInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf()); int retCode = -1; -#if NETSTANDARD2_0 || NET5_0 - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { -#endif - if ( -#if NET5_0 - RuntimeInformation.ProcessArchitecture == Architecture.X64 + + if ( +#if NET5_0_OR_GREATER + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + && RuntimeInformation.ProcessArchitecture == Architecture.X64 #else - Environment.Is64BitProcess + Environment.Is64BitProcess #endif - ) - { - retCode = ASFFunctions_Pro_x64.ASFDetectFacesEx(pEngine, imageInfo, pMultiFaceInfo, (int)ASF_DetectModel.ASF_DETECT_MODEL_RGB); - } - else -#if NET5_0 - if (RuntimeInformation.ProcessArchitecture == Architecture.X86) + ) + { + retCode = ASFFunctions_Pro_x64.ASFDetectFacesEx(pEngine, imageInfo, pMultiFaceInfo, (int)ASF_DetectModel.ASF_DETECT_MODEL_RGB); + } + else +#if NET5_0_OR_GREATER + if ( + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + && RuntimeInformation.ProcessArchitecture == Architecture.X86) #endif - { - retCode = ASFFunctions_Pro_x86.ASFDetectFacesEx(pEngine, imageInfo, pMultiFaceInfo, (int)ASF_DetectModel.ASF_DETECT_MODEL_RGB); - } -#if NET5_0 - else - { - throw new NotSupportedException("Only supported Windows x86 x64 and Linux x64"); - } + { + retCode = ASFFunctions_Pro_x86.ASFDetectFacesEx(pEngine, imageInfo, pMultiFaceInfo, (int)ASF_DetectModel.ASF_DETECT_MODEL_RGB); } +#if NET5_0_OR_GREATER else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && RuntimeInformation.ProcessArchitecture == Architecture.X64) { @@ -141,38 +131,32 @@ private static byte[] GetSinglePersonFeatureEx(IntPtr pEngine, ASF_SingleFaceInf byte[] feature = null; int retCode = -1; - IntPtr pSingleFaceInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf()); + IntPtr pSingleFaceInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf()); MemoryUtil.StructureToPtr(faceInfo, pSingleFaceInfo); IntPtr pFaceFeature = MemoryUtil.Malloc(MemoryUtil.SizeOf()); -#if NET5_0 - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { -#endif - if ( -#if NET5_0 - RuntimeInformation.ProcessArchitecture == Architecture.X64 + if ( +#if NET5_0_OR_GREATER + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + && RuntimeInformation.ProcessArchitecture == Architecture.X64 #else - Environment.Is64BitProcess + Environment.Is64BitProcess #endif - ) - { - retCode = ASFFunctions_Pro_x64.ASFFaceFeatureExtractEx(pEngine, imageInfo, pSingleFaceInfo, (int)(isRegister ? ASF_RegisterOrNot.ASF_REGISTER : ASF_RegisterOrNot.ASF_RECOGNITION), hadMask ? 1 : 0, pFaceFeature); - } - else -#if NET5_0 - if (RuntimeInformation.ProcessArchitecture == Architecture.X86) + ) + { + retCode = ASFFunctions_Pro_x64.ASFFaceFeatureExtractEx(pEngine, imageInfo, pSingleFaceInfo, (int)(isRegister ? ASF_RegisterOrNot.ASF_REGISTER : ASF_RegisterOrNot.ASF_RECOGNITION), hadMask ? 1 : 0, pFaceFeature); + } + else +#if NET5_0_OR_GREATER + if ( + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + && RuntimeInformation.ProcessArchitecture == Architecture.X86) #endif - { - retCode = ASFFunctions_Pro_x86.ASFFaceFeatureExtractEx(pEngine, imageInfo, pSingleFaceInfo, (int)(isRegister ? ASF_RegisterOrNot.ASF_REGISTER : ASF_RegisterOrNot.ASF_RECOGNITION), hadMask ? 1 : 0, pFaceFeature); - } -#if NET5_0 - else - { - throw new NotSupportedException("Only supported Windows x86 x64 and Linux x64"); - } + { + retCode = ASFFunctions_Pro_x86.ASFFaceFeatureExtractEx(pEngine, imageInfo, pSingleFaceInfo, (int)(isRegister ? ASF_RegisterOrNot.ASF_REGISTER : ASF_RegisterOrNot.ASF_RECOGNITION), hadMask ? 1 : 0, pFaceFeature); } +#if NET5_0_OR_GREATER else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && RuntimeInformation.ProcessArchitecture == Architecture.X64) { @@ -213,33 +197,28 @@ private static ASF_LivenessInfo LivenessInfoEx_IR(IntPtr pEngine, IntPtr imageIn MemoryUtil.StructureToPtr(multiFaceInfo, pMultiFaceInfo); int retCode = -1; -#if NETSTANDARD2_0 || NET5_0 - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { -#endif - if ( -#if NET5_0 - RuntimeInformation.ProcessArchitecture == Architecture.X64 + + if ( +#if NET5_0_OR_GREATER + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + && RuntimeInformation.ProcessArchitecture == Architecture.X64 #else - Environment.Is64BitProcess + Environment.Is64BitProcess #endif - ) - { - retCode = ASFFunctions_Pro_x64.ASFProcessEx_IR(pEngine, imageInfo, pMultiFaceInfo, (int)FaceEngineMask.ASF_IR_LIVENESS); - } - else -#if NET5_0 - if (RuntimeInformation.ProcessArchitecture == Architecture.X86) + ) + { + retCode = ASFFunctions_Pro_x64.ASFProcessEx_IR(pEngine, imageInfo, pMultiFaceInfo, (int)FaceEngineMask.ASF_IR_LIVENESS); + } + else +#if NET5_0_OR_GREATER + if ( + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + && RuntimeInformation.ProcessArchitecture == Architecture.X86) #endif - { - retCode = ASFFunctions_Pro_x86.ASFProcessEx_IR(pEngine, imageInfo, pMultiFaceInfo, (int)FaceEngineMask.ASF_IR_LIVENESS); - } -#if NET5_0 - else - { - throw new NotSupportedException("Only supported Windows x86 x64 and Linux x64"); - } + { + retCode = ASFFunctions_Pro_x86.ASFProcessEx_IR(pEngine, imageInfo, pMultiFaceInfo, (int)FaceEngineMask.ASF_IR_LIVENESS); } +#if NET5_0_OR_GREATER else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && RuntimeInformation.ProcessArchitecture == Architecture.X64) { @@ -253,33 +232,28 @@ private static ASF_LivenessInfo LivenessInfoEx_IR(IntPtr pEngine, IntPtr imageIn if (retCode == 0) { IntPtr pInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf()); -#if NET5_0 - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { -#endif - if ( -#if NET5_0 - RuntimeInformation.ProcessArchitecture == Architecture.X64 + + if ( +#if NET5_0_OR_GREATER + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + && RuntimeInformation.ProcessArchitecture == Architecture.X64 #else - Environment.Is64BitProcess + Environment.Is64BitProcess #endif - ) - { - retCode = ASFFunctions_Pro_x64.ASFGetLivenessScore_IR(pEngine, pInfo); - } - else -#if NET5_0 - if (RuntimeInformation.ProcessArchitecture == Architecture.X86) + ) + { + retCode = ASFFunctions_Pro_x64.ASFGetLivenessScore_IR(pEngine, pInfo); + } + else +#if NET5_0_OR_GREATER + if ( + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + && RuntimeInformation.ProcessArchitecture == Architecture.X86) #endif - { - retCode = ASFFunctions_Pro_x86.ASFGetLivenessScore_IR(pEngine, pInfo); - } -#if NET5_0 - else - { - throw new NotSupportedException("Only supported Windows x86 x64 and Linux x64"); - } + { + retCode = ASFFunctions_Pro_x86.ASFGetLivenessScore_IR(pEngine, pInfo); } +#if NET5_0_OR_GREATER else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && RuntimeInformation.ProcessArchitecture == Architecture.X64) { @@ -318,33 +292,28 @@ private static IntPtr FaceInfoProcessEx(IntPtr pEngine, IntPtr imageInfo, ASF_Mu IntPtr pMultiFaceInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf()); MemoryUtil.StructureToPtr(multiFaceInfo, pMultiFaceInfo); int retCode = -1; -#if NET5_0 - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { -#endif - if ( -#if NET5_0 - RuntimeInformation.ProcessArchitecture == Architecture.X64 + + if ( +#if NET5_0_OR_GREATER + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + && RuntimeInformation.ProcessArchitecture == Architecture.X64 #else - Environment.Is64BitProcess + Environment.Is64BitProcess #endif - ) - { - retCode = ASFFunctions_Pro_x64.ASFProcessEx(pEngine, imageInfo, pMultiFaceInfo, (int)faceEngineMask); - } - else -#if NET5_0 - if (RuntimeInformation.ProcessArchitecture == Architecture.X86) + ) + { + retCode = ASFFunctions_Pro_x64.ASFProcessEx(pEngine, imageInfo, pMultiFaceInfo, (int)faceEngineMask); + } + else +#if NET5_0_OR_GREATER + if ( + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + && RuntimeInformation.ProcessArchitecture == Architecture.X86) #endif - { - retCode = ASFFunctions_Pro_x86.ASFProcessEx(pEngine, imageInfo, pMultiFaceInfo, (int)faceEngineMask); - } -#if NET5_0 - else - { - throw new NotSupportedException("Only supported Windows x86 x64 and Linux x64"); - } + { + retCode = ASFFunctions_Pro_x86.ASFProcessEx(pEngine, imageInfo, pMultiFaceInfo, (int)faceEngineMask); } +#if NET5_0_OR_GREATER else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && RuntimeInformation.ProcessArchitecture == Architecture.X64) { diff --git a/Src/ASFFunctions.SetFaceInfo.cs b/Src/ASFFunctions.SetFaceInfo.cs index d8202f7..40348e8 100644 --- a/Src/ASFFunctions.SetFaceInfo.cs +++ b/Src/ASFFunctions.SetFaceInfo.cs @@ -1,5 +1,4 @@ using System; -using System.Drawing; using System.Runtime.InteropServices; using Yj.ArcSoftSDK._4_0.Models; using Yj.ArcSoftSDK._4_0.Utils; @@ -58,10 +57,10 @@ private static void SetFaceInfo(bool hadFaceInfo, ASF_AgeInfo ageInfo, ASF_Gende var faceLandmark = MemoryUtil.PtrToStructure(lanMaskInfo.Point + MemoryUtil.SizeOf() * i); faceInfo.FaceLandPoint = new PointF(faceLandmark.X, faceLandmark.Y); } - else - { - faceInfo.FaceLandPoint = new PointF(-1f, -1f); - } + //else + //{ + // faceInfo.FaceLandPoint = new PointF(-1f, -1f); + //} if (face3DAngleInfo.Num > i) { faceInfo.Face3DAngle.Status = 0; @@ -81,21 +80,23 @@ private static void SetFaceInfo(bool hadFaceInfo, ASF_AgeInfo ageInfo, ASF_Gende faceInfo.Gender = -1; faceInfo.Face3DAngle.Status = -1; faceInfo.Mask = -1; - faceInfo.FaceLandPoint = new PointF(-1f, -1f); + //faceInfo.FaceLandPoint = new PointF(-1f, -1f); } if (hadRgbLive - && rgbLiveInfo.Num == 1) + //&& rgbLiveInfo.Num == 1 + && i==0) { - faceInfo.RgbLive = MemoryUtil.PtrToStructure(rgbLiveInfo.IsLive); + faceInfo.RgbLive = MemoryUtil.PtrToStructure(rgbLiveInfo.IsLive + MemoryUtil.SizeOf() * i); } else { faceInfo.RgbLive = -2; } if (hadRIrLive - && irLiveInfo.Num == 1) + && irLiveInfo.Num == 1 + && i == 0) { - faceInfo.IrLive = MemoryUtil.PtrToStructure(irLiveInfo.IsLive); + faceInfo.IrLive = MemoryUtil.PtrToStructure(irLiveInfo.IsLive + MemoryUtil.SizeOf() * i); } else { @@ -120,6 +121,7 @@ private static FaceInfo CreateFaceInfo(ASF_MultiFaceInfo multiFaceInfo, int[] or FaceOrient = (ASF_OrientCode)orienArry[i], FaceDataInfo = MemoryUtil.PtrToStructure(multiFaceInfo.FaceDataInfoList + MemoryUtil.SizeOf() * i), }, + WearGlasses = MemoryUtil.PtrToStructure(multiFaceInfo.WearGlasses + MemoryUtil.SizeOf() * i), IsLeftEyeClosed = MemoryUtil.PtrToStructure(multiFaceInfo.LeftEyeClosed + MemoryUtil.SizeOf() * i) == 1, IsRightEyeClosed = MemoryUtil.PtrToStructure(multiFaceInfo.RightEyeClosed + MemoryUtil.SizeOf() * i) == 1, FaceShelter = MemoryUtil.PtrToStructure(multiFaceInfo.FaceShelter + MemoryUtil.SizeOf() * i), @@ -225,7 +227,7 @@ private static int[] ReadyFaceinStruct(IntPtr pEngine, bool needFaceInfo, bool n lanMaskInfo = FaceLandEstimation(pEngine); } if (needRgbLive - && multiFaceInfo.FaceNum == 1) + /* && multiFaceInfo.FaceNum == 1*/) { hadRgbLive = true; rgbLiveInfo = LivenessInfo_RGB(pEngine); @@ -250,10 +252,9 @@ private static int[] ReadyFaceinStruct(IntPtr pEngine, bool needFaceInfo, bool n /// /// /// - /// /// /// - private static FaceEngineMask SetEngineMask(bool needFaceInfo, bool needRgbLive,bool needImageQuality, ASF_MultiFaceInfo multiFaceInfo) + private static FaceEngineMask SetEngineMask(bool needFaceInfo, bool needRgbLive, ASF_MultiFaceInfo multiFaceInfo) { FaceEngineMask engineMask = FaceEngineMask.ASF_NONE; if (needFaceInfo && multiFaceInfo.FaceNum >= 1) @@ -261,14 +262,10 @@ private static FaceEngineMask SetEngineMask(bool needFaceInfo, bool needRgbLive, engineMask |= FaceEngineMask.ASF_AGE | FaceEngineMask.ASF_GENDER | FaceEngineMask.ASF_FACE3DANGLE | FaceEngineMask.ASF_FACELANDMARK | FaceEngineMask.ASF_MASKDETECT;// | FaceEngineMask.ASF_FACESHELTER | FaceEngineMask.ASF_UPDATE_FACEDATA; } - if (needRgbLive && multiFaceInfo.FaceNum == 1) + if (needRgbLive/* && multiFaceInfo.FaceNum == 1*/) { engineMask |= FaceEngineMask.ASF_LIVENESS; } - //if (needImageQuality && multiFaceInfo.FaceNum >= 1) - //{ - // engineMask |= FaceEngineMask.ASF_IMAGEQUALITY; - //} return engineMask; } diff --git a/Src/ASFFunctions.cs b/Src/ASFFunctions.cs index b853a38..49a41d6 100644 --- a/Src/ASFFunctions.cs +++ b/Src/ASFFunctions.cs @@ -1,9 +1,12 @@ -using System; -using System.Collections.Generic; +#if (NET40) using System.Drawing; -#if NET5_0 -using System.Runtime.InteropServices; +using System.IO; +#else +using SkiaSharp; #endif +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; using Yj.ArcSoftSDK._4_0.Models; using Yj.ArcSoftSDK._4_0.Utils; @@ -30,94 +33,89 @@ public static int Activation(string appId, string x86SdkKey, string x64SdkKey, s , string x86ProActiveKey = null, string x64ProActiveKey = null, string sox64ProActiveKey = null) { int result = -1; -#if NET5_0 - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { -#endif - if ( -#if NET5_0 - RuntimeInformation.ProcessArchitecture == Architecture.X64 + + if ( +#if NET5_0_OR_GREATER + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + && RuntimeInformation.ProcessArchitecture == Architecture.X64 #else - Environment.Is64BitProcess + Environment.Is64BitProcess #endif - ) - { - ASF_ActiveFileInfo aSF_ActiveFileInfo = default; - IntPtr pASF_ActiveFileInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf()); + ) + { + ASF_ActiveFileInfo aSF_ActiveFileInfo = default; + IntPtr pASF_ActiveFileInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf()); - if (!string.IsNullOrEmpty(x64ProActiveKey)) - { - result = ASFFunctions_Pro_x64.ASFGetActiveFileInfo(pASF_ActiveFileInfo); - } + if (!string.IsNullOrEmpty(x64ProActiveKey)) + { + result = ASFFunctions_Pro_x64.ASFGetActiveFileInfo(pASF_ActiveFileInfo); + } - if (result == 0) - { - aSF_ActiveFileInfo = MemoryUtil.PtrToStructure(pASF_ActiveFileInfo); - } - if (result == 0 - && long.TryParse(aSF_ActiveFileInfo.EndTime, out long endTime) - && long.TryParse(aSF_ActiveFileInfo.StartTime, out long startTime) - && (DateTime.Now.ToTimestamp() / 1000) < endTime - && (DateTime.Now.ToTimestamp() / 1000) >= startTime - && (aSF_ActiveFileInfo.Platform == "windows_x64" || aSF_ActiveFileInfo.SdkType == "windows_x64")) - { - return result; - } + if (result == 0) + { + aSF_ActiveFileInfo = MemoryUtil.PtrToStructure(pASF_ActiveFileInfo); + } + if (result == 0 + && long.TryParse(aSF_ActiveFileInfo.EndTime, out long endTime) + && long.TryParse(aSF_ActiveFileInfo.StartTime, out long startTime) + && (DateTime.Now.ToTimestamp() / 1000) < endTime + && (DateTime.Now.ToTimestamp() / 1000) >= startTime + && (aSF_ActiveFileInfo.Platform == "windows_x64" || aSF_ActiveFileInfo.SdkType == "windows_x64")) + { + return result; + } - if (!string.IsNullOrEmpty(x64ProActiveKey)) + if (!string.IsNullOrEmpty(x64ProActiveKey)) + { + result = ASFFunctions_Pro_x64.ASFOnlineActivation(appId, x64SdkKey, x64ProActiveKey); + if (result != 0 + && System.IO.File.Exists("ArcFacePro64.dat")) { + System.IO.File.Delete("ArcFacePro64.dat"); result = ASFFunctions_Pro_x64.ASFOnlineActivation(appId, x64SdkKey, x64ProActiveKey); - if (result != 0 - && System.IO.File.Exists("ArcFacePro64.dat")) - { - System.IO.File.Delete("ArcFacePro64.dat"); - result = ASFFunctions_Pro_x64.ASFOnlineActivation(appId, x64SdkKey, x64ProActiveKey); - } } } - else -#if NET5_0 - if (RuntimeInformation.ProcessArchitecture == Architecture.X86) + } + else +#if NET5_0_OR_GREATER + if ( + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + && RuntimeInformation.ProcessArchitecture == Architecture.X86) #endif - { - ASF_ActiveFileInfo aSF_ActiveFileInfo = default; - IntPtr pASF_ActiveFileInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf()); + { + ASF_ActiveFileInfo aSF_ActiveFileInfo = default; + IntPtr pASF_ActiveFileInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf()); - if (!string.IsNullOrEmpty(x86ProActiveKey)) - { - result = ASFFunctions_Pro_x86.ASFGetActiveFileInfo(pASF_ActiveFileInfo); - } + if (!string.IsNullOrEmpty(x86ProActiveKey)) + { + result = ASFFunctions_Pro_x86.ASFGetActiveFileInfo(pASF_ActiveFileInfo); + } - if (result == 0) - { - aSF_ActiveFileInfo = MemoryUtil.PtrToStructure(pASF_ActiveFileInfo); - } - if (result == 0 - && long.TryParse(aSF_ActiveFileInfo.EndTime, out long endTime) - && long.TryParse(aSF_ActiveFileInfo.StartTime, out long startTime) - && (DateTime.Now.ToTimestamp() / 1000) < endTime - && (DateTime.Now.ToTimestamp() / 1000) >= startTime - && (aSF_ActiveFileInfo.Platform == "windows_x86" || aSF_ActiveFileInfo.SdkType == "windows_x86")) - { - return result; - } - if (!string.IsNullOrEmpty(x86ProActiveKey)) + if (result == 0) + { + aSF_ActiveFileInfo = MemoryUtil.PtrToStructure(pASF_ActiveFileInfo); + } + if (result == 0 + && long.TryParse(aSF_ActiveFileInfo.EndTime, out long endTime) + && long.TryParse(aSF_ActiveFileInfo.StartTime, out long startTime) + && (DateTime.Now.ToTimestamp() / 1000) < endTime + && (DateTime.Now.ToTimestamp() / 1000) >= startTime + && (aSF_ActiveFileInfo.Platform == "windows_x86" || aSF_ActiveFileInfo.SdkType == "windows_x86")) + { + return result; + } + if (!string.IsNullOrEmpty(x86ProActiveKey)) + { + result = ASFFunctions_Pro_x86.ASFOnlineActivation(appId, x86SdkKey, x86ProActiveKey); + if (result != 0 + && System.IO.File.Exists("ArcFacePro32.dat")) { + System.IO.File.Delete("ArcFacePro32.dat"); result = ASFFunctions_Pro_x86.ASFOnlineActivation(appId, x86SdkKey, x86ProActiveKey); - if (result != 0 - && System.IO.File.Exists("ArcFacePro32.dat")) - { - System.IO.File.Delete("ArcFacePro32.dat"); - result = ASFFunctions_Pro_x86.ASFOnlineActivation(appId, x86SdkKey, x86ProActiveKey); - } } } -#if NET5_0 - else - { - throw new NotSupportedException("Only supported Windows x86 x64 and Linux x64"); - } } +#if NET5_0_OR_GREATER else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && RuntimeInformation.ProcessArchitecture == Architecture.X64) { @@ -218,43 +216,35 @@ public static int InitEngine(ref IntPtr pEngine, bool isImgMode = false, int fac } //初始化引擎,正常值为0,其他返回值请参考http://ai.arcsoft.com.cn/bbs/forum.php?mod=viewthread&tid=19&_dsign=dbad527e -#if NET5_0 - Console.WriteLine($"OSPlatform.Linux: {RuntimeInformation.IsOSPlatform(OSPlatform.Linux)} Environment.Is64BitProcess: { Environment.Is64BitProcess}"); - Console.WriteLine($"combinedMask: {combinedMask}"); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { -#endif - if ( -#if NET5_0 - RuntimeInformation.ProcessArchitecture == Architecture.X64 + if ( +#if NET5_0_OR_GREATER + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + && RuntimeInformation.ProcessArchitecture == Architecture.X64 #else - Environment.Is64BitProcess + Environment.Is64BitProcess #endif - ) + ) + { + result = ASFFunctions_Pro_x64.ASFInitEngine((uint)detectMode, (int)detectFaceOrientPriority, faceMaxNum, (int)combinedMask, ref pEngine); + if (result == 0 && needFaceInfo) { - result = ASFFunctions_Pro_x64.ASFInitEngine((uint)detectMode, (int)detectFaceOrientPriority, faceMaxNum, (int)combinedMask, ref pEngine); - if (result == 0 && needFaceInfo) - { - result = ASFFunctions_Pro_x64.ASFSetFaceShelterParam(pEngine, shelterThreshhold); - } + result = ASFFunctions_Pro_x64.ASFSetFaceShelterParam(pEngine, shelterThreshhold); } - else -#if NET5_0 - if (RuntimeInformation.ProcessArchitecture == Architecture.X86) + } + else +#if NET5_0_OR_GREATER + if ( + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + && RuntimeInformation.ProcessArchitecture == Architecture.X86) #endif + { + result = ASFFunctions_Pro_x86.ASFInitEngine((uint)detectMode, (int)detectFaceOrientPriority, faceMaxNum, (int)combinedMask, ref pEngine); + if (result == 0 && needFaceInfo) { - result = ASFFunctions_Pro_x86.ASFInitEngine((uint)detectMode, (int)detectFaceOrientPriority, faceMaxNum, (int)combinedMask, ref pEngine); - if (result == 0 && needFaceInfo) - { - result = ASFFunctions_Pro_x86.ASFSetFaceShelterParam(pEngine, shelterThreshhold); - } - } -#if NET5_0 - else - { - throw new NotSupportedException("Only supported Windows x86 x64 and Linux x64"); + result = ASFFunctions_Pro_x86.ASFSetFaceShelterParam(pEngine, shelterThreshhold); } } +#if NET5_0_OR_GREATER else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && RuntimeInformation.ProcessArchitecture == Architecture.X64) { @@ -280,33 +270,27 @@ public static int InitEngine(ref IntPtr pEngine, bool isImgMode = false, int fac public static int UninitEngine(ref IntPtr pEngine) { int result = -1; -#if NET5_0 - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { -#endif - if ( -#if NET5_0 - RuntimeInformation.ProcessArchitecture == Architecture.X64 + if ( +#if NET5_0_OR_GREATER + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + && RuntimeInformation.ProcessArchitecture == Architecture.X64 #else - Environment.Is64BitProcess + Environment.Is64BitProcess #endif - ) - { - result = ASFFunctions_Pro_x64.ASFUninitEngine(pEngine); - } - else -#if NET5_0 - if (RuntimeInformation.ProcessArchitecture == Architecture.X86) + ) + { + result = ASFFunctions_Pro_x64.ASFUninitEngine(pEngine); + } + else +#if NET5_0_OR_GREATER + if ( + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + && RuntimeInformation.ProcessArchitecture == Architecture.X86) #endif - { - result = ASFFunctions_Pro_x86.ASFUninitEngine(pEngine); - } -#if NET5_0 - else - { - throw new NotSupportedException("Only supported Windows x86 x64 and Linux x64"); - } + { + result = ASFFunctions_Pro_x86.ASFUninitEngine(pEngine); } +#if NET5_0_OR_GREATER else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && RuntimeInformation.ProcessArchitecture == Architecture.X64) { @@ -325,7 +309,7 @@ public static int UninitEngine(ref IntPtr pEngine) /// 获取人脸 信息 /// /// - /// + /// /// /// /// 需要角度、性别、年龄信息 @@ -335,16 +319,24 @@ public static int UninitEngine(ref IntPtr pEngine) /// 是否需要图像质量检测(只对虹软商用授权有效) /// 算法登记照(只对4.0算法有效) /// - public static List DetectFacesEx(IntPtr pEngine, Image image, int faceMinWith = 0, + public static List DetectFacesEx(IntPtr pEngine, byte[] imageBuffer, int faceMinWith = 0, bool needCheckImage = true, bool needFaceInfo = false, bool needRgbLive = false, bool needIrLive = false, bool needFeatures = false, bool needImageQuality = false, bool isRegister = true) { - Image needImage = image; +#if (NET40) + Image needImage = null; + using (MemoryStream ms = new MemoryStream(imageBuffer)) + { + needImage = new Bitmap(ms); + } +#else + SKBitmap needImage = SKBitmap.Decode(imageBuffer); +#endif if (needCheckImage) { needImage = ImageUtil.CheckImage(needImage); } - var imageInfo = ImageUtil.GetImageData(needImage, needCheckImage); + var imageInfo = ImageUtil.GetImageData(needImage); List result = DetectFacesEx(pEngine, imageInfo, faceMinWith, needFaceInfo, needRgbLive, needIrLive , needFeatures, needImageQuality, isRegister); if(imageInfo.ppu8Plane[0]!=IntPtr.Zero) @@ -396,10 +388,10 @@ public static List DetectFacesEx(IntPtr pEngine, ASVL_OFFSCREEN imageI // 是否有获取RGB活体 bool hadRgbLive = false; // 是否有获取IR活体 - bool hadRIrLive = false; + bool hadIrLive = false; IntPtr pMultiFaceInfo = IntPtr.Zero; - FaceEngineMask engineMask = SetEngineMask(needFaceInfo, needRgbLive, needImageQuality, multiFaceInfo); + FaceEngineMask engineMask = SetEngineMask(needFaceInfo, needRgbLive, multiFaceInfo); if (engineMask != FaceEngineMask.ASF_NONE) { @@ -410,9 +402,9 @@ public static List DetectFacesEx(IntPtr pEngine, ASVL_OFFSCREEN imageI ref maskInfo, ref lanMaskInfo); if (needIrLive - && multiFaceInfo.FaceNum == 1) + /*&& multiFaceInfo.FaceNum == 1*/) { - hadRIrLive = true; + hadIrLive = true; irLiveInfo = LivenessInfoEx_IR(pEngine, imageInfoPtr, multiFaceInfo); } @@ -428,7 +420,7 @@ public static List DetectFacesEx(IntPtr pEngine, ASVL_OFFSCREEN imageI result.Add(faceInfo); SetFaceInfo(hadFaceInfo, ageInfo, genderInfo, face3DAngleInfo, rgbLiveInfo, irLiveInfo, maskInfo, lanMaskInfo, hadRgbLive, - hadRIrLive, i, faceInfo); + hadIrLive, i, faceInfo); if (needImageQuality) { faceInfo.ImageQuality = ASFImageQualityDetectEx(pEngine, faceInfo.ASF_FaceInfo, imageInfoPtr, faceInfo.Mask == 1); @@ -452,13 +444,13 @@ public static List DetectFacesEx(IntPtr pEngine, ASVL_OFFSCREEN imageI /// 获取人脸个数 /// /// - /// + /// /// 人脸最小宽度 /// /// - public static int GetFaceNum(IntPtr pEngine, Image image, int faceMinWith = 0, bool needCheckImage = true) + public static int GetFaceNum(IntPtr pEngine, byte[] imageBuffer, int faceMinWith = 0, bool needCheckImage = true) { - return DetectFacesEx(pEngine, image, faceMinWith, needCheckImage).Count; + return DetectFacesEx(pEngine, imageBuffer, faceMinWith, needCheckImage).Count; } /// @@ -499,34 +491,28 @@ public static float FaceFeatureCompare(IntPtr pEngine, IntPtr pFaceFeature1, Int float result = -1; int retCode = -1; ASF_CompareModel compareModel = isIdcardCompare ? ASF_CompareModel.ASF_ID_PHOTO : ASF_CompareModel.ASF_LIFE_PHOTO; -#if NETSTANDARD2_0 || NET5_0 - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { -#endif - if ( -#if NET5_0 - RuntimeInformation.ProcessArchitecture == Architecture.X64 + + if ( +#if NET5_0_OR_GREATER + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + && RuntimeInformation.ProcessArchitecture == Architecture.X64 #else - Environment.Is64BitProcess + Environment.Is64BitProcess #endif - ) - { - retCode = ASFFunctions_Pro_x64.ASFFaceFeatureCompare(pEngine, pFaceFeature1, pFaceFeature2, ref result, (int)compareModel); - } - else -#if NET5_0 - if (RuntimeInformation.ProcessArchitecture == Architecture.X86) + ) + { + retCode = ASFFunctions_Pro_x64.ASFFaceFeatureCompare(pEngine, pFaceFeature1, pFaceFeature2, ref result, (int)compareModel); + } + else +#if NET5_0_OR_GREATER + if ( + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + && RuntimeInformation.ProcessArchitecture == Architecture.X86) #endif - { - retCode = ASFFunctions_Pro_x86.ASFFaceFeatureCompare(pEngine, pFaceFeature1, pFaceFeature2, ref result, (int)compareModel); - - } -#if NET5_0 - else - { - throw new NotSupportedException("Only supported Windows x86 x64 and Linux x64"); - } + { + retCode = ASFFunctions_Pro_x86.ASFFaceFeatureCompare(pEngine, pFaceFeature1, pFaceFeature2, ref result, (int)compareModel); } +#if NET5_0_OR_GREATER else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && RuntimeInformation.ProcessArchitecture == Architecture.X64) { diff --git a/Src/ASFFunctions_Pro_Sox64.cs b/Src/ASFFunctions_Pro_Sox64.cs index dd2c7a9..e0c08bb 100644 --- a/Src/ASFFunctions_Pro_Sox64.cs +++ b/Src/ASFFunctions_Pro_Sox64.cs @@ -150,7 +150,7 @@ internal static class ASFFunctions_Pro_Sox64 /// 待比较人脸特征1 /// 待比较人脸特征2 /// 相似度(0.0~1.0) - /// 选择人脸特征比对模型 + /// 选择人脸特征比对模型 /// 调用结果 [DllImport(Dll_PATH, CallingConvention = CallingConvention.Cdecl)] public static extern int ASFFaceFeatureCompare(IntPtr pEngine, IntPtr faceFeature1, IntPtr faceFeature2, ref float similarity, int compareModel); diff --git a/Src/ASFFunctions_Pro_x64.cs b/Src/ASFFunctions_Pro_x64.cs index 384c359..d128445 100644 --- a/Src/ASFFunctions_Pro_x64.cs +++ b/Src/ASFFunctions_Pro_x64.cs @@ -12,7 +12,7 @@ internal static class ASFFunctions_Pro_x64 /// /// SDK动态链接库路径 /// - public const string Dll_PATH = ".\\ArcProLib\\x64\\libarcsoft_face_engine.dll"; + public const string Dll_PATH = ".\\ArcProLib\\x64_4.0\\libarcsoft_face_engine.dll"; /// /// 激活人脸识别SDK引擎函数 @@ -183,7 +183,7 @@ internal static class ASFFunctions_Pro_x64 /// 0.0~1.0 /// [DllImport(Dll_PATH, CallingConvention = CallingConvention.Cdecl)] - public static extern int ASFSetFaceShelterParam(IntPtr pEngine,float shelterThreshhold); + public static extern int ASFSetFaceShelterParam(IntPtr pEngine, float shelterThreshhold); /// /// 获取人脸是否戴口罩 diff --git a/Src/ASFFunctions_Pro_x86.cs b/Src/ASFFunctions_Pro_x86.cs index 134d560..4bba957 100644 --- a/Src/ASFFunctions_Pro_x86.cs +++ b/Src/ASFFunctions_Pro_x86.cs @@ -12,7 +12,7 @@ internal static class ASFFunctions_Pro_x86 /// /// SDK动态链接库路径 /// - public const string Dll_PATH = ".\\ArcProLib\\x86\\libarcsoft_face_engine.dll"; + public const string Dll_PATH = ".\\ArcProLib\\x86_4.0\\libarcsoft_face_engine.dll"; /// /// 激活人脸识别SDK引擎函数 @@ -55,7 +55,7 @@ internal static class ASFFunctions_Pro_x86 /// 预留字段 暂时使用 /// 调用结果 [DllImport(Dll_PATH, CallingConvention = CallingConvention.Cdecl)] - public static extern int ASFImageQualityDetectEx(IntPtr pEngine, IntPtr imgData, IntPtr faceInfo, int isMask,ref float confidenceLevel, int detectModel); + public static extern int ASFImageQualityDetectEx(IntPtr pEngine, IntPtr imgData, IntPtr faceInfo, int isMask, ref float confidenceLevel, int detectModel); /// /// 人脸检测 @@ -152,7 +152,7 @@ internal static class ASFFunctions_Pro_x86 /// 待比较人脸特征1 /// 待比较人脸特征2 /// 相似度(0.0~1.0) - /// 选择人脸特征比对模型 + /// 选择人脸特征比对模型 /// 调用结果 [DllImport(Dll_PATH, CallingConvention = CallingConvention.Cdecl)] public static extern int ASFFaceFeatureCompare(IntPtr pEngine, IntPtr faceFeature1, IntPtr faceFeature2, ref float similarity, int compareModel); diff --git a/Src/ArcProLib/Sox64/libarcsoft_face_engine.so b/Src/ArcProLib/Sox64/libarcsoft_face_engine.so deleted file mode 100644 index 586b24f..0000000 Binary files a/Src/ArcProLib/Sox64/libarcsoft_face_engine.so and /dev/null differ diff --git a/Src/ArcProLib/Sox64/libarcsoft_face.so b/Src/ArcProLib/Sox64_4.0/libarcsoft_face.so similarity index 96% rename from Src/ArcProLib/Sox64/libarcsoft_face.so rename to Src/ArcProLib/Sox64_4.0/libarcsoft_face.so index b294db3..5b75678 100644 Binary files a/Src/ArcProLib/Sox64/libarcsoft_face.so and b/Src/ArcProLib/Sox64_4.0/libarcsoft_face.so differ diff --git a/Src/ArcProLib/Sox64_4.0/libarcsoft_face_engine.so b/Src/ArcProLib/Sox64_4.0/libarcsoft_face_engine.so new file mode 100644 index 0000000..21c4469 Binary files /dev/null and b/Src/ArcProLib/Sox64_4.0/libarcsoft_face_engine.so differ diff --git a/Src/ArcProLib/x64/libarcsoft_face.dll b/Src/ArcProLib/x64_4.0/libarcsoft_face.dll similarity index 100% rename from Src/ArcProLib/x64/libarcsoft_face.dll rename to Src/ArcProLib/x64_4.0/libarcsoft_face.dll diff --git a/Src/ArcProLib/x64/libarcsoft_face_engine.dll b/Src/ArcProLib/x64_4.0/libarcsoft_face_engine.dll similarity index 100% rename from Src/ArcProLib/x64/libarcsoft_face_engine.dll rename to Src/ArcProLib/x64_4.0/libarcsoft_face_engine.dll diff --git a/Src/ArcProLib/x86/libarcsoft_face.dll b/Src/ArcProLib/x86_4.0/libarcsoft_face.dll similarity index 100% rename from Src/ArcProLib/x86/libarcsoft_face.dll rename to Src/ArcProLib/x86_4.0/libarcsoft_face.dll diff --git a/Src/ArcProLib/x86/libarcsoft_face_engine.dll b/Src/ArcProLib/x86_4.0/libarcsoft_face_engine.dll similarity index 100% rename from Src/ArcProLib/x86/libarcsoft_face_engine.dll rename to Src/ArcProLib/x86_4.0/libarcsoft_face_engine.dll diff --git a/Src/Models/ASF_DetectModel.cs b/Src/Models/ASF_DetectModel.cs index 0a18823..a1c3fd5 100644 --- a/Src/Models/ASF_DetectModel.cs +++ b/Src/Models/ASF_DetectModel.cs @@ -6,7 +6,7 @@ internal enum ASF_DetectModel { /// - /// /RGB图像检测模型 + /// RGB图像检测模型 /// ASF_DETECT_MODEL_RGB = 0x1, diff --git a/Src/Models/ASF_FaceInfo.cs b/Src/Models/ASF_FaceInfo.cs index 95f9a2f..1c1c530 100644 --- a/Src/Models/ASF_FaceInfo.cs +++ b/Src/Models/ASF_FaceInfo.cs @@ -13,7 +13,7 @@ public class FaceInfo /// /// 人脸坐标Rect结果 /// - public System.Drawing.Rectangle Rectangle { internal set; get; } + public Rectangle Rectangle { internal set; get; } /// /// 头像角度 @@ -37,7 +37,7 @@ public class FaceInfo /// /// RGB 活体 - /// 0:非真人;1:真人;-1:不确定;-2:传入人脸数>1; + /// 0:非真人;1:真人;-1:不确定;-2:传入人脸数>1;-3: 人脸过小 -4: 角度过大 -5: 人脸超出边界 -6: 深度图错误 -7: 红外图太亮了 /// public int RgbLive { internal set; get; } @@ -66,7 +66,10 @@ public class FaceInfo /// 口罩 "0" 代表没有带口罩,"1"代表带口罩 ,"-1"表不确定 /// public int Mask { set; get; } - + /// + /// 戴眼镜置信度[0-1],推荐阈值0.5 + /// + public float WearGlasses { set; get; } /// /// 左眼状态 /// @@ -82,7 +85,7 @@ public class FaceInfo /// /// 额头坐标 Empty 表示无效 /// - public System.Drawing.PointF FaceLandPoint { set; get; } + public PointF FaceLandPoint { set; get; } = PointF.Empty; } /// diff --git a/Src/Models/ASF_LivenessInfo.cs b/Src/Models/ASF_LivenessInfo.cs index af58096..2c36df1 100644 --- a/Src/Models/ASF_LivenessInfo.cs +++ b/Src/Models/ASF_LivenessInfo.cs @@ -9,7 +9,7 @@ internal struct ASF_LivenessInfo { /// /// 是否是真人 - /// 0:非真人;1:真人;-1:不确定;-2:传入人脸数>1; + /// 0:非真人;1:真人;-1:不确定;-2:传入人脸数>1;-3: 人脸过小 -4: 角度过大 -5: 人脸超出边界 -6: 深度图错误 -7: 红外图太亮了 /// public IntPtr IsLive; diff --git a/Src/Models/ImageInfo.cs b/Src/Models/ImageInfo.cs index 65ff178..610ac0a 100644 --- a/Src/Models/ImageInfo.cs +++ b/Src/Models/ImageInfo.cs @@ -26,5 +26,9 @@ public class ImageInfo /// 图片格式 /// public ASF_ImagePixelFormat Format { get; set; } + /// + /// 步长 + /// + public int WidthStep { get; set; } } } \ No newline at end of file diff --git a/Src/Models/LPASF_ImageData.cs b/Src/Models/LPASF_ImageData.cs index bb25237..ebcaeff 100644 --- a/Src/Models/LPASF_ImageData.cs +++ b/Src/Models/LPASF_ImageData.cs @@ -25,13 +25,13 @@ internal struct LPASF_ImageData /// /// 图像数据 /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4, ArraySubType = System.Runtime.InteropServices.UnmanagedType.SysUInt)] + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4, ArraySubType = UnmanagedType.SysUInt)] public System.IntPtr[] ppu8Plane; /// /// /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4, ArraySubType = System.Runtime.InteropServices.UnmanagedType.I4)] + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4, ArraySubType = UnmanagedType.I4)] public int[] pi32Pitch; } } \ No newline at end of file diff --git a/Src/Models/Rectangle.cs b/Src/Models/Rectangle.cs new file mode 100644 index 0000000..5759793 --- /dev/null +++ b/Src/Models/Rectangle.cs @@ -0,0 +1,259 @@ +using System; + +namespace Yj.ArcSoftSDK._4_0.Models +{ + /// + /// + /// + public struct Rectangle + { + /// + /// + /// + public static readonly Rectangle Empty; + + /// + /// + /// + public int X { set; get; } + + /// + /// + /// + public int Y { set; get; } + + /// + /// + /// + public int Width { set; get; } + + /// + /// + /// + public int Height { set; get; } + + /// + /// + /// + public int Left => X; + + /// + /// + /// + public int Top => Y; + + /// + /// + /// + public int Right => X + Width; + + /// + /// + /// + public int Bottom => Y + Height; + /// + /// + /// + public bool IsEmpty + { + get + { + if (Height == 0 && Width == 0 && X == 0) + { + return Y == 0; + } + + return false; + } + } + /// + /// + /// + /// + /// + /// + /// + public Rectangle(int x, int y, int width, int height) + { + X = x; + Y = y; + Width = width; + Height = height; + } + + /// + /// + /// + /// + /// + /// + /// + /// + public static Rectangle FromLTRB(int left, int top, int right, int bottom) + { + return new Rectangle(left, top, right - left, bottom - top); + } + + /// + /// + /// + /// + public override bool Equals(object obj) + { + if (!(obj is Rectangle)) + { + return false; + } + + Rectangle rectangle = (Rectangle)obj; + if (rectangle.X == X && rectangle.Y == Y && rectangle.Width == Width) + { + return rectangle.Height == Height; + } + + return false; + } + + /// + /// + /// + /// + public static bool operator ==(Rectangle left, Rectangle right) + { + if (left.X == right.X && left.Y == right.Y && left.Width == right.Width) + { + return left.Height == right.Height; + } + + return false; + } + + /// + /// + /// + /// + public static bool operator !=(Rectangle left, Rectangle right) + { + return !(left == right); + } + + /// + /// + /// + /// + public override int GetHashCode() + { + return X ^ (Y << 13 | (int)((uint)Y >> 19)) ^ (Width << 26 | (int)((uint)Width >> 6)) ^ (Height << 7 | (int)((uint)Height >> 25)); + } + + /// + /// + /// + /// + public override string ToString() + { + return "{X=" + X + ",Y=" + Y + ",Width=" + Width + ",Height=" + Height + "}"; + } + } + /// + /// + /// + public struct PointF : IEquatable + { + /// + /// + /// + public static readonly PointF Empty; + + /// + /// + /// + public bool IsEmpty + { + get + { + return Math.Abs(X - 0.0d) < double.Epsilon + && Math.Abs(Y - 0.0d) < double.Epsilon; + } + } + /// + /// + /// + public float X { set; get; } + /// + /// + /// + public float Y { set; get; } + /// + /// + /// + /// + /// + /// + public PointF(float x, float y) + { + X = x; + Y = y; + } + + /// + /// + /// + /// + /// + /// + public bool Equals(PointF other) + { + throw null; + } + + /// + /// + /// + /// + /// + public override bool Equals(object obj) + { + if (!(obj is PointF)) + { + return false; + } + + PointF pointF = (PointF)obj; + return Math.Abs(pointF.X - X) < double.Epsilon + && Math.Abs(pointF.Y - Y) < double.Epsilon; + } + + /// + /// + /// + /// + public override int GetHashCode() + { + int hashCode = 8845; + hashCode = hashCode * -8799 + X.GetHashCode(); + hashCode = hashCode * -8799 + Y.GetHashCode(); + return hashCode; + } + /// + /// + /// + /// + /// + /// + public static bool operator ==(PointF left, PointF right) + { + return left.Equals(right); + } + /// + /// + /// + /// + /// + /// + public static bool operator !=(PointF left, PointF right) + { + return !left.Equals(right); + } + } +} diff --git a/Src/Readme.md b/Src/Readme.md new file mode 100644 index 0000000..37b5bc4 --- /dev/null +++ b/Src/Readme.md @@ -0,0 +1,68 @@ +# 硬件要求 +最低配置:Intel® CoreTM i5-2300@2.80GHz 或者同级别芯片
+推荐配置:Intel® CoreTM i7-4600U@2.1GHz 或者同级别芯片
+ +版本: So64 v4.0
+版本: x86 x64 v4.0
+ + +商用授权 离线激活 将激活验证文件更名为 ArcFacePro64.dat + +ArcFace64.dat ArcFace32.dat 是免费授权的授权文件名 + +```` +## 初始化虹软人脸sdk +````csharp +string proActiveKey32 = Ini.ReadIniData("ArcFace", "ProActiveKey32", string.Empty); +string proActiveKey64 = Ini.ReadIniData("ArcFace", "ProActiveKey64", string.Empty); +string proActiveKeySo64 = Ini.ReadIniData("ArcFace", "ProActiveKeySo64", string.Empty); + +string appId = Ini.ReadIniData("ArcFace", "APPID", string.Empty); +string key32 = Ini.ReadIniData("ArcFace", "KEY32", string.Empty); +string key64 = Ini.ReadIniData("ArcFace", "KEY64", string.Empty); +string keySo64 = Ini.ReadIniData("ArcFace", "KEYSo64", string.Empty); + +_ = ASFFunctions.Activation(appId, key32, key64, keySo64, proActiveKey32, proActiveKey64, proActiveKeySo64); +```` +## 初始化人脸引擎 +````csharp + +_ = ASFFunctions.InitEngine(pEngine: ref engine, isImgMode: isImgMode, faceMaxNum: maxFaceNum, + isAngleZeroOnly: false, needFaceInfo: true, needRgbLive: needRgbLive, needIrLive: false, + needFaceFeature: true,needImageQuality: needImageQuality); +```` +## 分析人脸照片 +````csharp +List result = null; + +if (engine != IntPtr.Zero) +{ + try + { + Image image = Converter.BuffToImage(imageBuffer); + if(needCheckImage) + { + Converter.CleanImagePropertyItems(ref image); + } + + result = ASFFunctions.DetectFacesEx(engine, image, faceMinWith: minWidth, + needCheckImage: needCheckImage, needFaceInfo: needFaceInfo, needRgbLive: needRgbLive, + needIrLive: false, needFeatures: needFeatures, needImageQuality: needImageQuality); + image.Dispose(); + } + catch (Exception ex) + { + Log.Instance.LogWrite(ex); + } +} + +```` +## 特征值对比 +````csharp +var similarity = ASFFunctions.FaceFeatureCompare(_DetectFacesEngine, feature1, feature2, ASFFunctions.IsPro && isIdcardCompare); +var similarity = ASFFunctions.FaceFeatureCompare(_DetectFacesEngine, featureIntptr1, featureIntptr2, ASFFunctions.IsPro && isIdcardCompare); +```` +## 特征值转指针对比 +````csharp +var featureIntptr=ASFFunctions.Feature2IntPtr(feature) +```` \ No newline at end of file diff --git a/Src/Utils/ImageUtil.cs b/Src/Utils/ImageUtil.NET40.cs similarity index 64% rename from Src/Utils/ImageUtil.cs rename to Src/Utils/ImageUtil.NET40.cs index 000f5d1..1ad6785 100644 --- a/Src/Utils/ImageUtil.cs +++ b/Src/Utils/ImageUtil.NET40.cs @@ -1,4 +1,5 @@ -using System; +#if (NET40) +using System; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; @@ -16,9 +17,8 @@ public static class ImageUtil /// ///
/// - /// /// - public static ASVL_OFFSCREEN GetImageData(Image inImage, bool needCheckImage = false) + public static ASVL_OFFSCREEN GetImageData(Image inImage) { ASVL_OFFSCREEN result = new ASVL_OFFSCREEN { @@ -33,8 +33,7 @@ public static ASVL_OFFSCREEN GetImageData(Image inImage, bool needCheckImage = f Bitmap image; bool needDisposeImage = false; if(inImage.PixelFormat!= PixelFormat.Format24bppRgb - || inImage.Flags!=2 - || needCheckImage) + || inImage.Flags!=2) { needDisposeImage = true; image = new Bitmap(inImage); @@ -44,7 +43,7 @@ public static ASVL_OFFSCREEN GetImageData(Image inImage, bool needCheckImage = f image = inImage as Bitmap; } //将Bitmap锁定到系统内存中,获得BitmapData - BitmapData data = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); + BitmapData data = image.LockBits(new System.Drawing.Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); //位图中第一个像素数据的地址。它也可以看成是位图中的第一个扫描行 IntPtr ptr = data.Scan0; //定义数组长度 @@ -80,12 +79,63 @@ public static ASVL_OFFSCREEN GetImageData(Image inImage, bool needCheckImage = f /// ///
/// - /// /// - public static ASVL_OFFSCREEN GetImageData_IR(Bitmap inImage, bool needCheckImage = false) + public static ASVL_OFFSCREEN GetImageData_IR(Image inImage) { - inImage.ConverGray(); - return GetImageData(inImage, needCheckImage); + ASVL_OFFSCREEN result = new ASVL_OFFSCREEN + { + u32PixelArrayFormat = (uint)ASF_ImagePixelFormat.ASVL_PAF_GRAY, + ppu8Plane = new IntPtr[4], + pi32Pitch = new int[4] + }; + + //将Image转换为 Format24bppRgb 格式的BMP + Bitmap image; + bool needDisposeImage = false; + if (inImage.PixelFormat != PixelFormat.Format24bppRgb + || inImage.Flags != 2) + { + needDisposeImage = true; + image = new Bitmap(inImage); + } + else + { + image = inImage as Bitmap; + } + //将Bitmap锁定到系统内存中,获得BitmapData + BitmapData data = image.LockBits(new System.Drawing.Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); + //位图中第一个像素数据的地址。它也可以看成是位图中的第一个扫描行 + IntPtr ptr = data.Scan0; + //定义数组长度 + int soureBitArrayLength = data.Height * Math.Abs(data.Stride); + byte[] sourceBitArray = new byte[soureBitArrayLength]; + //将bitmap中的内容拷贝到ptr_bgr数组中 + Marshal.Copy(ptr, sourceBitArray, 0, soureBitArrayLength); + result.i32Width = data.Width; + result.i32Height = data.Height; + + result.pi32Pitch[0] = data.Width; + int bgr_len = result.pi32Pitch[0] * data.Height; + byte[] destBitArray = new byte[bgr_len]; + //灰度化 + int j = 0; + double colortemp; + for (int i = 0; i < sourceBitArray.Length; i += 3) + { + colortemp = sourceBitArray[i + 2] * 0.299 + sourceBitArray[i + 1] * 0.587 + sourceBitArray[i] * 0.114; + destBitArray[j++] = (byte)colortemp; + } + + result.ppu8Plane[0] = MemoryUtil.Malloc(destBitArray.Length); + MemoryUtil.Copy(destBitArray, 0, result.ppu8Plane[0], destBitArray.Length); + + image.UnlockBits(data); + + if (needDisposeImage) + { + image.Dispose(); + } + return result; } /// @@ -107,7 +157,7 @@ public static ImageInfo ReadBMP(Image image) { bm = image as Bitmap; } - BitmapData data = bm.LockBits(new Rectangle(0, 0, bm.Width, bm.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); + BitmapData data = bm.LockBits(new System.Drawing.Rectangle(0, 0, bm.Width, bm.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); try { //位图中第一个像素数据的地址。它也可以看成是位图中的第一个扫描行 @@ -124,6 +174,8 @@ public static ImageInfo ReadBMP(Image image) result.Width = data.Width; result.Height = data.Height; result.Format = ASF_ImagePixelFormat.ASVL_PAF_RGB24_B8G8R8; + //步长的设置 + result.WidthStep = data.Stride; //获取去除对齐位后度图像数据 int line = result.Width * 3; @@ -163,52 +215,75 @@ public static ImageInfo ReadBMP(Image image) /// /// 获取图片IR信息 /// - /// 图片 + /// 图片 /// 成功或失败 - public static ImageInfo ReadBMP_IR(Bitmap bitmap) + public static ImageInfo ReadBMP_IR(Image image) { - bitmap.ConverGray(); - return ReadBMP(bitmap); - } - - /// - /// 图像灰度化 - /// - /// - public static void ConverGray(this Bitmap curBitmpap) - { - //位图矩形 - Rectangle rect = new Rectangle(0, 0, curBitmpap.Width, curBitmpap.Height); - //以可读写的方式锁定全部位图像素 - BitmapData bmpData = curBitmpap.LockBits(rect, ImageLockMode.ReadWrite, curBitmpap.PixelFormat); - //得到首地址 - IntPtr ptr = bmpData.Scan0; - - //定义被锁定的数组大小,由位图数据与未用空间组成的 - int bytes = bmpData.Stride * bmpData.Height; - //定义位图数组 - byte[] rgbValues = new byte[bytes]; - //复制被锁定的位图像素值到该数组内 - Marshal.Copy(ptr, rgbValues, 0, bytes); + ImageInfo result = new ImageInfo(); - //灰度化 - double colorTemp; - for (int i = 0; i < bmpData.Height; i++) + //将Image转换为Format24bppRgb格式的BMP + Bitmap bm; + if (image.PixelFormat != PixelFormat.Format24bppRgb) + { + bm = new Bitmap(image); + } + else + { + bm = image as Bitmap; + } + BitmapData data = bm.LockBits(new System.Drawing.Rectangle(0, 0, bm.Width, bm.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); + try { - //只处理每行中是图像像素的数据,舍弃未用空间 - for (int j = 0; j < bmpData.Width * 3; j += 3) + //位图中第一个像素数据的地址。它也可以看成是位图中的第一个扫描行 + IntPtr ptr = data.Scan0; + + //定义数组长度 + int soureBitArrayLength = data.Height * Math.Abs(data.Stride); + byte[] sourceBitArray = new byte[soureBitArrayLength]; + + //将bitmap中的内容拷贝到ptr_bgr数组中 + MemoryUtil.Copy(ptr, sourceBitArray, 0, soureBitArrayLength); + + //填充引用对象字段值 + result.Width = data.Width; + result.Height = data.Height; + result.Format = ASF_ImagePixelFormat.ASVL_PAF_GRAY; + //步长的设置 + result.WidthStep = data.Width; + + //获取去除对齐位后度图像数据 + int line = result.Width; + int pitch = Math.Abs(data.Stride); + int ir_len = line * result.Height; + byte[] destBitArray = new byte[ir_len]; + + //灰度化 + int j = 0; + double colortemp = 0; + for (int i = 0; i < sourceBitArray.Length; i += 3) { - //利用公式计算灰度值 - colorTemp = rgbValues[i * bmpData.Stride + j + 2] * 0.299 + rgbValues[i * bmpData.Stride + j + 1] * 0.587 + rgbValues[i * bmpData.Stride + j] * 0.114; - //R=G=B - rgbValues[i * bmpData.Stride + j] = rgbValues[i * bmpData.Stride + j + 1] = rgbValues[i * bmpData.Stride + j + 2] = (byte)colorTemp; + colortemp = sourceBitArray[i + 2] * 0.299 + sourceBitArray[i + 1] * 0.587 + sourceBitArray[i] * 0.114; + destBitArray[j++] = (byte)colortemp; } - } - //把数组复制回位图 - Marshal.Copy(rgbValues, 0, ptr, bytes); - //解锁位图像素 - curBitmpap.UnlockBits(bmpData); + result.ImgData= MemoryUtil.Malloc(destBitArray.Length); + MemoryUtil.Copy(destBitArray, 0, result.ImgData, destBitArray.Length); + + } + catch (Exception e) + { + throw e; + } + finally + { + bm.UnlockBits(data); + bm.Dispose(); + } + if (image.PixelFormat != PixelFormat.Format24bppRgb) + { + bm.Dispose(); + } + return result; } /// @@ -242,7 +317,7 @@ internal static Bitmap ScaleImage(Image image, int dstWidth, int dstHeight) g.CompositingQuality = CompositingQuality.HighQuality; g.SmoothingMode = SmoothingMode.HighQuality; g.InterpolationMode = InterpolationMode.HighQualityBicubic; - g.DrawImage(image, new Rectangle(0, 0, width, height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel); + g.DrawImage(image, new System.Drawing.Rectangle(0, 0, width, height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel); } return destBitmap; @@ -304,51 +379,6 @@ internal static float GetWidthAndHeight(int oldWidth, int oldHeigt, int newWidth return scaleRate; } - /// - /// 重设图片DPI - /// - /// - /// - /// - /// 使用旧照片尺寸, - /// true则按比例缩放图片大小,false则按原大小填充图像 - /// - internal static Bitmap ResetDpi(this Image image, float xDpi = 96, float yDpi = 96, bool useOldSize = true) - { - Bitmap result; - if (image.HorizontalResolution != xDpi - || image.VerticalResolution != yDpi) - { - Bitmap bitmap; - if (useOldSize) - { - bitmap = new Bitmap(image.Width, image.Height, image.PixelFormat); - } - else - { - bitmap = new Bitmap((int)(image.Width * xDpi / image.HorizontalResolution) - , (int)(image.Height * yDpi / image.VerticalResolution), image.PixelFormat); - } - bitmap.SetResolution(xDpi, yDpi); - using (var graphic = Graphics.FromImage(bitmap)) - { - //设置高质量查值法 - graphic.InterpolationMode = InterpolationMode.HighQualityBicubic; - //设置高质量,低速度呈现平滑程度 - graphic.SmoothingMode = SmoothingMode.HighQuality; - //清空画布并以透明背景色填充 - graphic.Clear(Color.Transparent); - graphic.DrawImage(image, new Rectangle(0, 0, bitmap.Width, bitmap.Height), new Rectangle(0, 0, image.Width, image.Height), GraphicsUnit.Pixel); - } - result = bitmap; - } - else - { - result = new Bitmap(image); - } - return result; - } - /// /// 宽度4的倍数校验 /// @@ -373,4 +403,5 @@ internal static Image CheckImage(Image image) return result; } } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Src/Utils/ImageUtil.NET60.cs b/Src/Utils/ImageUtil.NET60.cs new file mode 100644 index 0000000..499a8b6 --- /dev/null +++ b/Src/Utils/ImageUtil.NET60.cs @@ -0,0 +1,167 @@ +#if !(NET40) +using SkiaSharp; +using System; +using Yj.ArcSoftSDK._4_0.Models; + +namespace Yj.ArcSoftSDK._4_0.Utils +{ + /// + /// + /// + public static class ImageUtil + { + /// + /// + /// + /// + /// + public static ASVL_OFFSCREEN GetImageData(SKBitmap inImage) + { + ASVL_OFFSCREEN result = new ASVL_OFFSCREEN + { + u32PixelArrayFormat = (uint)ASF_ImagePixelFormat.ASVL_PAF_RGB24_B8G8R8, + ppu8Plane = new IntPtr[4], + pi32Pitch = new int[4] + }; + result.i32Width = inImage.Width; + result.i32Height = inImage.Height; + result.pi32Pitch[0] = inImage.Width * 3;// data.Width * 3; + + byte[] sourceBitArray = inImage.Bytes; + byte[] destBitArray = new byte[inImage.Width * inImage.Height * 3]; + + for (int sourceIndex = 0, destIndex = 0; sourceIndex < sourceBitArray.Length; sourceIndex += 4, destIndex += 3) + { + destBitArray[destIndex] = sourceBitArray[sourceIndex]; + destBitArray[destIndex + 1] = sourceBitArray[sourceIndex + 1]; + destBitArray[destIndex + 2] = sourceBitArray[sourceIndex + 2]; + } + + result.ppu8Plane[0] = MemoryUtil.Malloc(destBitArray.Length); + MemoryUtil.Copy(destBitArray, 0, result.ppu8Plane[0], destBitArray.Length); + return result; + } + + /// + /// + /// + /// + /// + public static ASVL_OFFSCREEN GetImageData_IR(SKBitmap inImage) + { + ASVL_OFFSCREEN result = new ASVL_OFFSCREEN + { + u32PixelArrayFormat = (uint)ASF_ImagePixelFormat.ASVL_PAF_GRAY, + ppu8Plane = new IntPtr[4], + pi32Pitch = new int[4] + }; + result.i32Width = inImage.Width; + result.i32Height = inImage.Height; + result.pi32Pitch[0] = inImage.Width; + + byte[] sourceBitArray = inImage.Bytes; + byte[] destBitArray = new byte[inImage.Width * inImage.Height]; + + for (int sourceIndex = 0, destIndex = 0; sourceIndex < sourceBitArray.Length; sourceIndex += 4, destIndex++) + { + destBitArray[destIndex] = (byte)(sourceBitArray[sourceIndex + 2] * 0.299 + sourceBitArray[sourceIndex + 1] * 0.587 + sourceBitArray[sourceIndex] * 0.114); + } + + result.ppu8Plane[0] = MemoryUtil.Malloc(destBitArray.Length); + MemoryUtil.Copy(destBitArray, 0, result.ppu8Plane[0], destBitArray.Length); + return result; + } + + /// + /// 获取图片信息 + /// + /// 图片 + /// 成功或失败 + public static ImageInfo ReadBMP(SKBitmap image) + { + ImageInfo result = new ImageInfo(); + try + { + //填充引用对象字段值 + result.Width = image.Width; + result.Height = image.Height; + result.Format = ASF_ImagePixelFormat.ASVL_PAF_RGB24_B8G8R8; + result.WidthStep = image.Width * 3; + byte[] sourceBitArray = image.Bytes; + byte[] destBitArray = new byte[image.Width * image.Height * 3]; + + for (int sourceIndex = 0, destIndex = 0; sourceIndex < sourceBitArray.Length; sourceIndex += 4, destIndex += 3) + { + destBitArray[destIndex] = sourceBitArray[sourceIndex]; + destBitArray[destIndex + 1] = sourceBitArray[sourceIndex + 1]; + destBitArray[destIndex + 2] = sourceBitArray[sourceIndex + 2]; + } + result.ImgData = MemoryUtil.Malloc(destBitArray.Length); + MemoryUtil.Copy(destBitArray, 0, result.ImgData, destBitArray.Length); + } + catch (Exception) + { + result = null; + } + + return result; + } + + /// + /// 获取图片IR信息 + /// + /// 图片 + /// 成功或失败 + public static ImageInfo ReadBMP_IR(SKBitmap image) + { + ImageInfo result = new ImageInfo(); + try + { + //填充引用对象字段值 + result.Width = image.Width; + result.Height = image.Height; + result.Format = ASF_ImagePixelFormat.ASVL_PAF_GRAY; + byte[] sourceBitArray = image.Bytes; + byte[] destBitArray = new byte[image.Width * image.Height]; + + for (int sourceIndex = 0, destIndex = 0; sourceIndex < sourceBitArray.Length; sourceIndex += 4, destIndex++) + { + destBitArray[destIndex] = (byte)(sourceBitArray[sourceIndex + 2] * 0.299 + sourceBitArray[sourceIndex + 1] * 0.587 + sourceBitArray[sourceIndex] * 0.114); + } + result.ImgData = MemoryUtil.Malloc(destBitArray.Length); + MemoryUtil.Copy(destBitArray, 0, result.ImgData, destBitArray.Length); + } + catch (Exception) + { + result = null; + } + + return result; + } + + /// + /// 宽度4的倍数校验 + /// + /// + /// + internal static SKBitmap CheckImage(SKBitmap image) + { + SKBitmap result = null; + if (image != null) + { + result = image.Copy(); + + if (result.Width % 4 != 0 + || result.Height % 4 != 0) + { + var newImage = image.Resize(new SKImageInfo(result.Width - (result.Width % 4), result.Height - (result.Height % 4)), SKFilterQuality.High); + result.Dispose(); + result = newImage; + } + } + + return result; + } + } +} +#endif \ No newline at end of file diff --git a/Src/Wenhe.ArcSoftSDK.4_0.xml b/Src/Wenhe.ArcSoftSDK.4_0.xml new file mode 100644 index 0000000..5138418 --- /dev/null +++ b/Src/Wenhe.ArcSoftSDK.4_0.xml @@ -0,0 +1,2332 @@ + + + + Yj.ArcSoftSDK.4_0 + + + + + + + + + + + 激活SDK + + + + + + 永久授权版 秘钥 + 永久授权版 秘钥 + 永久授权版 秘钥 + + + + + 初始化引擎 + + + + [1,10] + + 需要人脸信息(性别、年龄、角度) + 需要rgb活体 + 需要红外活体 + 需要提取人脸特征值 + 是否需要图像质量检测(只对虹软商用授权有效) + 设置遮挡算法检测的阈值(只对虹软4.0商用授权有效) + + + + + + + + + + + + 获取人脸 信息 + + + + + + 需要角度、性别、年龄信息 + 需要RGB活体 + 需要Ir活体 + 需要特征值 + 是否需要图像质量检测(只对虹软商用授权有效) + 算法登记照(只对4.0算法有效) + + + + + 获取人脸 信息 + + + + + 需要角度、性别、年龄信息 + 需要RGB活体 + 需要Ir活体 + 需要特征值 + 是否需要图像质量检测(只对虹软商用授权有效) + 算法登记照(只对4.0算法有效) + + + + + 获取人脸个数 + + + + 人脸最小宽度 + + + + + + 人脸对比 + + + + + 是否证件照对比 + + + + + 人脸对比 + + + + + 是否证件照对比 + + + + + 释放特征值指针 + + + + + + 获取特征值指针 + + + + + + + 年龄检测 + + 引擎Handle + 年龄检测结构体 + + + + 性别检测 + + 引擎Handle + 年龄检测结构体 + + + + 人脸3D角度检测 + + 引擎Handle + 年龄检测结构体 + + + + RGB活体检测 + + 引擎Handle + 年龄检测结构体 + + + + 口罩检测 + + 引擎Handle + 年龄检测结构体 + + + + 额头检测 + + 引擎Handle + 年龄检测结构体 + + + + 人脸图像质量检测 + + 引擎handle + LPASF_ImageData 图像数据 + 人脸信息 + 是否带口罩 默认不带 + 调用结果 + + + + + + + ASVL_OFFSCREEN + + + + + 获取单人人脸特征 + + + + + + RGB活体检测 + + 引擎Handle + + + 年龄检测结构体 + + + + + + + + + + pMultiFaceInfo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SDK动态链接库路径 自行复制至 /usr/lib + + + + + + 激活人脸识别SDK引擎函数 + + SDK对应的AppID + SDK对应的SDKKey + 授权码 + 调用结果 + + + + 获取激活文件信息接口 + + + 调用结果 + + + + 初始化引擎 + + AF_DETECT_MODE_VIDEO 视频模式 | AF_DETECT_MODE_IMAGE 图片模式 + 检测脸部的角度优先值,推荐:ASF_OrientPriority.ASF_OP_0_HIGHER_EXT + 最大需要检测的人脸个数 + 用户选择需要检测的功能组合,可单个或多个 + 初始化返回的引擎handle + 调用结果 + + + + 人脸图像质量检测 + + 引擎handle + LPASF_ImageData 图像数据 + 人脸检测结果 + 仅支持传入1、0、-1,戴口罩 1,否则认为未戴口罩 + 人脸图像质量检测结果 + 预留字段 暂时使用 + 调用结果 + + + + 人脸检测 + + 引擎handle + LPASF_ImageData 图像数据 + 人脸检测结果 + 预留字段 暂时使用 + 调用结果 + + + + 人脸检测 + + 引擎handle + 图像宽度 + 图像高度 + 图像颜色空间 + 图像数据 + 人脸检测结果 + 预留字段 暂时使用 + 调用结果 + + + + 设置RGB/IR活体阈值,若不设置内部默认RGB:0.5 IR:0.7 + + + 活体阈值,推荐RGB:0.5 IR:0.7 + + + + + 人脸信息检测(年龄/性别/人脸3D角度) 最多支持4张人脸信息检测,超过部分返回未知(活体仅支持单张人脸检测,超出返回未知)。 + + 引擎handle + LPASF_ImageData 图像数据 + 人脸信息,用户根据待检测的功能裁减选择需要使用的人脸 + 只支持初始化时候指定需要检测的功能,在process时进一步在这个已经指定的功能集中继续筛选例如初始化的时候指定检测年龄和性别, 在process的时候可以只检测年龄, 但是不能检测除年龄和性别之外的功能 + 调用结果 + + + + 人脸信息检测(年龄/性别/人脸3D角度) 最多支持4张人脸信息检测,超过部分返回未知(活体仅支持单张人脸检测,超出返回未知)。 + + 引擎handle + 图像宽度 + 图像高度 + 图像颜色空间 + 图像数据 + 人脸信息,用户根据待检测的功能裁减选择需要使用的人脸 + 只支持初始化时候指定需要检测的功能,在process时进一步在这个已经指定的功能集中继续筛选例如初始化的时候指定检测年龄和性别, 在process的时候可以只检测年龄, 但是不能检测除年龄和性别之外的功能 + 调用结果 + + + + 单人脸特征提取 + + 引擎handle + LPASF_ImageData 图像数据 + 单张人脸位置和角度信息 + 注册照:ASF_REGISTER 识别照:ASF_RECOGNITION + 带口罩 1,否则0 + 人脸特征 + 调用结果 + + + + 单人脸特征提取 + + 引擎handle + 图像宽度 + 图像高度 + 图像颜色空间 + 图像数据 + 单张人脸位置和角度信息 + 注册照:ASF_REGISTER 识别照:ASF_RECOGNITION + 带口罩 1,否则0 + 人脸特征 + 调用结果 + + + + 人脸特征比对 + + 引擎handle + 待比较人脸特征1 + 待比较人脸特征2 + 相似度(0.0~1.0) + 选择人脸特征比对模型 + 调用结果 + + + + 获取年龄信息 + + 引擎handle + 检测到的年龄信息 + 调用结果 + + + + 获取性别信息 + + 引擎handle + 检测到的性别信息 + 调用结果 + + + + 获取3D角度信息 + + 引擎handle + 检测到脸部3D角度信息 + 调用结果 + + + + 获取RGB活体结果 + + 引擎handle + 活体检测信息 + 调用结果 + + + + 该接口目前仅支持单人脸IR活体检测(不支持年龄、性别、3D角度的检测),默认取第一张人脸 + + 引擎handle + LPASF_ImageData 图片数据 + 人脸信息,用户根据待检测的功能选择需要使用的人脸。 + 目前只支持传入ASF_IR_LIVENESS属性的传入,且初始化接口需要传入 + + + + + 该接口目前仅支持单人脸IR活体检测(不支持年龄、性别、3D角度的检测),默认取第一张人脸 + + 引擎handle + 图片宽度 + 图片高度 + 颜色空间格式 + 图片数据 + 人脸信息,用户根据待检测的功能选择需要使用的人脸。 + 目前只支持传入ASF_IR_LIVENESS属性的传入,且初始化接口需要传入 + + + + + 获取IR活体结果 + + 引擎handle + 检测到IR活体结果 + + + + + 销毁引擎 + + 引擎handle + 调用结果 + + + + 获取版本信息 + + 引擎handle + 调用结果 + + + + 设置遮挡算法检测的阈值 + + + 0.0~1.0 + + + + + 获取人脸是否戴口罩 + + + + + + + + 获取额头区域位置 + + + + + + + + SDK中与人脸识别相关函数封装类 + + + + + SDK动态链接库路径 + + + + + 激活人脸识别SDK引擎函数 + + SDK对应的AppID + SDK对应的SDKKey + 授权码 + 调用结果 + + + + 获取激活文件信息接口 + + + 调用结果 + + + + 初始化引擎 + + AF_DETECT_MODE_VIDEO 视频模式 | AF_DETECT_MODE_IMAGE 图片模式 + 检测脸部的角度优先值,推荐:ASF_OrientPriority.ASF_OP_0_HIGHER_EXT + 最大需要检测的人脸个数 + 用户选择需要检测的功能组合,可单个或多个 + 初始化返回的引擎handle + 调用结果 + + + + 人脸图像质量检测 + + 引擎handle + LPASF_ImageData 图像数据 + 人脸检测结果 + 仅支持传入1、0、-1,戴口罩 1,否则认为未戴口罩 + 人脸图像质量检测结果 + 预留字段 暂时使用 + 调用结果 + + + + 人脸检测 + + 引擎handle + LPASF_ImageData 图像数据 + 人脸检测结果 + 预留字段 暂时使用 + 调用结果 + + + + 人脸信息检测(年龄/性别/人脸3D角度) 最多支持4张人脸信息检测,超过部分返回未知(活体仅支持单张人脸检测,超出返回未知)。 + + 引擎handle + LPASF_ImageData 图像数据 + 人脸信息,用户根据待检测的功能裁减选择需要使用的人脸 + 只支持初始化时候指定需要检测的功能,在process时进一步在这个已经指定的功能集中继续筛选例如初始化的时候指定检测年龄和性别, 在process的时候可以只检测年龄, 但是不能检测除年龄和性别之外的功能 + 调用结果 + + + + 单人脸特征提取 + + 引擎handle + LPASF_ImageData 图像数据 + 单张人脸位置和角度信息 + 注册照:ASF_REGISTER 识别照:ASF_RECOGNITION + 带口罩 1,否则0 + 人脸特征 + 调用结果 + + + + 人脸特征比对 + + 引擎handle + 待比较人脸特征1 + 待比较人脸特征2 + 相似度(0.0~1.0) + 选择人脸特征比对模型 + 调用结果 + + + + 获取年龄信息 + + 引擎handle + 检测到的年龄信息 + 调用结果 + + + + 获取性别信息 + + 引擎handle + 检测到的性别信息 + 调用结果 + + + + 获取3D角度信息 + + 引擎handle + 检测到脸部3D角度信息 + 调用结果 + + + + 获取RGB活体结果 + + 引擎handle + 活体检测信息 + 调用结果 + + + + 该接口目前仅支持单人脸IR活体检测(不支持年龄、性别、3D角度的检测),默认取第一张人脸 + + 引擎handle + LPASF_ImageData 图片数据 + 人脸信息,用户根据待检测的功能选择需要使用的人脸。 + 目前只支持传入ASF_IR_LIVENESS属性的传入,且初始化接口需要传入 + + + + + 获取IR活体结果 + + 引擎handle + 检测到IR活体结果 + + + + + 销毁引擎 + + 引擎handle + 调用结果 + + + + 获取版本信息 + + 引擎handle + 调用结果 + + + + 设置遮挡算法检测的阈值 + + + 0.0~1.0 + + + + + 获取人脸是否戴口罩 + + + + + + + + 获取额头区域位置 + + + + + + + + SDK中与人脸识别相关函数封装类 + + + + + SDK动态链接库路径 + + + + + 激活人脸识别SDK引擎函数 + + SDK对应的AppID + SDK对应的SDKKey + 授权码 + 调用结果 + + + + 获取激活文件信息接口 + + + 调用结果 + + + + 初始化引擎 + + AF_DETECT_MODE_VIDEO 视频模式 | AF_DETECT_MODE_IMAGE 图片模式 + 检测脸部的角度优先值,推荐:ASF_OrientPriority.ASF_OP_0_HIGHER_EXT + 最大需要检测的人脸个数 + 用户选择需要检测的功能组合,可单个或多个 + 初始化返回的引擎handle + 调用结果 + + + + 人脸图像质量检测 + + 引擎handle + LPASF_ImageData 图像数据 + 人脸检测结果 + 仅支持传入1、0、-1,戴口罩 1,否则认为未戴口罩 + 人脸图像质量检测结果 + 预留字段 暂时使用 + 调用结果 + + + + 人脸检测 + + 引擎handle + LPASF_ImageData 图像数据 + 人脸检测结果 + 预留字段 暂时使用 + 调用结果 + + + + 人脸检测 + + 引擎handle + 图像宽度 + 图像高度 + 图像颜色空间 + 图像数据 + 人脸检测结果 + 预留字段 暂时使用 + 调用结果 + + + + 设置RGB/IR活体阈值,若不设置内部默认RGB:0.5 IR:0.7 + + + 活体阈值,推荐RGB:0.5 IR:0.7 + + + + + 人脸信息检测(年龄/性别/人脸3D角度) 最多支持4张人脸信息检测,超过部分返回未知(活体仅支持单张人脸检测,超出返回未知)。 + + 引擎handle + LPASF_ImageData 图像数据 + 人脸信息,用户根据待检测的功能裁减选择需要使用的人脸 + 只支持初始化时候指定需要检测的功能,在process时进一步在这个已经指定的功能集中继续筛选例如初始化的时候指定检测年龄和性别, 在process的时候可以只检测年龄, 但是不能检测除年龄和性别之外的功能 + 调用结果 + + + + 人脸信息检测(年龄/性别/人脸3D角度) 最多支持4张人脸信息检测,超过部分返回未知(活体仅支持单张人脸检测,超出返回未知)。 + + 引擎handle + 图像宽度 + 图像高度 + 图像颜色空间 + 图像数据 + 人脸信息,用户根据待检测的功能裁减选择需要使用的人脸 + 只支持初始化时候指定需要检测的功能,在process时进一步在这个已经指定的功能集中继续筛选例如初始化的时候指定检测年龄和性别, 在process的时候可以只检测年龄, 但是不能检测除年龄和性别之外的功能 + 调用结果 + + + + 单人脸特征提取 + + 引擎handle + LPASF_ImageData 图像数据 + 单张人脸位置和角度信息 + 注册照:ASF_REGISTER 识别照:ASF_RECOGNITION + 带口罩 1,否则0 + 人脸特征 + 调用结果 + + + + 单人脸特征提取 + + 引擎handle + 图像宽度 + 图像高度 + 图像颜色空间 + 图像数据 + 单张人脸位置和角度信息 + 注册照:ASF_REGISTER 识别照:ASF_RECOGNITION + 带口罩 1,否则0 + 人脸特征 + 调用结果 + + + + 人脸特征比对 + + 引擎handle + 待比较人脸特征1 + 待比较人脸特征2 + 相似度(0.0~1.0) + 选择人脸特征比对模型 + 调用结果 + + + + 获取年龄信息 + + 引擎handle + 检测到的年龄信息 + 调用结果 + + + + 获取性别信息 + + 引擎handle + 检测到的性别信息 + 调用结果 + + + + 获取3D角度信息 + + 引擎handle + 检测到脸部3D角度信息 + 调用结果 + + + + 获取RGB活体结果 + + 引擎handle + 活体检测信息 + 调用结果 + + + + 该接口目前仅支持单人脸IR活体检测(不支持年龄、性别、3D角度的检测),默认取第一张人脸 + + 引擎handle + LPASF_ImageData 图片数据 + 人脸信息,用户根据待检测的功能选择需要使用的人脸。 + 目前只支持传入ASF_IR_LIVENESS属性的传入,且初始化接口需要传入 + + + + + 该接口目前仅支持单人脸IR活体检测(不支持年龄、性别、3D角度的检测),默认取第一张人脸 + + 引擎handle + 图片宽度 + 图片高度 + 颜色空间格式 + 图片数据 + 人脸信息,用户根据待检测的功能选择需要使用的人脸。 + 目前只支持传入ASF_IR_LIVENESS属性的传入,且初始化接口需要传入 + + + + + 获取IR活体结果 + + 引擎handle + 检测到IR活体结果 + + + + + 销毁引擎 + + 引擎handle + 调用结果 + + + + 获取版本信息 + + 引擎handle + 调用结果 + + + + 设置遮挡算法检测的阈值 + + + 0.0~1.0 + + + + + 获取人脸是否戴口罩 + + + + + + + + 获取额头区域位置 + + + + + + + + 激活文件信息 (4.1算法) + + + + + 开始时间 精度到毫秒的时间戳 + + + + + 截止时间 精度到毫秒的时间戳 + + + + + 激活码 + + + + + 平台 + + + + + sdk类型 + + + + + APPID + + + + + SDKKEY + + + + + SDK版本号 + + + + + 激活文件版本号 + + + + + 年龄结果结构体 + + + + + 年龄检测结果集合 + + + + + 结果集大小 + + + + + 根据应用场景选择对应的模型进行人脸特征比对 + + + + + 用于生活照之间的特征比对,推荐阈值0.80 + + + + + 用于证件照或生活照与证件照之间的特征比对,推荐阈值0.82 + + + + + 图片检测模式 + + + + + Video模式,一般用于多帧连续检测 + + + + + Image模式,一般用于静态图的单次检测 + + + + + 检测模型 + + + + + RGB图像检测模型 + + + + + 3D人脸角度检测结构体 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 人脸信息 + FACE_DATA_SIZE 5000 + do not free by self !!! + + + + + 人脸信息长度 + + + + + 人脸特征结构体 + + + + + 特征值 byte[] + + + + + 结果集大小 + + + + + 人脸信息 + + + + + + + + + + 人脸坐标Rect结果 + + + + + 头像角度 + + + + + 0:男;1:女; + + + + + + + + + + + + + + + RGB 活体 + 0:非真人;1:真人;-1:不确定;-2:传入人脸数>1;-3: 人脸过小 -4: 角度过大 -5: 人脸超出边界 -6: 深度图错误 -7: 红外图太亮了 + + + + + 红外 活体 + 0:非真人;1:真人;-1:不确定;-2:传入人脸数>1; + + + + + 特征 + + + + + face ID,IMAGE模式下不返回FaceID + + + + + 图像质量 -1无效 + + + + + 口罩 "0" 代表没有带口罩,"1"代表带口罩 ,"-1"表不确定 + + + + + 戴眼镜置信度[0-1],推荐阈值0.5 + + + + + 左眼状态 + + + + + 右眼状态 + + + + + "1" 表示 遮挡, "0" 表示 未遮挡, "-1" 表示不确定 + + + + + 额头坐标 Empty 表示无效 + + + + + 3D人脸角度检测 + + + + + 是否检测成功,0成功,其他为失败 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 结果集大小 + + + + + + + + + + + + + + + + + + + + 性别结构体 + + + + + 性别检测结果集合 + + + + + 结果集大小 + + + + + + + + + + 8-bit Y 通道,8-bit 2x2 采样 V 与 U 分量交织通道 + + + + + 8-bit Y 通道,8-bit 2x2 采样 U 与 V 分量交织通道 + + + + + RGB 分量交织,按 B, G, R, B 字节序排布 + R R R R R R R R G G G G G G G G B B B B B B B B + + + + + YUV 分量交织, V 与 U 分量 2x1 采样,按 Y0, U0, Y1, V0 字节序排布 + + + + + 16-bit IR图像 + + + + + R R R R R G G G G G G B B B B B + + + + + X R R R R R G G G G G B B B B B + + + + + X X X X R R R R G G G G B B B B + + + + + T R R R R R G G G G G B B B B B + + + + + B B B B B G G G G G G R R R R R + + + + + X B B B B B G G G G G R R R R R + + + + + X X X X B B B B G G G G R R R R + + + + + X X X X X X R R R R R R G G G G G G B B B B B B + + + + + X X X X X T R R R R R R G G G G G G B B B B B B + + + + + B B B B B B B B G G G G G G G G R R R R R R R R + + + + + X X X X X X B B B B B B G G G G G G R R R R R R + + + + + X X X X X X X X R R R R R R R R G G G G G G G G B B B B B B B B + + + + + A A A A A A A A R R R R R R R R G G G G G G G G B B B B B B B B + + + + + X X X X X X X X B B B B B B B B G G G G G G G G R R R R R R R R + + + + + B B B B B B B B G G G G G G G G R R R R R R R R A A A A A A A A + + + + + A A A A A A A A B B B B B B B B G G G G G G G G R R R R R R R R + + + + + Y0, U0, V0 + + + + + Y0, V0, U0 + + + + + U0, V0, Y0 + + + + + V0, U0, Y0 + + + + + Y0, V0, Y1, U0 + + + + + U0, Y0, V0, Y1 + + + + + V0, Y0, U0, Y1 + + + + + Y1, U0, Y0, V0 + + + + + Y1, V0, Y0, U0 + + + + + U0, Y1, V0, Y0 + + + + + V0, Y1, U0, Y0 + + + + + Y0, Y1, U0, V0 + + + + + 8-bit Y 通道, 8-bit 2x2 采样 U 通道, 8-bit 2x2 采样 V 通道 + + + + + 8 bit Y plane followed by 8 bit 1x2 subsampled U and V planes + + + + + 8 bit Y plane followed by 8 bit ,2x1 subsampled U and V planes + + + + + 8 bit Y plane followed by 8 bit U and V planes + + + + + + + + + + 8 bit Y plane followed by 8 bit 1x2 subsampled V and U planes + + + + + 8 bit Y plane followed by 8 bit 2x1 subsampled V and U planes + + + + + 8 bit Y plane followed by 8 bit V and U planes + + + + + 8-bit IR图像 + + + + + 8 bit Y plane followed by 8 bit 2x1 subsampled UV planes + + + + + 8 bit Y plane followed by 8 bit 2x1 subsampled VU planes + + + + + 8 bit Y plane followed by 8 bit 4x4 subsampled VU planes + + + + + Negative UYVY, U0, Y0, V0, Y1 + + + + + Negative I420, 8 bit Y plane followed by 8 bit 2x2 subsampled U and V planes + + + + + Mono UYVY, UV values are fixed, gray image in U0, Y0, V0, Y1 + + + + + Mono I420, UV values are fixed, 8 bit Y plane followed by 8 bit 2x2 subsampled U and V planes + + + + + P8_YUYV, 8 pixels a group, Y0Y1Y2Y3Y4Y5Y6Y7U0U1U2U3V0V1V2V3 + + + + + P16_YUYV, 16*16 pixels a group, Y0Y1Y2Y3...U0U1...V0V1... + + + + + 10 bits RGGB CFA raw data, each data has 2 bytes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 10 bits gray raw data + + + + + 10 bits gray raw data, each data has 2 bytes + + + + + 图像质量信息 + + + + + 人脸质量 float + + + + + 检测到的人脸数 + + + + + + + + + + 是否是真人 + 0:非真人;1:真人;-1:不确定;-2:传入人脸数>1;-3: 人脸过小 -4: 角度过大 -5: 人脸超出边界 -6: 深度图错误 -7: 红外图太亮了 + + + + + 结果集大小 + + + + + 活体置信度 + + + + + BGR活体检测阈值设置,默认值0.5 + + + + + IR活体检测阈值设置,默认值0.7 + + + + + 口罩信息 + + + + + "0" 代表没有带口罩,"1"代表带口罩 ,"-1"表不确定 + + + + + 结果集大小 + + + + + 多人脸检测结构体 + + + + + 人脸Rect结果集 + + + + + + 人脸角度结果集,与faceRects一一对应 对应ASF_OrientCode + + + + + + 结果集大小 + + + + + face ID,IMAGE模式下不返回FaceID + int32 + + + + + 戴眼镜置信度[0-1],推荐阈值0.5 + + + + + + 左眼状态 0 未闭眼;1 闭眼 + + + + + + 右眼状态 0 未闭眼;1 闭眼 + + + + + + "1" 表示 遮挡, "0" 表示 未遮挡, "-1" 表示不确定 + + + + + + 多张人脸信息 + + do not free by self !!! + + + + + 人脸角度结构体 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 人脸检测优先角度结构体,推荐ASF_OP_0_HIGHER_EXT + + + + + 常规预览下正方向 + + + + + 基于0°逆时针旋转90°的方向 + + + + + 基于0°逆时针旋转270°的方向 + + + + + 基于0°旋转180°的方向(逆时针、顺时针效果一样) + + + + + 全角度 + + + + + 根据应用场景(注册照还是识别照)选择对应的模型进行人脸特征提取 + + + + + 用于识别照人脸特征提取 + + + + + 用于注册照人脸特征提取 + + + + + 单人脸检测结构体 + + + + + 人脸坐标Rect结果 + + + + + 人脸角度 + + + + + 单张人脸数据 + + + + + SDK版本信息结构体 + + + + + + + + + + + + + + + + + + + + Define the image format space + + + + + 0x201 (513) + + + + + + + + + + + + + + + + + + + + + + + + + 引擎方法类型结构体,在初始化时将用到的类型用|连接传入,如 ASF_NONE|ASF_FACE_DETECT|ASF_FACERECOGNITION + + + + + 不做方法初始化方法类型 + + + + + 人脸检测 + + + + + 人脸特征 + 人脸识别方法类型常量,包含图片feature提取和feature比对 + + + + + 年龄 + + + + + 性别 + + + + + 3D角度 + + + + + 额头区域检测 + + + + + RGB活体 + + + + + 图像质量检测 + + + + + 红外活体 + + + + + 人脸遮挡 + + + + + 口罩检测 + + + + + 人脸信息 + + + + + + + + + + 图片的像素数据 + + + + + 图片像素宽 + + + + + 图片像素高 + + + + + 图片格式 + + + + + 步长 + + + + + + + + + + 颜色格式 + + + + + 图像宽度 + + + + + 图像高度 + + + + + 图像数据 + + + + + + + + + + 人脸框信息结构体 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 获取图片信息 + + 图片 + 成功或失败 + + + + 获取图片IR信息 + + 图片 + 成功或失败 + + + + 宽度4的倍数校验 + + + + + + + + + + + + 申请内存 + + 内存长度(单位:字节) + 内存首地址 + + + + 释放ptr托管的内存 + + 托管指针 + + + + 释放ptr托管的内存 + + 托管指针 + + + + 将字节数组的内容拷贝到托管内存中 + + 元数据 + 元数据拷贝起始位置 + 托管内存 + 拷贝长度 + + + + 将托管内存的内容拷贝到字节数组中 + + 托管内存 + 目标字节数组 + 拷贝起始位置 + 拷贝长度 + + + + 将ptr托管的内存转化为结构体对象 + + 泛型 + 托管指针 + 转化后的对象 + + + + 将结构体对象复制到ptr托管的内存 + + + + + + + + 获取类型的大小 + + 泛型 + 类型的大小 + + + + + + + + + + + + + + + + + + + + + + diff --git a/Src/Yj.ArcSoftSDK.4_0.csproj b/Src/Yj.ArcSoftSDK.4_0.csproj index 0f6d67d..cf1dcc1 100644 --- a/Src/Yj.ArcSoftSDK.4_0.csproj +++ b/Src/Yj.ArcSoftSDK.4_0.csproj @@ -1,70 +1,74 @@  - - net40;net5 - Yj.ArcSoftSDK - false - 2020.05.11.1 - yangjieshao - * 基于虹软的人脸识别库封装, 同时支持 windows 和 Linux -* ASFFunctions.InitEngine 初始化引擎 -* ASFFunctions.Activation 激活注册库(需联网) -* 最低配置:Intel® CoreTM i5-2300@2.80GHz 或者同级别芯片 -* 推荐配置:Intel® CoreTM i7-4600U@2.1GHz 或者同级别芯片 -* Window7 及以上系统 -* Ubuntu 14.04 及以上系统 -* 下载时间 2020-05-12 版本: v3.0 -* c++运行库 vc++2013 - - 1701;1702;CS0649;S1104;S101;S4200 - - - .\Yj.ArcSoftSDK.xml - 7.1 - + + NET6.0;NET5;NET40 + Yj.ArcSoftSDK._4_0 + false + 2021.12.01.1 + yangjieshao + + * 基于虹软的人脸识别库封装, 同时支持 windows 和 Linux + * ASFFunctions.InitEngine 初始化引擎 + * ASFFunctions.Activation 激活注册库(需联网) + * 最低配置:Intel® CoreTM i5-2300@2.80GHz 或者同级别芯片 + * 推荐配置:Intel® CoreTM i7-4600U@2.1GHz 或者同级别芯片 + * Window7 及以上系统 + * Ubuntu 14.04 及以上系统 + * 下载时间 2020-05-12 版本: v3.0 + * c++运行库 vc++2013 + * 虹软4.0 只有收费版 + * Linux 需要把 ArcLib/Sox64 下的so文件复制到 /usr/lib - - - 4.5.1 - - - 4.7.1 - - - - - 4.5.1 - - - 4.7.1 - - + 2021.06.22.1 修复了 多个人脸进入画面,对第一个人脸rgb活体检查的返回 + 2021.11.24.1 在 NET5 NET6 使用 SkiaSharp.SKBitmap 代替 System.Drawing.Bitmap + + 1701;1702;CS0649;S1104;S101;S4200 + + + .\Wenhe.ArcSoftSDK.4_0.xml + 7.1 + - - - Always - - - Always - - - true - build\ArcProLib_4_0\x64 - - - true - build\ArcProLib_4_0\x86 - - - true - build\Yj.ArcSoftSDK.targets - - + + + Always + + + + + + + Always + + + + - - - true - build\Yj.ArcSoftSDK.targets - - + + + Always + + + Always + + + + + + true + build\ArcProLib\Sox64_4.0 + + + true + build\ArcProLib\x64_4.0 + + + true + build\ArcProLib\x86_4.0 + + + true + build\Yj.ArcSoftSDK.4_0.targets + + \ No newline at end of file diff --git a/Src/Yj.ArcSoftSDK.4_0.sln b/Src/Yj.ArcSoftSDK.4_0.sln index 8b3218d..526eed7 100644 --- a/Src/Yj.ArcSoftSDK.4_0.sln +++ b/Src/Yj.ArcSoftSDK.4_0.sln @@ -1,10 +1,12 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.28307.572 +# Visual Studio Version 17 +VisualStudioVersion = 17.4.33213.308 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yj.ArcSoftSDK.4_0", "Yj.ArcSoftSDK.4_0.csproj", "{C6344C1D-9F2A-45ED-80C3-8696307DC51D}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ArcSoftFace.Test", "..\ArcSoftFace.Test\ArcSoftFace.Test.csproj", "{8A651228-7104-48D9-8F1B-AC56599F2078}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -15,6 +17,10 @@ Global {C6344C1D-9F2A-45ED-80C3-8696307DC51D}.Debug|Any CPU.Build.0 = Debug|Any CPU {C6344C1D-9F2A-45ED-80C3-8696307DC51D}.Release|Any CPU.ActiveCfg = Release|Any CPU {C6344C1D-9F2A-45ED-80C3-8696307DC51D}.Release|Any CPU.Build.0 = Release|Any CPU + {8A651228-7104-48D9-8F1B-AC56599F2078}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8A651228-7104-48D9-8F1B-AC56599F2078}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8A651228-7104-48D9-8F1B-AC56599F2078}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8A651228-7104-48D9-8F1B-AC56599F2078}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Src/Yj.ArcSoftSDK.targets b/Src/Yj.ArcSoftSDK.4_0.targets similarity index 72% rename from Src/Yj.ArcSoftSDK.targets rename to Src/Yj.ArcSoftSDK.4_0.targets index e557b17..8d5d5f9 100644 --- a/Src/Yj.ArcSoftSDK.targets +++ b/Src/Yj.ArcSoftSDK.4_0.targets @@ -4,9 +4,9 @@ True True - $(MSBuildThisFileDirectory)\ArcProLib\x86\libarcsoft_face_engine.dll - $(MSBuildThisFileDirectory)\ArcProLib\x64\libarcsoft_face_engine.dll - $(MSBuildThisFileDirectory)\ArcProLib\Sox64\libarcsoft_face_engine.so + $(MSBuildThisFileDirectory)\ArcProLib\x86_4.0\libarcsoft_face_engine.dll + $(MSBuildThisFileDirectory)\ArcProLib\x64_4.0\libarcsoft_face_engine.dll + $(MSBuildThisFileDirectory)\ArcProLib\Sox64_4.0\libarcsoft_face_engine.so This package do not contain necessary binary for X86 is targeted, but file $(NativeFileProX86) is missing. This package do not contain necessary binary for X64 is targeted, but file $(NativeFileProX64) is missing. @@ -15,22 +15,22 @@ - - ArcProLib\x86\%(RecursiveDir)%(Filename)%(Extension) + + ArcProLib\x86_4.0\%(RecursiveDir)%(Filename)%(Extension) Always - - ArcProLib\x64\%(RecursiveDir)%(Filename)%(Extension) + + ArcProLib\x64_4.0\%(RecursiveDir)%(Filename)%(Extension) Always - - ArcProLib\Sox64\%(RecursiveDir)%(Filename)%(Extension) + + ArcProLib\Sox64_4.0\%(RecursiveDir)%(Filename)%(Extension) Always diff --git a/Src/Yj.ArcSoftSDK.xml b/Src/Yj.ArcSoftSDK.xml index 3f5a766..5072ff1 100644 --- a/Src/Yj.ArcSoftSDK.xml +++ b/Src/Yj.ArcSoftSDK.xml @@ -46,12 +46,12 @@ - + 获取人脸 信息 - + 需要角度、性别、年龄信息 @@ -77,12 +77,12 @@ 算法登记照(只对4.0算法有效) - + 获取人脸个数 - + 人脸最小宽度 @@ -250,13 +250,12 @@ - + - @@ -1022,7 +1021,7 @@ - /RGB图像检测模型 + RGB图像检测模型 @@ -1120,7 +1119,7 @@ RGB 活体 - 0:非真人;1:真人;-1:不确定;-2:传入人脸数>1; + 0:非真人;1:真人;-1:不确定;-2:传入人脸数>1;-3: 人脸过小 -4: 角度过大 -5: 人脸超出边界 -6: 深度图错误 -7: 红外图太亮了 @@ -1149,6 +1148,11 @@ 口罩 "0" 代表没有带口罩,"1"代表带口罩 ,"-1"表不确定 + + + 戴眼镜置信度[0-1],推荐阈值0.5 + + 左眼状态 @@ -1593,7 +1597,7 @@ 是否是真人 - 0:非真人;1:真人;-1:不确定;-2:传入人脸数>1; + 0:非真人;1:真人;-1:不确定;-2:传入人脸数>1;-3: 人脸过小 -4: 角度过大 -5: 人脸超出边界 -6: 深度图错误 -7: 红外图太亮了 @@ -1966,6 +1970,11 @@ 图片格式 + + + 步长 + + @@ -2021,25 +2030,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - + - @@ -2049,19 +2230,13 @@ 图片 成功或失败 - + 获取图片IR信息 - 图片 + 图片 成功或失败 - - - 图像灰度化 - - - 按指定宽高缩放图片 @@ -2081,17 +2256,6 @@ 目标图片高 - - - 重设图片DPI - - - - - 使用旧照片尺寸, - true则按比例缩放图片大小,false则按原大小填充图像 - - 宽度4的倍数校验