同系列文章
源代码下载
源代码
MainWindow.xaml.cs
/* ---------------------------------------------------------- * 文件名称:MainWindow.xaml.cs * * 作者:秦建辉 * * 微信:splashcn * * 博客:http://www.firstsolver.com/wordpress/ * * 开发环境: * Visual Studio V2017 * .NET Framework 4 Client Profile * Baidu.AI 3.3.0.29135 * * 版本历史: * V1.0 2018年01月17日 * 百度AI 人脸检测演示示例 * * 参考资料: * http://ai.baidu.com/ * https://www.newtonsoft.com/json * http://blog.csdn.net/xingchenbingbuyu/article/details/78880931 ------------------------------------------------------------ */ using Baidu.Aip.Face; using Com.FirstSolver.Splash; using System.Collections.Generic; using System.IO; using System.Windows; using System.Windows.Media.Imaging; namespace FaceDetect { public partial class MainWindow : Window { /// <summary> /// 表情 /// </summary> public static readonly string[] FaceExpression = { "不笑", "微笑", "大笑" }; /// <summary> /// 眼镜 /// </summary> public static readonly string[] FaceGlasses = { "无眼镜", "普通眼镜", "墨镜" }; private Face Client; private Dictionary<string, object> options = new Dictionary<string, object>{ { "face_fields", "age,beauty,expression,faceshape,gender,glasses,landmark,race,qualities" } }; public MainWindow() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { string API_KEY = "你的 Api Key"; string SECRET_KEY = "你的 Secret Key"; Client = new Face(API_KEY, SECRET_KEY); } private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) { } private void ButtonSelectImage_Click(object sender, RoutedEventArgs e) { try { Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog { Filter = "Image|*.jpg;*.bmp;*.png;*.tif;*.tga;*.ras;*.jp2;*.j2k;*.jpe", DereferenceLinks = true }; this.CenterChild(); if (dlg.ShowDialog(Owner).Value == true) { using (FileStream fs = new FileStream(dlg.FileName, FileMode.Open, FileAccess.Read, FileShare.Read)) { byte[] source = new byte[fs.Length]; fs.Read(source, 0, (int)fs.Length); BitmapImage bi = new BitmapImage(); bi.BeginInit(); bi.StreamSource = new MemoryStream(source); bi.EndInit(); Image1.Source = bi; Image1.Tag = source; Reset(); } } } catch (System.Exception exception) { ShowExceptionMessage(exception); } } private void ButtonFaceDetect_Click(object sender, RoutedEventArgs e) { try { if (Image1.Source == null) return; var result = Client.Detect((byte[])Image1.Tag, options); var error_code = result["error_code"]; if (error_code != null) { MessageBoxPlus.Show(this, result["error_msg"].ToString(), "错误", MessageBoxButton.OK, MessageBoxImage.Warning); } else { foreach (dynamic item in result["result"]) { // 显示人脸属性 TextBlockAge.Text = System.Math.Floor((double)item["age"]).ToString(); TextBlockGender.Text = string.Equals(item["gender"].ToString(), "male") ? "男" : "女"; TextBlockExpression.Text = FaceExpression[(int)item["expression"]]; TextBlockBeauty.Text = System.Math.Ceiling((double)item["beauty"]).ToString(); TextBlockGlasses.Text = FaceGlasses[(int)item["glasses"]]; string type = string.Empty; double maxProbability = double.MinValue; foreach (dynamic shape in item["faceshape"]) { double probability = (double)shape["probability"]; if (probability > maxProbability) { maxProbability = probability; type = shape["type"].ToString(); } } TextBlockFaceShape.Text = type; TextBlockRace.Text = item["race"].ToString(); TextBlockIllumination.Text = item["qualities"]["illumination"].ToString(); // 显示人脸框及特征点 var location = item["location"]; System.Drawing.Rectangle region = new System.Drawing.Rectangle((int)location["left"], (int)location["top"], (int)location["width"], (int)location["height"]); using (MemoryStream ms = new MemoryStream((byte[])Image1.Tag)) { using (System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(ms)) { using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bmp)) { using (System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Color.Green, 3.0f)) { // 用矩形框标记人脸位置 g.DrawRectangle(pen, region); } // 标记4个关键点 using (System.Drawing.SolidBrush brush = new System.Drawing.SolidBrush(System.Drawing.Color.Red)) { foreach (dynamic point in item["landmark"]) { int x = point["x"]; int y = point["y"]; g.FillEllipse(brush, x - 2, y - 2, 5, 5); } } // 标记72个特征点 using (System.Drawing.SolidBrush brush = new System.Drawing.SolidBrush(System.Drawing.Color.Yellow)) { foreach (dynamic point in item["landmark72"]) { int x = point["x"]; int y = point["y"]; g.FillEllipse(brush, x - 1, y - 1, 3, 3); } } } Image2.Source = bmp.ToBitmapImage(); } } // 添加红帽子 AddHat("redhat.png", region, Image3); // 添加绿帽子 AddHat("greenhat.png", region, Image4); } } } catch (System.Exception exception) { ShowExceptionMessage(exception); } } // 添加帽子 private void AddHat(string filename, System.Drawing.Rectangle region, System.Windows.Controls.Image container) { try { if (Image1.Source == null) return; using (MemoryStream ms = new MemoryStream((byte[])Image1.Tag)) { using (System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(ms)) { using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bmp)) { using (System.Drawing.Bitmap hat = new System.Drawing.Bitmap(filename)) { // 根据人脸框大小调整帽子大小 int hatWidth = (int)System.Math.Round(region.Width * 1.5); int hatHeight = (int)System.Math.Round(region.Width * 1.5 * hat.Height / hat.Width); int x = region.X - (hatWidth - region.Width) / 2; int y = region.Y - hatHeight; g.DrawImage(hat, x, y, hatWidth, hatHeight); } } container.Source = bmp.ToBitmapImage(); } } } catch (System.Exception exception) { ShowExceptionMessage(exception); } } // 显示异常信息 public void ShowExceptionMessage(System.Exception exception) { string ErrorMessage = exception.Message; if (string.IsNullOrEmpty(ErrorMessage)) ErrorMessage = exception.InnerException.Message; MessageBoxPlus.Show(this, ErrorMessage, "异常", MessageBoxButton.OK, MessageBoxImage.Error); } private void Reset() { Image2.Source = null; Image3.Source = null; Image4.Source = null; foreach (UIElement item in GridFaceAttribute.Children) { if (item is System.Windows.Controls.TextBlock) { (item as System.Windows.Controls.TextBlock).Text = string.Empty; } } } } }
MainWindow.xaml
<Window x:Class="FaceDetect.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="百度AI 人脸检测演示示例" WindowStartupLocation="CenterScreen" FontSize="16" Icon="FR.ico" WindowState="Maximized" Loaded="Window_Loaded" Closing="Window_Closing"> <ScrollViewer> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition/> <RowDefinition Height="Auto"/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <Button Grid.Row="0" Grid.Column="0" Margin="4" Padding="8" Content="选择人脸图像…" HorizontalAlignment="Center" Name="ButtonSelectImage" Click="ButtonSelectImage_Click"/> <Button Grid.Row="0" Grid.Column="1" Margin="4" Padding="8" Content="人脸检测" HorizontalAlignment="Center" Name="ButtonFaceDetect" Click="ButtonFaceDetect_Click"/> <Label Grid.Row="0" Grid.Column="2" Margin="4" Padding="8" Content="人脸属性" HorizontalAlignment="Center"/> <Border Grid.Row="1" Grid.Column="0" Margin="4" BorderThickness="1" BorderBrush="LightGray"> <Image Margin="4" Name="Image1"/> </Border> <Border Grid.Row="1" Grid.Column="1" Margin="4" BorderThickness="1" BorderBrush="LightGray"> <Image Margin="4" Name="Image2"/> </Border> <Grid Grid.Row="1" Grid.Column="2" Margin="4" Name="GridFaceAttribute"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <Label Grid.Row="0" Grid.Column="0" Margin="4" VerticalAlignment="Center" Content="年龄"/> <Label Grid.Row="1" Grid.Column="0" Margin="4" VerticalAlignment="Center" Content="性别"/> <Label Grid.Row="2" Grid.Column="0" Margin="4" VerticalAlignment="Center" Content="表情"/> <Label Grid.Row="3" Grid.Column="0" Margin="4" VerticalAlignment="Center" Content="美丑"/> <TextBlock Grid.Row="0" Grid.Column="1" Margin="4" Width="100" VerticalAlignment="Center" Name="TextBlockAge" Foreground="Blue"/> <TextBlock Grid.Row="1" Grid.Column="1" Margin="4" Width="100" VerticalAlignment="Center" Name="TextBlockGender" Foreground="Blue"/> <TextBlock Grid.Row="2" Grid.Column="1" Margin="4" Width="100" VerticalAlignment="Center" Name="TextBlockExpression" Foreground="Blue"/> <TextBlock Grid.Row="3" Grid.Column="1" Margin="4" Width="100" VerticalAlignment="Center" Name="TextBlockBeauty" Foreground="Blue"/> <Label Grid.Row="0" Grid.Column="2" Margin="4" VerticalAlignment="Center" Content="眼镜"/> <Label Grid.Row="1" Grid.Column="2" Margin="4" VerticalAlignment="Center" Content="脸型"/> <Label Grid.Row="2" Grid.Column="2" Margin="4" VerticalAlignment="Center" Content="种族"/> <Label Grid.Row="3" Grid.Column="2" Margin="4" VerticalAlignment="Center" Content="光照"/> <TextBlock Grid.Row="0" Grid.Column="3" Margin="4" Width="100" VerticalAlignment="Center" Name="TextBlockGlasses" TextWrapping="Wrap" Foreground="Blue"/> <TextBlock Grid.Row="1" Grid.Column="3" Margin="4" Width="100" VerticalAlignment="Center" Name="TextBlockFaceShape" TextWrapping="Wrap" Foreground="Blue"/> <TextBlock Grid.Row="2" Grid.Column="3" Margin="4" Width="100" VerticalAlignment="Center" Name="TextBlockRace" TextWrapping="Wrap" Foreground="Blue"/> <TextBlock Grid.Row="3" Grid.Column="3" Margin="4" Width="100" VerticalAlignment="Center" Name="TextBlockIllumination" TextWrapping="Wrap" Foreground="Blue"/> </Grid> <Label Grid.Row="2" Grid.Column="0" Margin="4" Padding="8" Content="圣诞帽" HorizontalAlignment="Center"/> <Label Grid.Row="2" Grid.Column="1" Margin="4" Padding="8" Content="原谅帽" HorizontalAlignment="Center"/> <Border Grid.Row="3" Grid.Column="0" Margin="4" BorderThickness="1" BorderBrush="LightGray"> <Image Margin="4" Name="Image3"/> </Border> <Border Grid.Row="3" Grid.Column="1" Margin="4" BorderThickness="1" BorderBrush="LightGray"> <Image Margin="4" Name="Image4"/> </Border> </Grid> </ScrollViewer> </Window>