百度AI(4)人脸识别の人脸检测(C#)

同系列文章

源代码下载

BaiduAI.zip

演示程序界面

源代码
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>

Comments are closed.