用 .NET 10 做人脸活体核验:SimdFace 1.1.0

把两张照片交给程序,得到一个人脸相似度,已经能解决不少问题。但如果有人把参考照片举到摄像头前,画面里还是那张脸。相似度再高,也回答不了镜头前的人有没有在做动作。

SimdFace 1.1.0 给照片比对加上了摄像头核验。浏览器采集画面,.NET 后端检查随机转头、闭眼再睁眼或张嘴再合嘴,结合防翻拍模型,最终给出两个独立结果:照片是否匹配 ,以及 活体检测是否通过 。这次也把核验会话放进了 NuGet 核心库,已有摄像头采集能力的 .NET 应用可以直接接入。 SimdFace 1.1.0 发布说明

一次核验怎么走完

系统先从参考照提取一份 SFace 特征。摄像头打开后,从第一组正脸画面建立本次核验的起点,再要求用户向随机一侧转头。用户回到正脸后,会收到一个随机的眼睛或嘴部指令。做完动作并回到自然表情后,系统再采样一组正脸,确认动作前后是同一个人,然后融合两次正脸特征与参考照比对。

图 1 参考照提供身份基准,摄像头画面同时为动作检查与身份比对提供证据。

这一流程用了四个模型,各自解决一个具体问题。

模型 在流程里的作用 执行设备
YuNet 找到人脸框和五个关键点,供人脸定位和对齐使用 CPU 或 Vulkan
SFace 生成 128 维特征,用余弦相似度比对参考照,并检查动作前后的人脸是否一致 CPU 或 Vulkan
MiniFASNetV2 在合适的正脸帧上进行防翻拍评分,提供照片或屏幕翻拍的判定依据 CPU
MediaPipe Face Mesh 估计 468 个人脸关键点,用眼睑和嘴唇的相对距离判断动作 CPU

闭眼是容易漏掉的一步。自然眨眼很短,有时只采到一帧明显闭合。因此实现会先记住两只眼各自的睁眼基线。明显的双眼闭合可以用单帧确认,重新睁眼后仍需要稳定画面。这样能兼顾眼睛较小和眨眼较快的情况。测试台里的 468 点网格来自普通彩色画面,Z 值表示模型估计的相对深度。 核验会话源码 · 眼睛与嘴部动作源码

实际检测与比对效果

下面的两张图来自 SimdFace 测试台的实际运行,使用后端 Vulkan。先上传一张 NASA 公开肖像做单图检测。绿色矩形是人脸框,五个黄色点标出双眼、鼻尖和两个嘴角。这一张检出 1 张脸,检测置信度为 93.7%。 照片来源:NASA S99-00858

图 2 YuNet 人脸定位。右上角显示原始分辨率、检出数量和置信度。

切换到双图比对后,左图仍用这张肖像,右图换成同一人在飞行任务中拍摄的照片。SFace 给出的余弦相似度为 0.7357 ,超过页面的同人阈值 0.68,本次模型判断为同一人。 右图来源:NASA S93-E-5033

图 3 SFace 双图比对。页面保留了两张照片各自的检测框和关键点。

用浏览器先跑一遍

准备 .NET 10 SDK,从 v1.1.0 标签启动 Web 测试台。四份固定权重随仓库提供。

powershell 复制代码
git clone --branch v1.1.0 --depth 1 https://github.com/donet-org-cn/SimdFace.git
cd SimdFace
dotnet restore --locked-mode
dotnet run -c Release --no-restore --project src/SimdFace.Web

打开 http://localhost:5088/verify.html,选一张清晰的单人正面照,点击「打开摄像头并开始」。可以在「推理设备」选择后端 CPU 或 Vulkan GPU。动作提示位于视频框内,右侧可以分别查看照片比对和活体检测结果。

为了展示实际提示与结论,自动化回归测试把选定的录像帧送入浏览器摄像头接口,按顺序完成了转头、闭眼和睁眼。下图遮住了录像原画,保留页面实际绘制的人脸框、动作提示和检测状态。

图 4 闭眼动作阶段。视频框内显示绿色人脸框和「请闭上双眼」。

做完动作后,页面分别显示「照片比对:匹配」和「活体检测:通过」。参考照和输入帧来自同一段测试录像,截图中的 1.000 是这一次回归的相似度。

图 5 核验完成,页面保留两个结论并关闭摄像头输入。

在手机上测试时,让手机和电脑连接同一个局域网。Windows 上可以用 PowerShell 7.4 或更新版本运行下面的脚本。把 IP 换成电脑的局域网地址,按项目说明在测试手机上信任脚本生成的测试 CA,再打开终端打印的 HTTPS 地址。 局域网 HTTPS 测试说明

powershell 复制代码
pwsh -File ./scripts/Start-CameraLab.ps1 -LanAddress 192.168.1.3

在 C# 里接入逐帧核验

已有摄像头采集代码时,可以直接安装核心包。NuGet 包提供推理和核验 API,四份 ONNX 权重从发布标签的 models/ 目录取得,放到程序工作目录的 models/ 下。参考照和视频帧由应用解码为紧密排列的 RGB24,每行无填充。 NuGet 包 · 模型权重与许可证

powershell 复制代码
dotnet add package SimdFace --version 1.1.0

下面的类可以放进开启隐式 using 的 .NET 10 项目。模型加载一次即可复用,VerifyAsync 每次创建一个新会话。把摄像头输出接到 frames,按采集顺序和实际帧间隔送入,避免把积压的帧一次性灌入会话。

csharp 复制代码
using SimdFace;

public sealed record RgbFrame(byte[] Pixels, int Width, int Height);

public sealed class CameraVerifier(string modelDirectory)
{
    private readonly FaceDetector detector =
        new(Path.Combine(modelDirectory, FaceDetector.ModelFileName));
    private readonly FaceRecognizer recognizer =
        new(Path.Combine(modelDirectory, FaceRecognizer.ModelFileName));
    private readonly FaceAntiSpoof antiSpoof =
        new(Path.Combine(modelDirectory, FaceAntiSpoof.ModelFileName));
    private readonly FaceMesh mesh =
        new(Path.Combine(modelDirectory, FaceMesh.ModelFileName));

    public async Task<FaceVerificationResult?> VerifyAsync(
        RgbFrame referencePhoto,
        IAsyncEnumerable<RgbFrame> frames,
        Action<FaceVerificationResult> onFrame,
        CancellationToken cancellationToken = default)
    {
        var faces = detector.Detect(
            referencePhoto.Pixels, referencePhoto.Width, referencePhoto.Height);
        if (faces.Count != 1)
            throw new ArgumentException("参考照需要恰好一张脸。", nameof(referencePhoto));

        var embedding = recognizer.EmbedForVerification(
            referencePhoto.Pixels, referencePhoto.Width, referencePhoto.Height,
            faces[0].Landmarks, cancellationToken);
        var session = new FaceVerificationSession(detector, recognizer, antiSpoof, mesh, embedding);

        await foreach (var frame in frames.WithCancellation(cancellationToken))
        {
            var result = session.ProcessFrame(
                frame.Pixels, frame.Width, frame.Height, cancellationToken);
            onFrame(result);
            if (result.IsFinished)
                return result;
        }

        // 视频流已结束,核验尚未得出结论。
        return null;
    }
}

应用层可以读取 Stage、TurnDirection、ExpressionPrompt 和 Hint 来更新提示。frames 来自应用已有的采集器。下面的调用给一次尝试设置 45 秒时限,只有两个结论都符合条件才接受。

csharp 复制代码
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(45));
var verifier = new CameraVerifier("models");

FaceVerificationResult? result;
try
{
    result = await verifier.VerifyAsync(referencePhoto, cameraFrames,
        frame => Console.WriteLine($"{frame.Stage} {frame.ExpressionPrompt} {frame.Hint}"),
        timeout.Token);
}
catch (OperationCanceledException) when (timeout.IsCancellationRequested)
{
    Console.WriteLine("核验超时,请重新开始。");
    result = null;
}

bool accepted = result is
{
    Identity: FaceIdentityDecision.Match,
    Liveness: FaceLivenessDecision.Passed
};

如果 Liveness 通过而 Identity 是 Uncertain,页面应当提示身份无法确认。参考照太旧、角度差异大或光照不均,都值得先换成一张清晰的正面照再试。相似度阈值需要用自己的正负样本验证。活体部分也要用目标设备测试现场照片和屏幕回放,才能知道方案在实际场景里的表现。

推理放在哪里

核心推理使用 C#,CPU 路径使用 SIMD。选择 Vulkan 时,YuNet 与 SFace 的模型算子可交给 GPU,MiniFASNetV2 与 Face Mesh 仍在 CPU 上运行。摄像头测试台由浏览器采集,核验计算由 ASP.NET Core 后端执行。项目另有浏览器 WASM 照片检测和比对入口。

用录像帧做的回归覆盖了闭眼再睁眼、张嘴再合嘴以及两份翻拍样本。发布前也用正式包在 CPU 和 RTX 3060 上执行了推理检查。GitHub Actions 在 Linux 上构建并消费打出的包,检查软件 Vulkan 设备的识别,然后发布到 NuGet.org 并核对公开下载。 流水线记录

如果你想先体验交互,可以直接启动上面的 Web 测试台。如果已经有图像或视频采集管线,可以从 FaceVerificationSession.ProcessFrame 开始,把结果接到现有界面。 项目源码与中英文文档 · SimdFace 1.1.0 on NuGet.org

相关推荐
土星云SaturnCloud7 天前
基于 ArcFace 的闸机门禁刷脸:从底库整理到土星云 SE110S 系列边缘部署
人脸识别·边缘计算·arcface
AI人工智能+9 天前
炫彩活体检测利用手机屏幕投射随机彩色光,通过分析真实皮肤对光的次表面散射、血红蛋白吸收及纹理细节等光学特性,实现1-2秒内无感核验
人工智能·深度学习·人脸识别·炫彩活体检测
feishixin12317 天前
代理网络环境下 Linux Pro 在线激活实操指南
人脸识别·后端服务器
只睡四小时19 天前
端侧推理:face-api.js 首屏 92% 是白下载的
开发语言·javascript·人脸识别·ecmascript·tensorflow.js·face-api.js·端侧推理
豆角焖肉1 个月前
SpringBoot 集成腾讯 AI 人脸识别
人工智能·spring boot·后端·人脸识别·腾讯 ai·base64 图片
TGITCIC1 个月前
CNN 小白实战入门(九):检测到人脸后,进一步判断谁戴了口罩
人工智能·cnn·人脸识别·卷积神经网络·人脸
AI人工智能+2 个月前
炫彩活体检测利用手机屏幕发出动态彩色光,通过分析人脸皮肤对红、绿、蓝光的次表面散射特性,区分真人与照片、视频、3D面具等伪造物
人工智能·深度学习·人脸识别·人脸活体检测·炫彩活体检测
geovindu2 个月前
python: Face Recognition
开发语言·后端·python·人脸识别
陈年老古董2 个月前
OpenCV 人脸识别学习笔记:从Haar检测到三种特征脸算法实战
笔记·opencv·学习·人脸识别