Microsoft Azure和WPF实现人脸检测

Microsoft Azure和WPF实现人脸检测,第1张

在本文中,详解如何使用Microsoft Azure和WPF技术的帮助下使用实现人脸API应用程序。该应用程序检测人脸图像,显示每张脸周围的红框,以及通过将光标移动到框来显示每张脸的描述的状态栏。

先决条件

  • 在 Azure 门户中创建人脸 API。
  • 在 WPF 应用程序中访问和管理人脸 API 密钥。
  • 在 Visual Studio 2019 中使用人脸 API 创建 WPF 应用程序。

按照步骤在 Azure 门户上创建人脸 API。

第1步

登录 Azure网站。

Step 2

按“+新建”,选择“AI+认知服务”,选择“人脸API”。

第 3 步

在“创建人脸 API”边栏选项卡中,输入您的API名称,选择所需的订阅,然后为API选择所需的位置。选择我们使用所需的适当定价层。为API创建资源组。然后,按“创建”。

复制端点并按“显示/管理密钥”以显示我们在WPF应用程序中使用的密钥。

第4步

“管理密钥”刀片显示将用作我们的人脸API访问密钥的密钥。单击“复制”按钮,然后将其粘贴到记事本中。

使用 C#在Visual Studio中实现人脸API

第 5 步

按照步骤使用 Visual Studio 2019创建基于Windows 的 WPF应用程序。

打开Visual Studio 2019。

  • 从菜单栏中,单击文件>>新建>>新建项目。
  • 在Visual Studio中,选择已安装-->模板-->Visual C#-->Windows经典桌面-->WPF应用程序(.NET 应用程序)。
  • 为我们的应用程序输入名称为FaceApiDemo,然后按 OK 在解决方案资源管理器中打开它。

第 6 步

我们需要将两个包添加到我们的WPF应用程序中。右键单击解决方案资源管理器并按“NuGet 包管理器”添加两个包。

Newtonsoft.json是适用于.NET应用程序的流行JSON框架的框架。我们将使用它,因为我们的 Face API包含大量JSON文件来存储有关图像的各种详细信息。

在 NuGet 包中,浏览 Newtonsoft.json,然后按“安装”。

此外,浏览Microsoft.ProjectOxford.Face并按“安装” 。该包用于通过HTTPS请求配置人脸 API 和我们的应用程序。因此,它导入了一个封装 Face API REST 请求的 .NET 库。

第 7 步

将以下代码复制并粘贴到MainWindow.Xaml。这是我们的Windows应用程序的布局代码。

  
      
          
          
            

步骤8

打开MainWindow.xaml.cs,用下面的代码替换代码。

using System;  
using System.Collections.Generic;  
using System.IO;  
using System.Text;  
using System.Threading.Tasks;  
using System.Windows;  
using System.Windows.Input;  
using System.Windows.Media;  
using System.Windows.Media.Imaging;  
using Microsoft.ProjectOxford.Common.Contract;  
using Microsoft.ProjectOxford.Face;  
using Microsoft.ProjectOxford.Face.Contract;  
  
namespace FaceApiDemo  
  
{  
    public partial class MainWindow : Window  
    {  
        // Replace the first parameter with your valid subscription key.  
        //  
        // Replace or verify the region in the second parameter.  
        //  
        // You must use the same region in your REST API call as you used to obtain your subscription keys.  
        // For example, if you obtained your subscription keys from the westus region, replace  
        // "westcentralus" in the URI below with "westus".  
        //  
        // NOTE: Free trial subscription keys are generated in the westcentralus region, so if you are using  
        // a free trial subscription key, you should not need to change this region.  
        private readonly IFaceServiceClient faceServiceClient =  
            new FaceServiceClient("keys", "Endpoints");  
  
        Face[] faces;                   // The list of detected faces.  
        String[] faceDescriptions;      // The list of descriptions for the detected faces.  
        double resizeFactor;            // The resize factor for the displayed image.  
        //private object faceDescriptionStatusBar;  
  
        public MainWindow()  
        {  
            InitializeComponent();  
        }  
  
        // Displays the image and calls Detect Faces.  
  
        private async void BrowseButton_Click(object sender, RoutedEventArgs e)  
        {  
            // Get the image file to scan from the user.  
            var openDlg = new Microsoft.Win32.OpenFileDialog();  
  
            openDlg.Filter = "JPEG Image(*.jpg)|*.jpg";  
            bool? result = openDlg.ShowDialog(this);  
  
            // Return if canceled.  
            if (!(bool)result)  
            {  
                return;  
            }  
  
            // Display the image file.  
            string filePath = openDlg.FileName;  
  
            Uri fileUri = new Uri(filePath);  
            BitmapImage bitmapSource = new BitmapImage();  
  
            bitmapSource.BeginInit();  
            bitmapSource.CacheOption = BitmapCacheOption.None;  
            bitmapSource.UriSource = fileUri;  
            bitmapSource.EndInit();  
  
            FacePhoto.Source = bitmapSource;  
  
            // Detect any faces in the image.  
            Title = "Detecting...";  
            faces = await UploadAndDetectFaces(filePath);  
            Title = String.Format("Detection Finished. {0} face(s) detected", faces.Length);  
  
            if (faces.Length > 0)  
            {  
                // Prepare to draw rectangles around the faces.  
                DrawingVisual visual = new DrawingVisual();  
                DrawingContext drawingContext = visual.RenderOpen();  
                drawingContext.DrawImage(bitmapSource,  
                    new Rect(0, 0, bitmapSource.Width, bitmapSource.Height));  
                double dpi = bitmapSource.DpiX;  
                resizeFactor = 96 / dpi;  
                faceDescriptions = new String[faces.Length];  
  
                for (int i = 0; i < faces.Length; ++i)  
                {  
                    Face face = faces[i];  
  
                    // Draw a rectangle on the face.  
                    drawingContext.DrawRectangle(  
                        Brushes.Transparent,  
                        new Pen(Brushes.Red, 2),  
                        new Rect(  
                            face.FaceRectangle.Left * resizeFactor,  
                            face.FaceRectangle.Top * resizeFactor,  
                            face.FaceRectangle.Width * resizeFactor,  
                            face.FaceRectangle.Height * resizeFactor  
                            )  
                    );  
  
                    // Store the face description.  
                    faceDescriptions[i] = FaceDescription(face);  
                }  
  
                drawingContext.Close();  
  
                // Display the image with the rectangle around the face.  
                RenderTargetBitmap faceWithRectBitmap = new RenderTargetBitmap(  
                    (int)(bitmapSource.PixelWidth * resizeFactor),  
                    (int)(bitmapSource.PixelHeight * resizeFactor),  
                    96,  
                    96,  
                    PixelFormats.Pbgra32);  
  
                faceWithRectBitmap.Render(visual);  
                FacePhoto.Source = faceWithRectBitmap;  
  
                // Set the status bar text.  
                faceDescriptionStatusBar.Text = "Place the mouse pointer over a face to see the face description.";  
            }  
        }  
  
        // Displays the face description when the mouse is over a face rectangle.  
  
        private void FacePhoto_MouseMove(object sender, MouseEventArgs e)  
        {  
            // If the REST call has not completed, return from this method.  
            if (faces == null)  
                return;  
  
            // Find the mouse position relative to the image.  
            Point mouseXY = e.GetPosition(FacePhoto);  
  
            ImageSource imageSource = FacePhoto.Source;  
            BitmapSource bitmapSource = (BitmapSource)imageSource;  
  
            // Scale adjustment between the actual size and displayed size.  
            var scale = FacePhoto.ActualWidth / (bitmapSource.PixelWidth / resizeFactor);  
  
            // Check if this mouse position is over a face rectangle.  
            bool mouseOverFace = false;  
  
            for (int i = 0; i < faces.Length; ++i)  
            {  
                FaceRectangle fr = faces[i].FaceRectangle;  
                double left = fr.Left * scale;  
                double top = fr.Top * scale;  
                double width = fr.Width * scale;  
                double height = fr.Height * scale;  
  
                // Display the face description for this face if the mouse is over this face rectangle.  
                if (mouseXY.X >= left && mouseXY.X <= left + width && mouseXY.Y >= top && mouseXY.Y <= top + height)  
                {  
                    faceDescriptionStatusBar.Text = faceDescriptions[i];  
                    mouseOverFace = true;  
                    break;  
                }  
            }  
  
            // If the mouse is not over a face rectangle.  
            if (!mouseOverFace)  
                faceDescriptionStatusBar.Text = "Place the mouse pointer over a face to see the face description.";  
        }  
  
        // Uploads the image file and calls Detect Faces.  
  
        private async Task UploadAndDetectFaces(string imageFilePath)  
        {  
            // The list of Face attributes to return.  
            IEnumerable faceAttributes =  
                new FaceAttributeType[] { FaceAttributeType.Gender, FaceAttributeType.Age, FaceAttributeType.Smile, FaceAttributeType.Emotion, FaceAttributeType.Glasses, FaceAttributeType.Hair };  
  
            // Call the Face API.  
            try  
            {  
                using (Stream imageFileStream = File.OpenRead(imageFilePath))  
                {  
                    Face[] faces = await faceServiceClient.DetectAsync(imageFileStream, returnFaceId: true, returnFaceLandmarks: false, returnFaceAttributes: faceAttributes);  
                    return faces;  
                }  
            }  
            // Catch and display Face API errors.  
            catch (FaceAPIException f)  
            {  
                MessageBox.Show(f.ErrorMessage, f.ErrorCode);  
                return new Face[0];  
            }  
            // Catch and display all other errors.  
            catch (Exception e)  
            {  
                MessageBox.Show(e.Message, "Error");  
                return new Face[0];  
            }  
        }  
  
        // Returns a string that describes the given face.  
  
        private string FaceDescription(Face face)  
        {  
            StringBuilder sb = new StringBuilder();  
  
            sb.Append("Face: ");  
  
            // Add the gender, age, and smile.  
            sb.Append(face.FaceAttributes.Gender);  
            sb.Append(", ");  
            sb.Append(face.FaceAttributes.Age);  
            sb.Append(", ");  
            sb.Append(String.Format("smile {0:F1}%, ", face.FaceAttributes.Smile * 100));  
  
            // Add the emotions. Display all emotions over 10%.  
            sb.Append("Emotion: ");  
            EmotionScores emotionScores = face.FaceAttributes.Emotion;  
            if (emotionScores.Anger >= 0.1f) sb.Append(String.Format("anger {0:F1}%, ", emotionScores.Anger * 100));  
            if (emotionScores.Contempt >= 0.1f) sb.Append(String.Format("contempt {0:F1}%, ", emotionScores.Contempt * 100));  
            if (emotionScores.Disgust >= 0.1f) sb.Append(String.Format("disgust {0:F1}%, ", emotionScores.Disgust * 100));  
            if (emotionScores.Fear >= 0.1f) sb.Append(String.Format("fear {0:F1}%, ", emotionScores.Fear * 100));  
            if (emotionScores.Happiness >= 0.1f) sb.Append(String.Format("happiness {0:F1}%, ", emotionScores.Happiness * 100));  
            if (emotionScores.Neutral >= 0.1f) sb.Append(String.Format("neutral {0:F1}%, ", emotionScores.Neutral * 100));  
            if (emotionScores.Sadness >= 0.1f) sb.Append(String.Format("sadness {0:F1}%, ", emotionScores.Sadness * 100));  
            if (emotionScores.Surprise >= 0.1f) sb.Append(String.Format("surprise {0:F1}%, ", emotionScores.Surprise * 100));  
  
            // Add glasses.  
            sb.Append(face.FaceAttributes.Glasses);  
            sb.Append(", ");  
  
            // Add hair.  
            sb.Append("Hair: ");  
  
            // Display baldness confidence if over 1%.  
            if (face.FaceAttributes.Hair.Bald >= 0.01f)  
                sb.Append(String.Format("bald {0:F1}% ", face.FaceAttributes.Hair.Bald * 100));  
  
            // Display all hair color attributes over 10%.  
            HairColor[] hairColors = face.FaceAttributes.Hair.HairColor;  
            foreach (HairColor hairColor in hairColors)  
            {  
                if (hairColor.Confidence >= 0.1f)  
                {  
                    sb.Append(hairColor.Color.ToString());  
                    sb.Append(String.Format(" {0:F1}% ", hairColor.Confidence * 100));  
                }  
            }  
  
            // Return the built string.  
            return sb.ToString();  
        }  
    }  
}  

在代码的第30行,输入我们从Azure Face API获取的密钥和端点 URL。

private readonly IFaceServiceClient faceServiceClient =  
        new FaceServiceClient("_key_", "End-point URL");  

在 Azure 门户上使用人脸API替换密钥和端点。

步骤 9

保存并启动程序。然后,单击“浏览”按钮导入图像以检测人脸。

第 10 步

等待几秒钟。云API想要响应我们的图像,以使用图像中人脸周围的红色框来检测人脸。将光标移到面部矩形上,该图像的描述会显示在状态栏中。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/716694.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-25
下一篇 2022-04-25

发表评论

登录后才能评论

评论列表(0条)

保存