首页/新闻资讯/正文详情

Windows-universal-samples 中的 BasicFaceDetection 示例:使用 FaceDetector 在 UWP 应用中实现静态人脸检测

发布时间:2026/9/25 13:41:29 来源:云帆数科 栏目:资讯中心
Windows-universal-samples 中的 BasicFaceDetection 示例:使用 FaceDetector 在 UWP 应用中实现静态人脸检测
示例工程【免费下载链接】Windows-universal-samplesAPI samples for the Universal Windows Platform.项目地址https://gitcode.com/gh_mirrors/wi/Windows-universal-samples点击查看免费下载本指南以 Windows-universal-samples 仓库中的 BasicFaceDetection 示例为蓝本系统讲解 UWP 应用中如何使用Windows.Media.FaceAnalysis.FaceDetector类在一张静态照片或单帧视频中定位人脸并完成像素格式转换、检测结果可视化与界面缩放同步。读完本文你将掌握FaceDetector的初始化与复用策略、SoftwareBitmap/VideoFrame两种输入路径的构建方法以及如何用 XAMLCanvas绘制人脸框并在窗口缩放时保持位置准确。示例概览与目录结构示例位于 Samples/BasicFaceDetection包含两个并列的实现语言目录与一个共享 UI 目录目录说明csC# 实现Scenario1_DetectInPhoto.xaml.cs、Scenario2_DetectInWebcam.xaml.cs、SampleConfiguration.cscppwinrtC/WinRT 实现Scenario1_DetectInPhoto.cpp、Scenario2_DetectInWebcam.cpp、SampleConfiguration.cppshared两个场景共享的 XAML 页面Scenario1_DetectInPhoto.xaml与Scenario2_DetectInWebcam.xaml两个场景通过 SampleConfiguration.cs 中的场景列表注册到示例框架Detect Faces in Photos从文件选择器中挑选一张图片jpg/jpeg/png/bmp解码后执行人脸检测Detect Faces in Webcam启动摄像头实时预览抓取单帧快照后执行人脸检测。从源码结构看两个场景的差异仅在于输入源照片场景把解码后的SoftwareBitmap交给FaceDetector网络摄像头场景则把MediaCapture抓取到的VideoFrame中的SoftwareBitmap交给同一个检测器后续的检测调用与可视化逻辑完全一致。FaceDetector 的初始化与复用创建检测器实例FaceDetector位于Windows.Media.FaceAnalysis命名空间只能通过异步工厂方法创建FaceDetector detector await FaceDetector.CreateAsync();照片场景的源码Scenario1_DetectInPhoto.xaml.cs特别注释了这一点FaceDetector初始化可能耗时较长在大多数情况下应当创建成员变量并复用该对象本场景为了演示简洁性每次点击按钮时新建实例。因此实际项目中推荐的模式是在页面或服务对象中保存一个FaceDetector字段在首次使用时惰性创建后续检测直接复用避免反复承担初始化开销。检测前的格式校验FaceDetector只接受有限的像素格式检测前必须用静态方法校验if (FaceDetector.IsBitmapPixelFormatSupported(InputPixelFormat)) { // 执行检测 }示例在两个场景中分别校验了两种典型格式照片场景使用BitmapPixelFormat.Gray88 位灰度因为人脸检测本质上不需要彩色信息灰度图体积小、检测更快网络摄像头场景使用BitmapPixelFormat.Nv12这是摄像头预览流常见的 YUV 格式MediaCapture.GetPreviewFrameAsync会把原生帧转换为此格式。校验失败时会通过rootPage.NotifyUser输出错误提示例如 PixelFormat Gray8 is not supported by FaceDetector。场景一从照片文件检测人脸文件选择与位图解码照片场景通过 FileOpenPicker 提供的按钮触发选择器限制为图片扩展名FileOpenPicker photoPicker new FileOpenPicker(); photoPicker.ViewMode PickerViewMode.Thumbnail; photoPicker.SuggestedStartLocation PickerLocationId.PicturesLibrary; photoPicker.FileTypeFilter.Add(.jpg); photoPicker.FileTypeFilter.Add(.jpeg); photoPicker.FileTypeFilter.Add(.png); photoPicker.FileTypeFilter.Add(.bmp);选中文件后用BitmapDecoder解码位图并制作两份副本——一份交给检测器一份用于显示using (IRandomAccessStream fileStream await photoFile.OpenAsync(Windows.Storage.FileAccessMode.Read)) { BitmapDecoder decoder await BitmapDecoder.CreateAsync(fileStream); BitmapTransform transform this.ComputeScalingTransformForSourceImage(decoder); using (SoftwareBitmap originalBitmap await decoder.GetSoftwareBitmapAsync( decoder.BitmapPixelFormat, BitmapAlphaMode.Ignore, transform, ExifOrientationMode.IgnoreExifOrientation, ColorManagementMode.DoNotColorManage)) { const BitmapPixelFormat InputPixelFormat BitmapPixelFormat.Gray8; if (FaceDetector.IsBitmapPixelFormatSupported(InputPixelFormat)) { using (SoftwareBitmap detectorInput SoftwareBitmap.Convert(originalBitmap, InputPixelFormat)) { // 显示用副本 WriteableBitmap displaySource new WriteableBitmap(originalBitmap.PixelWidth, originalBitmap.PixelHeight); originalBitmap.CopyToBuffer(displaySource.PixelBuffer); FaceDetector detector await FaceDetector.CreateAsync(); IListDetectedFace faces await detector.DetectFacesAsync(detectorInput); this.SetupVisualization(displaySource, faces); } } } }关键点有三个格式转换用SoftwareBitmap.Convert把原始位图转为Gray8这是检测器输入显示副本WriteableBitmap不支持灰度图因此显示时仍使用原始像素格式的位图通过CopyToBuffer拷贝到WriteableBitmap.PixelBuffer检测调用DetectFacesAsync(detectorInput)返回IListDetectedFace其中DetectedFace.FaceBoxBitmapBounds结构给出了每个人脸的包围矩形坐标。大图降采样1280 像素高度限制FaceDetector在超大图片上的性能会显著下降示例因此设置了一个输入高度上限。C# 与 C/WinRT 两侧的常量完全一致private readonly uint sourceImageHeightLimit 1280;static constexpr uint32_t sourceImageHeightLimit 1280;ComputeScalingTransformForSourceImage在解码时按比例降采样当PixelHeight超过 1280 时按1280 / 原始高度的比例同时缩放宽高返回一个BitmapTransform交给GetSoftwareBitmapAsync。源码注释明确说明这是为兼顾检测精度与性能而选择的任意值实际应用应根据自身性能/精度需求调整。场景二从摄像头快照检测人脸摄像头初始化与预览网络摄像头场景的状态机Idle → Streaming → Snapshot由 Scenario2_DetectInWebcam.xaml.cs 管理。启动流式传输时依次完成创建FaceDetector→ 初始化MediaCapture→ 缓存视频属性 → 开始预览this.faceDetector await FaceDetector.CreateAsync(); MediaCaptureInitializationSettings settings new MediaCaptureInitializationSettings(); settings.StreamingCaptureMode StreamingCaptureMode.Video; // 仅视频不申请麦克风 await this.mediaCapture.InitializeAsync(settings); this.mediaCapture.CameraStreamStateChanged this.MediaCapture_CameraStreamStateChanged; var deviceController this.mediaCapture.VideoDeviceController; this.videoProperties deviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview) as VideoEncodingProperties; this.CamPreview.Source this.mediaCapture; // CaptureElement 的 Source 必须在启动前设置 await this.mediaCapture.StartPreviewAsync();这里有两个值得注意的工程细节能力声明匹配初始化设置只声明了StreamingCaptureMode.Video与 Package.appxmanifest 中仅声明的webcam设备能力对应。源码注释特别警告如果改用包含麦克风的默认构造函数则必须同时在清单中补充microphone能力否则初始化会失败异常处理如果用户在隐私设置中禁用了摄像头InitializeAsync会抛出UnauthorizedAccessException示例会给出明确提示Webcam is disabled or access to the webcam is disabled for this app. Ensure Privacy Settings allow webcam usage.。UWP 应用中相机访问需要用户在系统设置中授予隐私权限这是实际部署时最常见的失败点之一。抓帧并执行检测点击 Take Snapshot 后用VideoFrame指定 NV12 目标格式再调用GetPreviewFrameAsync让系统把摄像头原生帧转换为该格式const BitmapPixelFormat InputPixelFormat BitmapPixelFormat.Nv12; using (VideoFrame previewFrame new VideoFrame(InputPixelFormat, (int)this.videoProperties.Width, (int)this.videoProperties.Height)) { await this.mediaCapture.GetPreviewFrameAsync(previewFrame); if (FaceDetector.IsBitmapPixelFormatSupported(previewFrame.SoftwareBitmap.BitmapPixelFormat)) { IListDetectedFace faces await this.faceDetector.DetectFacesAsync(previewFrame.SoftwareBitmap); // WriteableBitmap 不支持 NV12转换为 32 位 BGRA 用于显示 using (SoftwareBitmap convertedSource SoftwareBitmap.Convert(previewFrame.SoftwareBitmap, BitmapPixelFormat.Bgra8)) { displaySource new WriteableBitmap(convertedSource.PixelWidth, convertedSource.PixelHeight); convertedSource.CopyToBuffer(displaySource.PixelBuffer); } this.SetupVisualization(displaySource, faces); } }注意这里的格式选择与照片场景相反检测输入保持 NV12摄像头预览原生格式避免额外转换开销而显示副本转为 BGRA8因为WriteableBitmap不支持 NV12。抓帧完成后立即关闭摄像头并释放MediaCapture进入Snapshot状态展示结果点击 Clear Display 则回到Idle。应用挂起Suspending事件时示例通过延迟SuspendingOperation.GetDeferral确保先回到Idle状态、释放摄像头资源再完成挂起流程。检测结果的可视化与缩放同步用黄色边框框出人脸两个场景共享同一套可视化逻辑。共享 XAML 中定义了一个DataTemplate见 Scenario1_DetectInPhoto.xamlPage.Resources DataTemplate x:NameHighlightedFaceBox Border BorderBrushYellow BorderThickness2/ /DataTemplate /Page.ResourcesC# 侧的MainPage.HighlightFacesSampleConfiguration.cs把检测结果逐个渲染到Canvas上public static void HighlightFaces(WriteableBitmap displaySource, IListDetectedFace foundFaces, Canvas canvas, DataTemplate template) { double widthScale canvas.ActualWidth / displaySource.PixelWidth; double heightScale canvas.ActualHeight / displaySource.PixelHeight; foreach (DetectedFace face in foundFaces) { var box (FrameworkElement)template.LoadContent(); box.Tag face.FaceBox; // 保存原始包围盒供后续缩放 ApplyScale(box, widthScale, heightScale); canvas.Children.Add(box); } // 输出 Found N human faces in the image 等状态消息 }C/WinRT 的SampleHelpers::HighlightFacesSampleConfiguration.cpp逻辑完全对应仅把 C# 的box.Tag换成了box.Tag(box_value(face.FaceBox()))。缩放自适应Tag 保存原始坐标由于图片尺寸与Canvas的实际显示尺寸往往不同示例把face.FaceBox的原始值存入元素的Tag再按缩放比例换算宽高与边距static void ApplyScale(FrameworkElement box, double widthScale, double heightScale) { BitmapBounds faceBox (BitmapBounds)box.Tag; box.Width faceBox.Width * widthScale; box.Height faceBox.Height * heightScale; box.Margin new Thickness(faceBox.X * widthScale, faceBox.Y * heightScale, 0, 0); }当窗口尺寸变化触发Canvas.SizeChanged时RepositionFaces重新计算缩放因子并对所有子元素重新应用ApplyScale从而保证人脸框始终与图像内容对齐。这是 UWP 自适应布局中处理图像坐标系 ↔ 控件坐标系映射的通用手法。构建与运行系统要求按 README.md 的说明示例需要硬件摄像头仅用于视频捕获场景照片场景不需要客户端Windows 10服务端Windows Server 2016 Technical Preview手机Windows 10。Package.appxmanifest中声明TargetDeviceFamily的MinVersion10.0.10240.0即首个 Windows 10 正式版本即可运行。构建步骤若下载的是整个示例集合的 ZIP务必解压整个归档文件而不仅是目标示例所在文件夹——示例依赖共享的SharedContent目录启动 Visual Studio选择File Open Project/Solution定位到示例的cs或cppwinrt子目录双击其中的解决方案文件BasicFaceDetection.sln按CtrlShiftB或选择Build Build Solution。运行步骤仅部署选择Build Deploy Solution调试运行按F5或选择Debug Start Debugging免调试运行按CtrlF5或选择Debug Start Without Debugging。重要边界FaceDetector 与 FaceTracker 的选型README 明确给出了一条关键的设计约束FaceDetector面向静态图像或视频单帧并非为视频播放或实时摄像头流优化。如果需要实时跟踪人脸无论是直播流还是视频片段应改用FaceTrackerAPI。仓库中的相关示例可直接对照学习BasicFaceTracking实时人脸跟踪示例C/C#/C/WinRTHolographicFaceTracking基于 C 的混合现实人脸跟踪FilePicker照片场景依赖的文件选择器用法CameraStarterKit摄像头初始化与预览的完整示例SimpleImaging位图解码与SoftwareBitmap基础操作。小结BasicFaceDetection 示例完整演示了 UWP 人脸检测的四个核心环节FaceDetector的创建与复用、输入位图的获取与像素格式转换、DetectFacesAsync的调用以及基于Canvas的检测结果可视化。其源码还包含两个值得迁移到实际项目的工程细节用 1280 像素高度上限对大图降采样以平衡性能与精度以及用Tag保存原始包围盒坐标实现窗口缩放时的人脸框自适应。理解这些实现后你可以快速为自己的 UWP 应用接入静态图片/单帧视频的人脸检测能力并在需要连续跟踪时平滑切换到FaceTracker方案。赞分享示例工程【免费下载链接】Windows-universal-samplesAPI samples for the Universal Windows Platform.项目地址https://gitcode.com/gh_mirrors/wi/Windows-universal-samples点击查看免费下载相关推荐提升研究质量Awesome Claude Skills学术写作助手提升研究质量Awesome Claude Skills学术写作助手 Awesome Claude Skills是一个精心策划的Claude技能、资源和工具列表AI 技能AI 插件人工智能工作流自动化技术栈迁移指南从国际标准到国密算法的完整实施路径技术栈迁移指南从国际标准到国密算法的完整实施路径 面对日益严峻的网络安全挑战和技术自主可控要求企业级应用正在加速从传统国际加密算法向国密算法技术栈迁移。Op密码学网络安全通信UWP 应用数据存储实战Windows-universal-samples 之 ApplicationData 示例深度解析UWP 应用数据存储实战Windows universal samples 之 ApplicationData 示例深度解析 导读 本文以 Windows u示例工程上一篇5个步骤掌握Audiveris免费开源乐谱识别软件的终极指南下一篇Semantica store migrate 命令详解FAISS、SQLite 与 pgvector 之间迁移向量库创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

免费CRM与私人网站的区别:永久在线客户管理系统如何驱动销售闭环
免费CRM与私人网站的区别:永久在线客户管理系统如何驱动销售闭环

1. 谈选型前,先把“免费CRM”和“私人网站”这两个概念掰开做销售管理这行超过十年,我见过太多团队在CRM选型上栽跟头。尤其是这两年,市面上冒出大量打着“永久在线”“免费”旗号的CRM网站,从蝉鸣、飞鱼到各种不知名的小平台&… · 2026/9/25 13:41:23

Semi Design Dropdown 下拉菜单组件实战指南:用法、API 与无障碍设计全解析
Semi Design Dropdown 下拉菜单组件实战指南:用法、API 与无障碍设计全解析

前端UI组件设计系统 【免费下载链接】semi-design 🚀A modern, comprehensive, flexible design system and React UI library, AI-friendly built-in.🎨Provide 3000 Design Tokens, easy to build your design system. Make Semi Design to Any Design… · 2026/9/25 13:41:23

GHelper:华硕笔记本的奥创平替,3 步装好不折腾
GHelper:华硕笔记本的奥创平替,3 步装好不折腾

GHelper:华硕笔记本的奥创平替,3 步装好不折腾 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops with nearly the same functionality. Works with ROG Zephyrus, Flow, TUF, Strix, Scar, ProArt, Vivobook, Zenbook… · 2026/9/25 13:41:10

MySQL批量删除相同前缀数据表:安全清理与防误删全攻略
MySQL批量删除相同前缀数据表:安全清理与防误删全攻略

简介:针对MySQL数据库中相同前缀数据表的批量清理需求,这款基于PHP开发的小工具提供了直接可用的脚本方案。开发者只需配置数据库连接信息并指定表前缀,即可一次删除所有匹配的数据表,尤其适合开发、测试环境中快速重置临时表或项… · 2026/9/25 14:16:23

通讯优先的CRM系统落地实践:从桌面端到客户档案
通讯优先的CRM系统落地实践:从桌面端到客户档案

从接到“DeskcommCRM”这个项目到现在,前后差不多大半年时间。刚开始团队其实没有很深的CRM基础,大家想象的客户管理系统无非就是建个客户库、记录跟进、统计业绩。但真正跑到一线调研之后才发现,半数以上的销售和客服团队,工作重… · 2026/9/25 14:16:09

Hugo Blox Portfolio 的 Accomplishments 组件:证书与成就时间线配置实战
Hugo Blox Portfolio 的 Accomplishments 组件:证书与成就时间线配置实战

静态站点前端开发工具 【免费下载链接】kit 🧱 Describe your site, AI builds it, you own it as Markdown. Snap together Tailwind blocks like Lego — landing pages, blogs, portfolios, docs & more. No AI slop. Free to deploy anywhere 👇… · 2026/9/25 14:16:03

互联网大事记:技术演进与商业变革双线复盘
互联网大事记:技术演进与商业变革双线复盘

我无法根据当前输入生成符合要求的博文。原因如下:项目标题“互联网的大事记”是一个高度泛化、缺乏具体技术指向或实操场景的宏观概念性表述;项目正文为空,未提供任何实质性内容、背景、范围界定(如时间跨度:1994–20… · 2026/9/25 14:15:50

Windows上用VS2008编译zhparser:PostgreSQL中文全文检索扩展指南
Windows上用VS2008编译zhparser:PostgreSQL中文全文检索扩展指南

简介:面向Windows下PostgreSQL中文分词需求的开发者,这份资源包提供了zhparser扩展在VS2008环境下的完整编译安装方案,解决原版仅支持Linux、Windows下无现成工程的关键痛点。zhparser基于scws分词库设计,作者通过自建VS2008项目&… · 2026/9/25 14:15:50

昇腾Atlas 300V推理卡部署YOLO模型完整指南
昇腾Atlas 300V推理卡部署YOLO模型完整指南

1. Atlas 到底是什么:先解决“从哪下手”的问题如果你最近在搜索框里敲下“atlas”这个词,大概率不是在看什么古希腊神话,而是盯上了华为昇腾的 Atlas 系列 AI 计算设备。实话实说,我在第一次接触 Atlas 的时候也懵过一阵&#xf… · 2026/9/25 14:15:44

数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)
数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31

创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31

MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:37

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码