Skip to content

Repository files navigation

🛡️ 摄像头隐私屏

别人凑过来,屏幕自己藏起来

本地人脸识别 · 非主人入镜自动模糊全屏 · 数据不出本机

PrivacyScreenGuard · Camera Privacy Guard

License Platform .NET Version

功能特性 · 快速开始 · 使用说明 · 技术细节 · 重要限制

主界面

设备选择与快捷启动 遮罩外观与健康提醒 更新与隐私数据
设备选择与快捷启动 遮罩外观与健康提醒 更新与隐私数据

1. 简介与特性

PrivacyScreenGuard 是一款 Windows 桌面「摄像头隐私屏」(WPF,.NET 8)。它用摄像头在本地识别坐在屏幕前的是不是你:一旦有陌生人入镜,立刻把整块屏幕模糊遮住;主人回到镜头前,遮罩自动解除。

全程本地推理,不上传、不录制、不保存任何画面。

🔒 本地优先 🖥️ 多屏覆盖 ⚡ 自动响应 💾 加密存储
人脸检测与比对全部在本机 CPU 完成,画面不离开内存 全部显示器 / 仅主屏 / 指定屏三种守护范围 非主人入镜约 500ms 触发遮罩,主人回归 800ms 解除 主人特征经 DPAPI 加密,换用户、换机器均无法解密

适用场景:开放工位、共享办公、图书馆、宿舍。临时离开座位不想锁屏时,或在公共场合需要屏幕内容自动隐身时。

功能特性

  • 本地人脸守护:YuNet 人脸检测 + SFace 特征识别,与主人的加密特征模板余弦比对,全程本地推理,不依赖任何云端服务。
  • 多屏遮罩:支持"全部显示器 / 仅主显示器 / 指定显示器"三种守护范围,遮罩同时覆盖所选屏幕。
  • 点击穿透:遮罩窗口不接收鼠标、不抢焦点,鼠标操作可穿透到下层窗口;不出现在任务栏与 Alt+Tab。
  • 全局热键:默认 Ctrl+Alt+P 一键暂停/恢复守护(可在设置中更换,被占用时提示)。
  • 系统托盘:常驻托盘图标(绿=守护中 / 黄=已暂停 / 红=摄像头异常),右键菜单 + 关键事件气泡提醒。
  • 加密存储:主人特征模板使用 DPAPI(当前 Windows 用户)加密落盘,换用户/换机器均无法解密;提供一键清除生物特征。
  • 健康提醒(可选):基于现有人脸检测提供久坐、用眼距离、低头坐姿、喝水、放松五类温和提醒,默认全部关闭;健康分析仅使用人脸几何数据(不保存任何图像),全部本机处理,距离与坐姿为粗略估算仅供参考,非医疗建议。
  • 明亮 / 深色主题:基于 WPF-UI(Fluent Design)实现 Windows 11 观感,主窗口右上角一键切换明亮与深色主题,选择随设置持久保存,重启后保持。
  • 单实例运行:重复启动会提示"已在运行"并退出。
  • 开机自启:可选,注册表方式,设置文件为准双向同步。

隐私承诺

  • 全本地处理:人脸检测、特征提取、比对全部在本机 CPU 完成。
  • 唯一的联网行为:仅在首次运行、模型文件缺失且用户点击确认后下载模型(约 37 MB,来自 OpenCV Zoo 官方仓库)。模型就绪后,正常运行期间不发起任何网络请求;可在设置完成后用防火墙/netstat 自行验证。
  • 不上传:不向任何服务器发送数据(包括人脸特征、画面、使用统计)。
  • 不录制、不保存原始画面:摄像头帧仅在内存中处理,处理完立即释放,绝不写盘、不缓存超过一帧、无临时文件。
  • 仅保存加密特征:落盘的只有 DPAPI 加密后的 128 维特征向量(%LOCALAPPDATA%\PrivacyScreenGuard\owner.bin),不含任何图像。
  • 一键清除:主窗口提供"清除主人人脸数据",删除加密模板后需重新注册才能继续守护。

2. 快速开始

环境要求

  • Windows 10 / 11(x64)
  • .NET 8 SDK(构建与运行源码时需要;单文件发布版无需安装运行时)
  • 可用的摄像头(内置或 USB)

获取程序

方式一:下载发布版(推荐) —— 到 Releases 下载单文件 exe,双击即用,无需安装 .NET 运行时。首次启动会提示下载模型(约 37 MB)。

方式二:从源码构建 —— 见下方「构建与运行」。

模型文件

应用启动时必须能找到以下两个模型(缺失则提示并退出):

模型 文件名 用途 许可证
YuNet 人脸检测 face_detection_yunet_2023mar.onnx(约 0.22 MB) 输出人脸框 + 5 关键点(左眼、右眼、鼻尖、左嘴角、右嘴角) Apache-2.0(可商用)
SFace 人脸识别 face_recognition_sface_2021dec.onnx(约 36.9 MB) 从对齐后的 112×112 人脸提取 128 维特征 Apache-2.0(可商用)

下载地址(OpenCV Zoo 官方 GitHub 仓库):

放置路径:

  • 程序内自动下载(推荐):首次启动时若模型缺失,程序会询问并自动下载到 exe 同目录的 models/;该位置不可写时(如安装在 Program Files)自动改用 %LOCALAPPDATA%\PrivacyScreenGuard\models\
  • 手动放置:开发期放仓库根 models/;发布后放 exe 同目录的 models/ 文件夹

程序按以下顺序查找模型目录(见 ModelLocator):① exe 同目录 models → ② 当前工作目录 models → ③ exe 目录上溯三级的 models(兼容开发期 bin/Debug 结构)→ ④ %LOCALAPPDATA%\PrivacyScreenGuard\models。

下载源按顺序尝试:GitHub 官方 → 国内镜像(ghfast.top、gh-proxy.com),任一成功即停;下载先写入 .tmp 临时文件,校验大小后原子改名,避免残缺文件被当作模型使用。下载失败时窗口内可点"重试"(会重新遍历下载源)。

构建与运行

# 构建整个解决方案
dotnet build PrivacyScreenGuard.sln

# 运行(需已按上节准备好 models/ 目录)
dotnet run --project src/PrivacyScreenGuard

调试说明:

  • 使用 Visual Studio 或 VS Code 打开 PrivacyScreenGuard.sln 即可调试(VS Code 需 C# Dev Kit 或 C# 扩展)。
  • 推荐断点:GuardEngine.OnFrameCaptured / GuardEngine.ProcessFrame(帧处理主链路)、GuardStateMachine.Process(状态机判定)。
  • 首次运行(无主人模板)会自动弹出注册向导;取消向导则应用退出。
  • 单元测试:dotnet test(状态机、健康提醒、多人在场策略、姿态过滤、模板存储共 54 个用例)。

注意:TemplateStoreTests 直接读写真实的 %LOCALAPPDATA%\PrivacyScreenGuard\owner.bin,每个用例开头会 Delete() 清场。若本机已注册主人人脸,请先备份该文件再执行 dotnet test,否则模板会被清除。

发布打包

单文件自包含发布(无需目标机器安装 .NET 运行时):

dotnet publish src/PrivacyScreenGuard/PrivacyScreenGuard.csproj -c Release -r win-x64 --self-contained -p:PublishSingleFile=true -o publish

发布完成后,需要把仓库根的 models 目录复制到 publish 目录旁边(与 PrivacyScreenGuard.exe 同级),否则启动时会提示模型缺失:

Copy-Item -Recurse models publish\models

MSIX 说明:如需商店分发或打包安装器,可再用 Visual Studio 的"Windows 应用程序打包项目"向导把发布产物打包为 MSIX;本仓库直接提供单文件 exe 即可满足常规使用。

3. 使用说明

首次引导(三步多姿态注册)

首次启动(未检测到主人模板)会打开注册向导,分三步采集(支持自动采集,约每 0.9 秒一张;采集时按当前步骤的姿态过滤,采错姿态不会入库):

  1. 正脸(必填 3~5 张):正对镜头,保持自然表情
  2. 左转头(推荐 1~2 张,可跳过):头向左转约 30° 并保持
  3. 右转头(推荐 1~2 张,可跳过):头向右转约 30° 并保持

每个姿态组内逐维平均并 L2 归一化,形成多姿态加密模板(正脸 + 左侧 + 右侧)。比对时取与全部模板的最大相似度,并带姿态自适应阈值——侧脸姿态下匹配阈值自动下调 0.08(0.55→0.47),补偿侧脸特征天然偏低的问题。主人扭头看侧屏时,侧脸会与对应方向的侧脸模板匹配上,从根上解决"侧脸被误判为陌生人"。

侧脸采集角度约 30° 即可(头转到一个方向、另一侧脸颊明显可见);过大的角度(如 90° 完全侧面)五官不可见,检测会失效,无需采集。

侧脸样本缺失时仍可完成注册(弹窗确认),但大幅扭头时可能误判。采集画面仅在本地处理,不保存任何图像;落盘的只有 DPAPI 加密后的模板特征。

设置项说明

设置项 默认值 范围/取值 说明
识别阈值 0.55 0.3–0.9 与主人特征的余弦相似度判定线,越大越严格(漏认主人多、误放陌生人少)
触发延迟 500 ms 300–800 ms 检测到非主人人脸持续多久后触发遮罩(防瞬时误触发)
恢复延迟 800 ms 500–1000 ms 主人回归后持续多久解除遮罩(防闪烁)
采集帧率 8 FPS 5–10 FPS 摄像头采集与推理频率,越低越省电
无人策略 保持正常 保持正常 / 触发锁定 画面中无人脸时是否视为风险("触发锁定"适用于离开工位自动锁屏场景)
多人在场 主人在场即放行 放行 / 有陌生人即遮罩 主人与他人同框时的策略:放行适合给别人演示;"有陌生人即遮罩"下即使主人在场,出现未匹配主人的人脸也遮罩
全局热键 Ctrl+Alt+P 可自定义 暂停/恢复守护;被其他程序占用时注册失败并提示更换
开机自启 关闭 开/关 写注册表 Run 键,与设置文件双向同步
摄像头 索引 0 下拉选择 枚举本机摄像头(名称经 WMI 对齐)
守护范围 全部显示器 全部 / 仅主屏 / 指定 多屏遮罩覆盖范围
识别侧脸样本 关闭 开/关 开启后侧脸/贴边脸也参与比对(配合左/右转头模板能认出侧脸主人、拦截侧身陌生人);关闭时侧脸不判定
模糊强度 50 0–100 遮罩激活时截屏并高斯模糊的强度(sigma 随值放大),值越大越模糊;0 = 纯黑遮罩。下次遮罩显示时生效
久坐提醒 关闭 开/关 + 阈值滑块 连续在场达到阈值分钟数后提醒起来活动;阈值范围 15–120 分钟,默认 45 分钟,中途离场超过 5 分钟累计清零
用眼距离提醒 关闭 开/关 + 阈值/时长滑块 人脸框宽超过画面宽的比例达到阈值(范围 0.25–0.5,默认 0.35)且持续(范围 5–60 秒,默认 10 秒)后提醒"稍往后靠",保护眼睛
低头坐姿提醒 关闭 开/关 + 阈值/时长滑块 低头比例超过阈值(范围 0.5–0.8,默认 0.62)且持续(范围 10–120 秒,默认 30 秒)后提醒挺直腰背
喝水提醒 关闭 开/关 + 间隔滑块 每隔设定分钟数提醒喝水;范围 15–180 分钟,默认 60 分钟
放松提醒 关闭 开/关 + 间隔滑块 每隔设定分钟数提醒远眺放松眼睛;范围 10–120 分钟,默认 30 分钟
提醒冷却 10 分钟 1–60 分钟 同类提醒的最小间隔分钟数,冷却期内同类型不重复触发;五类提醒均经托盘气泡呈现(同时显示在主窗口消息栏),修改无需重启即时生效
清除生物特征 — 按钮 删除加密模板(需确认),之后须重新注册

设置持久化于 %LOCALAPPDATA%\PrivacyScreenGuard\settings.json,非法数值在读写时自动夹取到合法范围。

托盘菜单

托盘图标右键菜单:显示主窗口 / 暂停守护·恢复守护(文案随状态切换)/ 退出;双击图标等同"显示主窗口"。触发遮罩、摄像头异常(无摄像头/被占用/断开/光线过暗/模型缺失)等关键事件会弹气泡提醒,图标圆点颜色实时反映守护状态。

4. 技术细节

NuGet 依赖

以下依赖均来自 src/PrivacyScreenGuard/PrivacyScreenGuard.csproj:

包 版本 用途
OpenCvSharp4 4.13.0.20260627 OpenCV 的 .NET 封装:摄像头采集(VideoCapture)、DNN 推理(CvDnn)、图像处理(对齐变换等)
OpenCvSharp4.runtime.win 4.13.0.20260627 OpenCV 在 Windows 上的原生动态库(随单文件发布一并打包)
OpenCvSharp4.WpfExtensions 4.13.0.20260627 Mat 与 WPF BitmapSource 互转(首次注册向导的摄像头预览)
WPF-UI 4.3.0 Fluent Design 控件样式与明暗主题服务(Windows 11 观感)
System.Management 10.0.12 通过 WMI 查询摄像头设备名称
System.Security.Cryptography.ProtectedData 10.0.12 DPAPI 加密主人特征模板
System.Text.Json 10.0.12 读写设置文件 settings.json

说明:本项目使用的 OpenCvSharp 4.13 版本没有 FaceRecognizerSF 包装类,因此 SFace 识别通过 CvDnn 直接加载 ONNX 推理,5 点对齐使用 Cv2.EstimateAffinePartial2D 自行实现(与 OpenCV 官方 SFace 实现数值等价)。

技术实现要点

  • 识别流水线:YuNet 检测(输出人脸框 + 5 关键点)→ 以 ArcFace 标准 5 点为参考,Cv2.EstimateAffinePartial2D(RANSAC 相似变换)把人脸对齐裁剪到 112×112 → SFace(CvDnn 直接加载 ONNX,预处理与 OpenCV 官方一致)提取 128 维特征 → 与主人多姿态模板(正脸 + 左/右转头,组内平均归一化)逐一比对取最大相似度;侧脸姿态下阈值自适应下调 0.08。
  • 状态机(防闪烁):每帧产生观测结论(无人 / 主人在场 / 有人但非主人);"有人但非主人"(以及无人策略为锁定时的"无人")为风险帧——连续风险达到触发延迟才显示遮罩;遮罩激活后需连续安全达到恢复延迟才解除,避免单帧抖动造成遮罩闪烁。触发/恢复延迟与无人策略变更时状态机整体重建,重建/暂停时补发 Hide 保证遮罩不卡死。
  • 多人判定:对帧内每张人脸分别比对,默认任意一张匹配主人即视为安全帧(主人在场放行,方便给别人演示);「多人在场」设为"有陌生人即遮罩"后,帧内存在未匹配主人的人脸即触发,即使主人也在场。
  • 遮罩窗口:每个目标显示器一个 WPF 无边框半透明窗口(约 88% 不透明深黑 + 提示文字),设置扩展样式 WS_EX_TRANSPARENT | WS_EX_LAYERED | WS_EX_TOOLWINDOW | WS_EX_NOACTIVATE 实现点击穿透、不进 Alt+Tab、不抢焦点,并钩 WM_MOUSEACTIVATE 返回 MA_NOACTIVATE 双保险;用 SetWindowPos 以物理像素精确定位(规避 PerMonitorV2 下 WPF DIP 换算偏差),清单声明 PerMonitorV2,跨不同缩放率的多屏可正确全覆盖;窗口句柄复用,重复显隐不重建,切换 ≤200ms。
  • 摄像头健壮性:DSHOW 后端、640×480;打开失败每 2 秒自动重试(累计 5 次提示"可能被占用"),连续 3 次读帧失败判定断开并自动重连;帧平均亮度低于暗光阈值(默认 18)以 5 秒节流提示;拔掉摄像头应用不崩溃。
  • 线程模型:帧处理在摄像头后台采集线程上同步执行(天然限流);引擎事件均在后台线程触发,UI/托盘操作一律经 Dispatcher 封送;普通状态文本 500ms 节流、推理异常 10 秒节流。

性能目标与实测建议

目标值(现代 4 核 CPU、CPU 推理):

指标 目标
CPU 占用 ≤ 15%(默认 8 FPS)
内存 ≤ 300 MB
遮罩显隐切换 ≤ 200 ms

实测建议:任务管理器观察进程 CPU/内存,让引擎以默认设置连续运行 30 分钟,确认无内存持续增长;用秒表/录屏逐帧核对遮罩出现与消失的响应时间;如 CPU 偏高,可将采集帧率下调(5–10 FPS 可调),帧率越低占用越低。

5. 重要限制(请务必了解)

  • 系统级界面无法覆盖:遮罩是普通桌面窗口,无法覆盖 UAC 提升对话框、安全桌面、锁屏、Ctrl+Alt+Del 界面,也无法覆盖受 DRM 保护的内容(如部分流媒体播放器窗口)。
  • 不能防物理手段:无法阻止他人用手机拍照、物理截屏或录屏软件录下屏幕内容;防截屏需系统级 API(SetWindowDisplayAffinity 仅对窗口内容生效),MVP 未实现。
  • 只做"非主人人脸检测":不判断视线方向(是否"正在看屏幕"),陌生人正脸入镜即触发。
  • 侧脸/贴边脸不参与判定(扭头看侧屏不误触发):只有"正脸 + 位于画面中部"的人脸才参与主人比对;明显侧脸(如主人扭头看侧屏)与贴边脸(路过/部分入镜)视为不可靠观测,既不算主人也不算陌生人——不触发遮罩但也不起保护作用。边界:陌生人刻意侧身+只露侧脸靠近屏幕时不会被遮罩拦截;主人短时间完全转出画面(画面里没人)按"无人策略"处理。建议在注册向导中完成左/右转头采集:有侧脸模板后,严格模式/多人严格策略下主人侧脸也能正确匹配,不再依赖姿态过滤放行。
  • 主人与陌生人同时在场按主人处理:帧内任意一张正脸匹配主人即不触发遮罩,陌生人可能与主人一同观看屏幕,后续版本可加强。
  • "真模糊"已实现(含边界说明):遮罩激活瞬间会在后台对屏幕做一次 GDI 截屏 → OpenCV 高斯模糊(强度可在设置中调节,0 = 纯黑遮罩)→ 以模糊画面覆盖全屏,并叠加约 35% 压暗层保证不可读。模糊快照仅存在于内存、遮罩隐藏即释放、不落盘、不上传。边界:锁屏 / 安全桌面 / DRM 保护内容下截屏会失败或得到黑块,此时自动回退为半透明纯黑遮罩;模糊图截取的是触发瞬间的画面,遮罩期间屏幕内容变化不会实时刷新(本来就不可读)。
  • 模型许可证:本项目默认的 YuNet 与 SFace 模型均为 Apache-2.0,可商用。若追求更高精度换用 ArcFace(InsightFace)官方权重,其许可证为"研究/非商业用途",商用需自行评估授权;ArcFace 仅作为可选高精度路线说明,本项目不随包分发。

6. 参与贡献

欢迎提交 Issue 与 Pull Request。开发环境搭建、测试执行、发布打包、目录结构说明等,见 CONTRIBUTING.md。

  • 发现 Bug 或有功能建议:请用 Issue 模板 提交,附上系统版本、摄像头型号与复现步骤。
  • 报告安全漏洞:请勿公开提 Issue,按 SECURITY.md 的方式私下联系。
  • 提交代码:请先阅读 CONTRIBUTING.md 中的代码风格与提交规范。

7. 开源许可

本项目基于 MIT License 开源,Copyright (c) 2026 meiwe。

第三方依赖与资源的许可证:

名称 许可证 说明
OpenCvSharp4 / .runtime.win / .WpfExtensions Apache-2.0 OpenCV 的 .NET 封装
WPF-UI MIT Fluent Design 控件样式
YuNet / SFace 模型(OpenCV Zoo) Apache-2.0 可商用,不随仓库分发,由程序按需下载
项目图标(assets/icon.svg) MIT 本项目原创

若你二次分发本项目的发布产物(单文件 exe),需一并遵守上述依赖的许可证条款(Apache-2.0 需保留版权与许可声明,MIT 需保留版权声明)。

About

摄像头隐私屏:本地人脸识别判断主人在否,非主人入镜自动模糊全屏。Windows WPF 桌面工具,画面与特征全部本机处理,数据不出本机。

Topics

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages