Thử nghiệm Emotion API trong Microsoft Cognitive

Các bạn thân mến, nắm bắt được tâm lý thông qua nhận biết độ hài lòng của khách hàng luôn là một trong những yếu tố tiên quyết để phục vụ cho việc kinh doanh. Hôm nay tôi sẽ làm một demo đơn giản với Emotion Api trong bộ Cognitive để có thể giúp các bạn phần nào. Ok, let’s start.

Demo ở đây sẽ là 1 app .Net đơn giản bạn có thể input hình ảnh của khách hàng và tôi sẽ đưa ra các chỉ số về độ vui vẻ, tức giận, … của những người trong bức ảnh.

Bước 1: Tạo solution sử dụng WPF Application

emotion_api

Bước 2: Mở NuGet Package Manager để install 2 packages: Newtonsoft.JsonMicrosoft.ProjectOxford.Emotion

emotion_api_02Package Newtonsoft.Json

emotion_api_03Package Microsoft.ProjectOxford.Emotion

Bước 3: Mở file MainWindow.xaml thêm đoạn code bên dưới để vẽ 1 form đơn giản cho việc chọn file ảnh và hiển thị:

<Window x:Class="Azure.DemoEmotion.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Azure.DemoEmotion" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Image x:Name="ImgPhoto" Stretch="Uniform" Margin="0,0,0,30"/>
        <Button x:Name="BtnBrowse" Margin="20,5" Height="20" VerticalAlignment="Bottom" Content="Browse..." Click="BtnBrowse_Click"/>
    </Grid>
</Window>

Bước 4: Bây giờ mở file MainWindow.xaml.cs để bắt đầu làm phần việc chính:

Khai báo để sử dụng 2 classes như bên dưới:

using Microsoft.ProjectOxford.Emotion;
using Microsoft.ProjectOxford.Emotion.Contract;

Khởi tạo object của Client trong MainWindow class:

private readonly EmotionServiceClient emotionServiceClient = new EmotionServiceClient("điền Emotion key vào đây");

Bây giờ chúng ta viết hàm để upload file và gọi API:

private async Task<Emotion[]> UploadAndDetectEmotions(string imageFilePath)
        	{
            try
            {
                using (Stream imageFileStream = File.OpenRead(imageFilePath))
                {
                    var emotionResult = await emotionServiceClient.RecognizeAsync(imageFileStream);
                    return emotionResult;
                }
            }
            catch (Exception)
            {
                return null;
            }
        	}

Tiếp theo chúng ta viết event cho button Browse để user chọn ảnh:

private async void BtnBrowse_Click(object sender, RoutedEventArgs e)
        	{
            var openDlg = new Microsoft.Win32.OpenFileDialog
            {
                Filter = "JPEG Image(*.jpg)|*.jpg"
            };

            var result = openDlg.ShowDialog(this);
            if (!result.Value)
                return;

            var filePath = openDlg.FileName;
            var fileUri = new Uri(filePath);

            var bitmapSource = new BitmapImage();
            bitmapSource.BeginInit();
            bitmapSource.CacheOption = BitmapCacheOption.None;
            bitmapSource.UriSource = fileUri;
            bitmapSource.EndInit();

            ImgPhoto.Source = bitmapSource;//View original image
}

Vậy là chúng ta đã có ảnh, việc tiếp theo là gọi hàm bên trên và chờ kết quả trả về thôi 😀

Emotion[] emotionResult = await UploadAndDetectEmotions(filePath);

Tada, kết quả đê:
Với mỗi khuôn mặt API nhận ra được sẽ có: thứ nhất là vị trí của khuôn mặt trong ảnh:

emotion_api_04
Thứ 2 là chi tiết trọng số điểm các trạng thái của khuôn mặt đó, có 8 tiêu chí đánh giá như bên dưới:

emotion_api_05

Theo kết quả bên trên, ta biết rằng người trong ảnh đang ở trạng thái rất vui vì điểm Happiness là 0.94 😀 cao nhất sẽ là 1.00 nhé.

Tùy theo mục đích sử dụng của từng người để xử lý kết quả nhận được. Trong ví dụ này, tôi sẽ khoanh vùng khuôn mặt và hiển thị 3 trạng thái có điểm cao nhất ra màn hình như bên dưới:
Đây là toàn bộ event Browse của tôi:

private async void BtnBrowse_Click(object sender, RoutedEventArgs e)
        {
            var openDlg = new Microsoft.Win32.OpenFileDialog
            {
                Filter = "JPEG Image(*.jpg)|*.jpg"
            };

            var result = openDlg.ShowDialog(this);
            if (!result.Value)
                return;

            var filePath = openDlg.FileName;
            var fileUri = new Uri(filePath);

            var bitmapSource = new BitmapImage();
            bitmapSource.BeginInit();
            bitmapSource.CacheOption = BitmapCacheOption.None;
            bitmapSource.UriSource = fileUri;
            bitmapSource.EndInit();

            ImgPhoto.Source = bitmapSource;//View original image

            Title = "Detecting...";
            Emotion[] emotionResult = await UploadAndDetectEmotions(filePath);

            Title = "Detection Done";

            if (emotionResult != null && emotionResult.Length > 0)
            {
                DrawingVisual visual = new DrawingVisual();
                DrawingContext drawingContext = visual.RenderOpen();
                drawingContext.DrawImage(bitmapSource,
                    new Rect(0, 0, bitmapSource.Width, bitmapSource.Height));
                double dpi = bitmapSource.DpiX;
                double resizeFactor = 96 / dpi;

                foreach (var emotion in emotionResult)
                {
                    drawingContext.DrawRectangle(
                        Brushes.Transparent,
                        new Pen(Brushes.Red, 2),
                        new Rect(
                            emotion.FaceRectangle.Left * resizeFactor,
                            emotion.FaceRectangle.Top * resizeFactor,
                            emotion.FaceRectangle.Width * resizeFactor,
                            emotion.FaceRectangle.Height * resizeFactor
                            )
                    );
                    var listEmotion = emotion.Scores.ToRankedList().OrderByDescending(i => i.Value.ToString("0.000")).ToList();

                    for (int i = 0; i < 3; i++)
                    {
                        drawingContext.DrawText(
                       new FormattedText(listEmotion[i].Key + ": " + listEmotion[i].Value.ToString("0.00000"),
                            CultureInfo.GetCultureInfo("en-us"),
                              FlowDirection.LeftToRight,
                              new Typeface("Verdana"),
                              24 * resizeFactor, Brushes.Red),
                              new Point(emotion.FaceRectangle.Left * resizeFactor + emotion.FaceRectangle.Width * resizeFactor, 
                              emotion.FaceRectangle.Top * resizeFactor + 30 * i));
                    }
                }

                drawingContext.Close();
                var faceWithRectBitmap = new RenderTargetBitmap(
                    (int)(bitmapSource.PixelWidth * resizeFactor),
                    (int)(bitmapSource.PixelHeight * resizeFactor),
                    96,
                    96,
                    PixelFormats.Pbgra32);

                faceWithRectBitmap.Render(visual);
                ImgPhoto.Source = faceWithRectBitmap;
            }
}

Cuối cùng chỉ việc build và chạy thử thành quả thôi ^^

emotion_api_06

Trần Hoàng Giang

Anh Trần Hoàng Giang là chuyên gia với hơn 6 năm kinh nghiệm trong lĩnh vực Mobility. Anh Giang từng là kiến trúc sư giải pháp cho các giải pháp Mobility cho tổ chức chính phủ tại Singapore, đặc biệt cho 1 trong những hãng chế tạo máy bay lớn nhất thế giới. Anh Giang hiện đang công tác tại FPT Software, chịu trách nhiệm chính trong việc tư vấn về cái giải pháp Enterprise Mobility. Đến với AzureVN.NET, anh Giang mong muốn được chia sẻ về Microsoft Azure Mobility, Cognitive Service

giangth has 9 posts and counting.See all posts by giangth

Trả lời

Thư điện tử của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *