FaceDetector类支持从指定的位图中检测出人脸所在的区域,检测结果用DetectedFace对象表示。人脸检测结果可以从DetectedFace类公开的FaceBox属性中获取,包含人脸区域相对于位图的位置,例如X和Y坐标,以及宽度和高度。

FaceDetector公开一些静态成员,用以在使用FaceDetector之前进行相关的验证。如果当前设备不支持人脸检测,则IsSupported属性会返回false。

如下代码片段所示:

            bool isSupport = FaceDetector.IsSupported;Debug.WriteLine($"设备是否支持人脸检测: {isSupport}");

另外需要验证的一点就是哪些像素格式支持人脸检测操作。目前FaceDetector支持两种像素格式——Nv12和Gray8。

可以调用IsBitmapPixelFormatSupported方法来判断某个像素格式是否受支持,或者通过下面代码来获取FaceDetector所支持的像素格式列表。

            IReadOnlyList<BitmapPixelFormat> formats = FaceDetector.GetSupportedBitmapPixelFormats();string msg = $"受支持的像素格式: \n{string.Join("\n",formats)}";Debug.WriteLine(msg);

要对位图进行人脸检测,需要一个SoftwareBitmap对象。如果要从文件中读取图像,应使用BitmapDecoder类来解码图像文件,随后就可以从GetSoftwareBitmapAsync方法返回SoftwareBitmap实例。SoftwareBitmap除了用于存储加载到内存中的位图数据外,还可以转换图像的像素格式,前文提到过,人脸检测组件仅支持Nv12和Gray8两种像素格式,若是读取的图像的像素格式不受支持,可以调用Convert方法将图像的像素格式转换为Gray8或者Nv12,然后再进行人脸检测。要在用户界面上显示SoftwareBitmap对象中存放的图像,可以先实例化一个SoftwareBitmapSource对象,然后调用该对象的SetBitmapAsync方法来设置一个关联的SoftwareBitmap对象,最后将SoftwareBitmapSource实例赋值给Image控件的Source属性。

下面将通过示例演示一下FaceDetector类的使用方法。

(1). 新建一个应用程序项目。

(2). 示例用户界面的XAML代码如下所示:

    <Page.Resources><Style x:Key="rectangleStyle" TargetType="Rectangle"><Setter Property="Stroke" Value="IndianRed"/><Setter Property="StrokeThickness" Value="5"/></Style></Page.Resources><Grid x:Name="layout" Margin="8" Background="LightGray" SizeChanged="layout_SizeChanged"><Grid.RowDefinitions><RowDefinition/><RowDefinition Height="auto"/></Grid.RowDefinitions><Image x:Name="img" Stretch="Uniform"/><Canvas x:Name="facesCvs"/><Button x:Name="btn" Content="开始检测人脸" Grid.Row="1" Margin="10" Background="Black" Tapped="btn_Tapped"/></Grid>

Image控件用于显示打开的图像文件,用于标记人脸区域的矩形列表将添加到Canvas面板的子元素集合中。

(3). Button事件处理程序如下(浏览一个图像文件,并检测出图像中人脸的位置):

        private async void btn_Tapped(object sender, TappedRoutedEventArgs e){//选取一个图像文件FileOpenPicker picker = new FileOpenPicker();picker.FileTypeFilter.Add(".jpg");picker.FileTypeFilter.Add(".jpeg");var imgFile = await picker.PickSingleFileAsync();if (imgFile != null){//解码图像文件using (IRandomAccessStream imgFileStream = await imgFile.OpenReadAsync()){BitmapDecoder decoder = await BitmapDecoder.CreateAsync(imgFileStream);//获取SoftwareBitmap对象SoftwareBitmap softBitmap = await decoder.GetSoftwareBitmapAsync(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied);//创建SoftwareBitmapSourceSoftwareBitmapSource bitmapSource = new SoftwareBitmapSource();await bitmapSource.SetBitmapAsync(softBitmap);//在Image元素中显示图像img.Source = bitmapSource;//将源图像的大小保存到Canvas面板的Tag属性中,随后需要用到Tuple<int, int> tpsize = new Tuple<int, int>(softBitmap.PixelWidth, softBitmap.PixelHeight);facesCvs.Tag = tpsize;//将像素格式转换为Gray8SoftwareBitmap todetectBitmap = SoftwareBitmap.Convert(softBitmap, BitmapPixelFormat.Gray8);//获取FaceDetector实例FaceDetector detector = await FaceDetector.CreateAsync();//对图像进行人脸检测IList<DetectedFace> results = await detector.DetectFacesAsync(todetectBitmap);//释放不再需要的资源todetectBitmap.Dispose();softBitmap.Dispose();//显示标注人脸位置的矩形AddRectanglesToCanvas(results);}}}

首先应通过BitmapDecoder对象获取一个SoftwareBitmap实例,但是,这个SoftwareBitmap实例的像素格式为Bgra8,可是FaceDetector类不支持该像素格式。因此,需要编写代码将图像的像素格式转换为Gray8。如本例中的以下代码:

                    SoftwareBitmap todetectBitmap = SoftwareBitmap.Convert(softBitmap, BitmapPixelFormat.Gray8);

Convert是静态方法,第一个参数是待转换的SoftwareBitmap对象,第二个参数指定目标像素格式,在本利中应为Gray8。

FaceDetector组件未公开任何可用的构造函数,要获得FaceDetector类的实例,请调用CreateAsync方法。

图像被检测后,以DetectedFace列表的形式返回,因为一个图像中,可能会包含多张人脸,每张脸所在的区域都用一个DetectedFace实例来表示。

在用户界面中显示人脸区域时要注意,DetectedFace对象所描述的人脸区域是相对于原来的图像的,而Image控件所呈现的内容的尺寸与原图像不同,因此,标注人脸区域的矩形元素的坐标和大小不能直接使用DetectedFace对象所提供的数据,必须对人脸区域的位置和大小进行重新计算。计算过程是,首先让Image控件所呈现的尺寸与原图像的尺寸进行比例运算,得到比例系数,最后把DetectedFace对象所提供的数据乘以这个比例系数,就可以得到矩形元素要呈现的实际区域了。

AddRectanglesToCanvas方法的功能是根据FaceDetector类的检测结果计算每个矩形的位置和大小,并将矩形添加到Canvas面板的子元素集合中。具体代码如下:

        private void AddRectanglesToCanvas(IList<DetectedFace> detectedResults){//先清空Canvas面板中的所有子元素facesCvs.Children.Clear();if (detectedResults.Count == 0){return;}//从Tag属性中取得源图像的宽度和高度Tuple<int, int> tp = facesCvs.Tag as Tuple<int, int>;//计算源图像与Image元素的尺寸比例double scaleWid = img.ActualWidth / tp.Item1;double scaleHei = img.ActualHeight / tp.Item2;//获取Image元素的左上角相对于父元素的坐标GeneralTransform gf = img.TransformToVisual(layout);Point imgTopleftPoint = gf.TransformPoint(new Point());//添加表示人脸位置的矩形foreach (DetectedFace face in detectedResults){var rectangle = new Rectangle();facesCvs.Children.Add(rectangle);//应用样式rectangle.Style = Resources["rectangleStyle"] as Style;//计算矩形应呈现的位置rectangle.Width = face.FaceBox.Width * scaleWid;rectangle.Height = face.FaceBox.Height * scaleHei;Canvas.SetLeft(rectangle, imgTopleftPoint.X + face.FaceBox.X * scaleWid);Canvas.SetTop(rectangle, imgTopleftPoint.Y + face.FaceBox.Y * scaleHei);//将DetectedFace对象与Rectangle元素的Tag属性关联rectangle.Tag = face;}}

(4). 到此步,示例应用程序的大致功能已经实现。但是,有一个问题不得不考虑:由于Image控件位于Grid中,默认的对齐方式是完全填充,一旦窗口的大小被调整,Image元素的宽度和高度会改变,先前添加到Canvas面板中的矩形的位置和大小应当进行相应的调整。为了完成该功能,可以处理Grid容器的SizeChanged事件,当Grid元素的大小改变时会自动引发此事件。响应该事件,重新计算矩形列表的位置和大小:

SizeChanged事件处理程序如下:

        private void layout_SizeChanged(object sender, SizeChangedEventArgs e){if (facesCvs.Children.Count == 0){return;}//从Tag属性中取得源图像的宽度和高度Tuple<int, int> tp = facesCvs.Tag as Tuple<int, int>;//计算源图像与Image元素的尺寸比例double scaleWid = img.ActualWidth / tp.Item1;double scaleHei = img.ActualHeight / tp.Item2;//获取Image元素的左上角相对于父元素的坐标GeneralTransform gf = img.TransformToVisual(layout);Point imgTopleftPoint = gf.TransformPoint(new Point());//重新计算矩形的位置foreach (var element in facesCvs.Children){Rectangle rect = element as Rectangle;DetectedFace face = rect.Tag as DetectedFace;rect.Width = face.FaceBox.Width * scaleWid;rect.Height = face.FaceBox.Height * scaleHei;Canvas.SetLeft(rect, imgTopleftPoint.X + face.FaceBox.X * scaleWid);Canvas.SetTop(rect,imgTopleftPoint.Y + face.FaceBox.Y * scaleHei);}}

刚才在AddRectanglesToCanvas方法中已经把每个DetectedFace对象与矩形元素的Tag属性关联,所以此处从矩形元素的Tag属性中就可以取出对应的DetectedFace实例。

运行效果如下:

人脸检测(图像处理)相关推荐

  1. OpenCV图像处理——iOS端人脸检测

    前言 1.OpenCV有专门的iOS平台的包,可以真接下载导入工程,也可以用cmake把OpenCV源码编成.a文件,以静态库的形式导入工程. 2.我这里用的Xcode11,OpenCV用的是最4.2 ...

  2. [Python图像处理] 二十八.OpenCV快速实现人脸检测及视频中的人脸

    该系列文章是讲解Python OpenCV图像处理知识,前期主要讲解图像入门.OpenCV基础用法,中期讲解图像处理的各种算法,包括图像锐化算子.图像增强技术.图像分割等,后期结合深度学习研究图像识别 ...

  3. OpenCV与图像处理学习十七——OpenCV人脸检测(含代码)

    OpenCV与图像处理学习十七--OpenCV人脸检测(含代码) 一.人脸识别概要 1.1 人脸检测 1.2 人脸对齐(Face Alignment) 1.3 人脸特征提取(Face Feature ...

  4. 人脸表情识别/人脸检测/ML/DL/图像处理博主

    人脸表情识别/人脸检测/ML/DL/图像处理博主 人脸表情识别/人脸检测/ML/DL/图像处理博主:https://blog.csdn.net/app_12062011/article/categor ...

  5. 《数字图像处理》dlib人脸检测获取关键点,delaunay三角划分,实现人脸的几何变换warpping,接着实现两幅人脸图像之间的渐变合成morphing

    这学期在上<数字图像处理>这门课程,老师布置了几个大作业,自己和同学一起讨论完成后,感觉还挺有意思的,就想着把这个作业整理一下 : 目录 1.实验任务和要求 2.实验原理 3.实验代码 3 ...

  6. Java 图像处理教程(人脸检测,添加水印,图像颜色转换)

    Java 图像处理教程(人脸检测,添加水印,图像颜色转换) 文章目录 Java 图像处理教程(人脸检测,添加水印,图像颜色转换) 1:图片的读和写 2:彩色图像转换成灰度图像 3:彩色图像转换成负图像 ...

  7. 图像处理基本方法-c语言调用opencv实现人脸检测功能

    图像处理基本方法-c语言调用opencv-实现BMP图片中人脸检测功能 使用opencv检测bmp图片中人脸,主要使用cvHaarDetectObjects函数实现. 函数定义 CvSeq* cvHa ...

  8. Python图像处理,cv2模块,OpenCV实现人脸检测蔡徐坤

    前言 利用Python实现OpenCV实现人脸检测,废话不多说~ 让我们愉快地开始吧~ 开发工具 Python版本: 3.6.4 相关模块: cv2模块: 以及一些Python自带的模块. 环境搭建 ...

  9. 【MATLAB教程案例31】基于matlab的人脸检测相关算法的仿真与分析——肤色模型与形态学图像处理方法

    FPGA教程目录 MATLAB教程目录 目录 1.软件版本 2.人脸检测理论概述 3.人脸检测的matlab实现

最新文章

  1. LeetCode Reconstruct Original Digits from English
  2. mysql的SQL_NO_CACHE(在查询时不使用缓存)和sql_cache用法
  3. 字符串类型的数字比较大小_Python核心知识系列:数字与字符串类型
  4. Bootstrap快速浮动.pull-left 或 .pull-right 类
  5. win10 安装docker流程_Windows10下安装Docker的步骤图文教程
  6. 省钱有简单的祛痘方法 - 健康程序员,至尚生活!
  7. java设计模式----简单工厂
  8. 利用filebeat推送mysql慢查询日志
  9. 信息量、熵、相对熵与交叉熵的理解
  10. 数据库对象之存储过程
  11. ios touch坐标_iOS 3D Touch –窥视与流行
  12. Socket编程--TCP粘包问题
  13. windows 2008下载地址及版本介绍
  14. MAC 安装 kafka
  15. w ndows 10关机快捷键,windows关机快捷键winuu
  16. 181008 逆向-inctf(load3r、Decoy)
  17. CAD定数等分不显示等分点
  18. python语言迷宫游戏_一个Python迷宫小游戏
  19. Huggingface Transformers 安装报错 ImportError: /lib64/libc.so.6: version `GLIBC_2.18‘ not found
  20. uCLinux LINUX区别

热门文章

  1. SOLIDWORKS模版的建立
  2. 2021年京东双11将于10月20日开启预售 将上线4亿件新品
  3. django自带邮件模块实现用户注册激活邮件发送
  4. 滑动窗口算法基本原理
  5. java 接口和抽象类的区别6_Java抽象类与接口的区别
  6. 机械工程研究生转行计算机,机械类考研可以转什么专业?能不跨专业最好,跨专业定当考虑周全...
  7. 股票 WR威廉指标形态图解
  8. Permutation Feature Importance
  9. Django 管理工具(Admin)
  10. 性能跟踪工具--10046事件详解