Azure Media Analytics での顔と感情の検出Detect Face and Emotion with Azure Media Analytics

概要Overview

Azure Media Face Detector メディア プロセッサ (MP) を使用すると、対象ユーザーを数えたり、動きを追跡したり、表情によって対象ユーザーの参加や反応を測定することさえできます。The Azure Media Face Detector media processor (MP) enables you to count, track movements, and even gauge audience participation and reaction via facial expressions. このサービスには 2 つの機能があります。This service contains two features:

  • 顔検出Face detection

    顔検出は、ビデオの中で人の顔を検出して追跡します。Face detection finds and tracks human faces within a video. 複数の顔を検出した後、画面内の移動を追跡でき、時間と位置のメタデータが JSON ファイルで返されます。Multiple faces can be detected and subsequently be tracked as they move around, with the time and location metadata returned in a JSON file. 追跡中、この機能は画面内を移動する同じ人の顔には同じ ID をできる限り設定し、顔が遮られたり一瞬フレームの外に出たりしても維持されます。During tracking, it will attempt to give a consistent ID to the same face while the person is moving around on screen, even if they are obstructed or briefly leave the frame.

    注意

    このサービスでは、顔認識は実行されません。This service does not perform facial recognition. 顔が遮られたりフレームから外れる時間が長すぎると、戻ったときには新しい ID が設定されます。An individual who leaves the frame or becomes obstructed for too long will be given a new ID when they return.

  • 感情検出Emotion detection

    感情検出は Face Detection メディア プロセッサのオプションのコンポーネントであり、喜び、悲しみ、恐怖、怒りなど、検出された顔から複数の感情的属性の分析を返します。Emotion Detection is an optional component of the Face Detection Media Processor that returns analysis on multiple emotional attributes from the faces detected, including happiness, sadness, fear, anger, and more.

Azure Media Face Detector MP は現在プレビュー段階です。The Azure Media Face Detector MP is currently in Preview.

ここでは、 Azure Media Face Detector の詳細を説明し、Media Services SDK for .NET でのその使用方法を示します。This topic gives details about Azure Media Face Detector and shows how to use it with Media Services SDK for .NET.

Face Detector の入力ファイルFace Detector input files

ビデオ ファイルです。Video files. 現在サポートされている形式は MP4、MOV、WMV です。Currently, the following formats are supported: MP4, MOV, and WMV.

Face Detector の出力ファイルFace Detector output files

顔検出および追跡 API は、高精度の顔位置検出と追跡を行い、ビデオ内で最大 64 個の人の顔を検出できます。The face detection and tracking API provides high precision face location detection and tracking that can detect up to 64 human faces in a video. 顔が正面を向いているときに最善の結果が得られ、横顔や小さい顔 (24 x 24 ピクセル以下) のときは精度が低下することがあります。Frontal faces provide the best results, while side faces and small faces (less than or equal to 24x24 pixels) might not be as accurate.

検出されて追跡される顔に対しては、画像内での顔の位置を示す座標 (左端、上端、幅、高さ、ピクセル単位) と、追跡対象の個人を識別する顔 ID 番号が返されます。The detected and tracked faces are returned with coordinates (left, top, width, and height) indicating the location of faces in the image in pixels, as well as a face ID number indicating the tracking of that individual. 顔 ID 番号は、前向きの顔が失われたりフレーム内で重なったりするとリセットされる場合があり、同じ顔に複数の ID が割り当てられる可能性があります。Face ID numbers are prone to reset under circumstances when the frontal face is lost or overlapped in the frame, resulting in some individuals getting assigned multiple IDs.

出力 JSON ファイルの要素Elements of the output JSON file

このジョブでは、検出および追跡された顔に関するメタデータを含む JSON 出力ファイルを生成します。The job produces a JSON output file that contains metadata about detected and tracked faces. そのメタデータには、画像内での顔の位置を示す座標と、追跡対象の個人を識別する顔 ID 番号が含まれます。The metadata includes coordinates indicating the location of faces, as well as a face ID number indicating the tracking of that individual. 顔 ID 番号は、前向きの顔が失われたりフレーム内で重なったりするとリセットされる場合があり、同じ顔に複数の ID が割り当てられる可能性があります。Face ID numbers are prone to reset under circumstances when the frontal face is lost or overlapped in the frame, resulting in some individuals getting assigned multiple IDs.

出力 JSON には、次の属性が含まれています。The output JSON includes the following attributes:

要素Element DescriptionDescription
versionversion Video API のバージョンを示します。This refers to the version of the Video API.
Indexindex (Azure Media Redactor にのみ適用されます) 現在のイベントのフレーム インデックスを定義します。(Applies to Azure Media Redactor only) defines the frame index of the current event.
timescaletimescale ビデオの 1 秒あたりの "ティック数" です。"Ticks" per second of the video.
offsetoffset タイムスタンプの時間オフセットです。This is the time offset for timestamps. Video API のバージョン 1.0 では、これは常に 0 になります。In version 1.0 of Video APIs, this will always be 0. 今後サポートされるシナリオでは、変更される可能性があります。In future scenarios we support, this value may change.
framerateframerate ビデオの 1 秒あたりのフレーム数です。Frames per second of the video.
fragmentsfragments メタデータは、フラグメントと呼ばれる複数のセグメントに分割されます。The metadata is chunked up into different segments called fragments. 各フラグメントには、開始、継続時間、間隔数、およびイベントが含まれます。Each fragment contains a start, duration, interval number, and event(s).
startstart 最初のイベントの開始時間です ("ティック数")。The start time of the first event in ‘ticks’.
durationduration フラグメントの長さです ("ティック数")。The length of the fragment, in “ticks”.
intervalinterval フラグメント内の各イベント エントリの間隔です ("ティック数")。The interval of each event entry within the fragment, in “ticks”.
eventsevents 各イベントには、その期間内で検出および追跡された顔が含まれます。Each event contains the faces detected and tracked within that time duration. これは、イベントの配列の配列です。It is an array of array of events. 外側の配列は、1 つの時間間隔を表します。The outer array represents one interval of time. 内側の配列は、その時点で発生した 0 個以上のイベントで構成されます。The inner array consists of 0 or more events that happened at that point in time. 空のかっこ [] は、顔が検出されなかったことを意味します。An empty bracket [] means no faces were detected.
idid 追跡されている顔の ID です。The ID of the face that is being tracked. この番号は、顔が検出されなくなると変化する可能性があります。This number may inadvertently change if a face becomes undetected. 特定の個人にはビデオ全体を通して同じ ID が割り当てられるべきですが、検出アルゴリズム (遮蔽など) の制限により保証できません。A given individual should have the same ID throughout the overall video, but this cannot be guaranteed due to limitations in the detection algorithm (occlusion, etc.)
x、yx, y 0.0 ~ 1.0 の範囲で正規化された、顔の境界ボックスの左上の X および Y 座標です。The upper left X and Y coordinates of the face bounding box in a normalized scale of 0.0 to 1.0.
X および Y 座標は常に横長の配置が基準になるので、縦長のビデオ (または、iOS では上下反転) の場合は、適切に変換する必要があります。-X and Y coordinates are relative to landscape always, so if you have a portrait video (or upside-down, in the case of iOS), you'll have to transpose the coordinates accordingly.
width、heightwidth, height 0.0 ~ 1.0 の範囲で正規化された、顔の境界ボックスの幅と高さです。The width and height of the face bounding box in a normalized scale of 0.0 to 1.0.
facesDetectedfacesDetected JSON の結果の最後にあり、ビデオ内でアルゴリズムが検出した顔の数がまとめられています。This is found at the end of the JSON results and summarizes the number of faces that the algorithm detected during the video. 顔が検出されなくなった場合 (顔が画面から外れる、横を向く、など)、ID が誤ってリセットされることがあるため、この値はビデオ内の顔の正確な数と常に一致しているとは限りません。Because the IDs can be reset inadvertently if a face becomes undetected (e.g. face goes off screen, looks away), this number may not always equal the true number of faces in the video.

Face Detector は、フラグメント化 (メタデータを時間に基づいて分割し、必要なものだけをダウンロードできます) およびセグメント化 (イベントが大きくなりすぎた場合に分割されます) の技法を使用します。Face Detector uses techniques of fragmentation (where the metadata can be broken up in time-based chunks and you can download only what you need), and segmentation (where the events are broken up in case they get too large). 簡単な計算でデータを変換できます。Some simple calculations can help you transform the data. たとえば、イベントが 6300 (ティック) に開始し、タイムスケールが 2997 (ティック/秒)、フレームレートが 29.97 (フレーム/秒) である場合、次のようになります。For example, if an event started at 6300 (ticks), with a timescale of 2997 (ticks/sec) and framerate of 29.97 (frames/sec), then:

  • 開始/タイムスケール = 2.1 秒Start/Timescale = 2.1 seconds
  • 秒 x フレームレート = 63 フレームSeconds x Framerate = 63 frames

顔検出の入力と出力の例Face detection input and output example

入力ビデオInput video

入力ビデオInput Video

タスクの構成 (プリセット)Task configuration (preset)

Azure Media Face Detectorでタスクを作成するときは、構成プリセットを指定する必要があります。When creating a task with Azure Media Face Detector, you must specify a configuration preset. 次の構成プリセットは、顔検出用だけです。The following configuration preset is just for face detection.

{
  "version":"1.0",
  "options":{
      "TrackingMode": "Fast"
  }
}

属性の説明Attribute descriptions

属性名Attribute name DescriptionDescription
ModeMode Fast: 処理速度は速くなりますが、精度が低下します (既定値)。Fast - fast processing speed, but less accurate (default).

JSON 出力JSON output

次の JSON 出力例は途中までです。The following example of JSON output was truncated.

{
"version": 1,
"timescale": 30000,
"offset": 0,
"framerate": 29.97,
"width": 1280,
"height": 720,
"fragments": [
    {
    "start": 0,
    "duration": 60060
    },
    {
    "start": 60060,
    "duration": 60060,
    "interval": 1001,
    "events": [
        [
        {
            "id": 0,
            "x": 0.519531,
            "y": 0.180556,
            "width": 0.0867188,
            "height": 0.154167
        }
        ],
        [
        {
            "id": 0,
            "x": 0.517969,
            "y": 0.181944,
            "width": 0.0867188,
            "height": 0.154167
        }
        ],
        [
        {
            "id": 0,
            "x": 0.517187,
            "y": 0.183333,
            "width": 0.0851562,
            "height": 0.151389
        }
        ],

    . . . 

感情検出の入力と出力の例Emotion detection input and output example

入力ビデオInput video

入力ビデオInput Video

タスクの構成 (プリセット)Task configuration (preset)

Azure Media Face Detectorでタスクを作成するときは、構成プリセットを指定する必要があります。When creating a task with Azure Media Face Detector, you must specify a configuration preset. 次の構成プリセットでは、感情検出に基づく JSON の作成を指定しています。The following configuration preset specifies to create JSON based on the emotion detection.

{
  "version": "1.0",
  "options": {
    "aggregateEmotionWindowMs": "987",
    "mode": "aggregateEmotion",
    "aggregateEmotionIntervalMs": "342"
  }
}

属性の説明Attribute descriptions

属性名Attribute name DescriptionDescription
ModeMode Faces: 顔検出のみ。Faces: Only face detection.
PerFaceEmotion: 検出された顔ごとに、感情を個別に返します。PerFaceEmotion: Return emotion independently for each face detection.
AggregateEmotion: フレーム内のすべての顔の平均的感情値を返します。AggregateEmotion: Return average emotion values for all faces in frame.
AggregateEmotionWindowMsAggregateEmotionWindowMs AggregateEmotion モードが選択されている場合に使用します。Use if AggregateEmotion mode selected. 各集計結果を生成するために使用するビデオの長さを指定します (ミリ秒単位)。Specifies the length of video used to produce each aggregate result, in milliseconds.
AggregateEmotionIntervalMsAggregateEmotionIntervalMs AggregateEmotion モードが選択されている場合に使用します。Use if AggregateEmotion mode selected. 集計結果を生成する頻度を指定します。Specifies with what frequency to produce aggregate results.

集計の既定値Aggregate defaults

以下は、集計時間枠と間隔の設定に対して推奨される値です。Below are recommended values for the aggregate window and interval settings. AggregateEmotionWindowMs は AggregateEmotionIntervalMs より長くする必要があります。AggregateEmotionWindowMs should be longer than AggregateEmotionIntervalMs.

既定値 (秒)Defaults(s) 最大 (秒)Max(s) 最小 (秒)Min(s)
AggregateEmotionWindowMsAggregateEmotionWindowMs 0.50.5 22 0.250.25
AggregateEmotionIntervalMsAggregateEmotionIntervalMs 0.50.5 11 0.250.25

JSON 出力JSON output

感情の集計の JSON 出力 (途中まで):JSON output for aggregate emotion (truncated):

{
 "version": 1,
 "timescale": 30000,
 "offset": 0,
 "framerate": 29.97,
 "width": 1280,
 "height": 720,
 "fragments": [
   {
     "start": 0,
     "duration": 60060,
     "interval": 15015,
     "events": [
       [
         {
           "windowFaceDistribution": {
             "neutral": 0,
             "happiness": 0,
             "surprise": 0,
             "sadness": 0,
             "anger": 0,
             "disgust": 0,
             "fear": 0,
             "contempt": 0
           },
           "windowMeanScores": {
             "neutral": 0,
             "happiness": 0,
             "surprise": 0,
             "sadness": 0,
             "anger": 0,
             "disgust": 0,
             "fear": 0,
             "contempt": 0
           }
         }
       ],
       [
         {
           "windowFaceDistribution": {
             "neutral": 0,
             "happiness": 0,
             "surprise": 0,
             "sadness": 0,
             "anger": 0,
             "disgust": 0,
             "fear": 0,
             "contempt": 0
           },
           "windowMeanScores": {
             "neutral": 0,
             "happiness": 0,
             "surprise": 0,
             "sadness": 0,
             "anger": 0,
             "disgust": 0,
             "fear": 0,
             "contempt": 0
           }
         }
       ],
       [
         {
           "windowFaceDistribution": {
             "neutral": 0,
             "happiness": 0,
             "surprise": 0,
             "sadness": 0,
             "anger": 0,
             "disgust": 0,
             "fear": 0,
             "contempt": 0
           },
           "windowMeanScores": {
             "neutral": 0,
             "happiness": 0,
             "surprise": 0,
             "sadness": 0,
             "anger": 0,
             "disgust": 0,
             "fear": 0,
             "contempt": 0
           }
         }
       ],
       [
         {
           "windowFaceDistribution": {
             "neutral": 0,
             "happiness": 0,
             "surprise": 0,
             "sadness": 0,
             "anger": 0,
             "disgust": 0,
             "fear": 0,
             "contempt": 0
           },
           "windowMeanScores": {
             "neutral": 0,
             "happiness": 0,
             "surprise": 0,
             "sadness": 0,
             "anger": 0,
             "disgust": 0,
             "fear": 0,
             "contempt": 0
           }
         }
       ]
     ]
   },
   {
     "start": 60060,
     "duration": 60060,
     "interval": 15015,
     "events": [
       [
         {
           "windowFaceDistribution": {
             "neutral": 1,
             "happiness": 0,
             "surprise": 0,
             "sadness": 0,
             "anger": 0,
             "disgust": 0,
             "fear": 0,
             "contempt": 0
           },
           "windowMeanScores": {
             "neutral": 0.688541,
             "happiness": 0.0586323,
             "surprise": 0.227184,
             "sadness": 0.00945675,
             "anger": 0.00592107,
             "disgust": 0.00154993,
             "fear": 0.00450447,
             "contempt": 0.0042109
           }
         }
       ],
       [
         {
           "windowFaceDistribution": {
             "neutral": 1,
             "happiness": 0,
             "surprise": 0,
             "sadness": 0,
             "anger": 0,
             "disgust": 0,
             "fear": 0,

制限事項Limitations

  • サポートされている入力ビデオ形式は、MP4、MOV、WMV です。The supported input video formats include MP4, MOV, and WMV.
  • 検出可能な顔のサイズは、24 x 24 ~ 2048 x 2048 ピクセルの範囲です。The detectable face size range is 24x24 to 2048x2048 pixels. この範囲から外れる顔は検出されません。The faces out of this range will not be detected.
  • 各ビデオについて、返される顔の最大数は 64 です。For each video, the maximum number of faces returned is 64.
  • 技術的な課題のために、顔を検出できない場合があります (例: 顔を角度が非常に大きい (頭部姿勢)、遮蔽が大きい)。Some faces may not be detected due to technical challenges; e.g. very large face angles (head-pose), and large occlusion. 顔が正面または正面に近い方向を向いているときに、最善の結果が得られます。Frontal and near-frontal faces have the best results.

.NET サンプル コード.NET sample code

このプログラムでは次の方法を示します。The following program shows how to:

  1. 資産を作成し、その資産にメディア ファイルをアップロードします。Create an asset and upload a media file into the asset.
  2. 次の JSON プリセットを含む構成ファイルに基づく顔検出タスクのジョブを作成します。Create a job with a face detection task based on a configuration file that contains the following json preset.

     {
         "version": "1.0"
     }
    
  3. 出力 JSON ファイルをダウンロードします。Download the output JSON files.

Visual Studio プロジェクトの作成と構成Create and configure a Visual Studio project

.NET を使用した Media Services 開発」の説明に従って、開発環境をセットアップし、app.config ファイルに接続情報を指定します。Set up your development environment and populate the app.config file with connection information, as described in Media Services development with .NET.

Example

using System;
using System.Configuration;
using System.IO;
using System.Linq;
using Microsoft.WindowsAzure.MediaServices.Client;
using System.Threading;
using System.Threading.Tasks;

namespace FaceDetection
{
    class Program
    {
        private static readonly string _AADTenantDomain =
                  ConfigurationManager.AppSettings["AADTenantDomain"];
        private static readonly string _RESTAPIEndpoint =
                  ConfigurationManager.AppSettings["MediaServiceRESTAPIEndpoint"];

        // Field for service context.
        private static CloudMediaContext _context = null;

        static void Main(string[] args)
        {
            var tokenCredentials = new AzureAdTokenCredentials(_AADTenantDomain, AzureEnvironments.AzureCloudEnvironment);
            var tokenProvider = new AzureAdTokenProvider(tokenCredentials);

            _context = new CloudMediaContext(new Uri(_RESTAPIEndpoint), tokenProvider);

            // Run the FaceDetection job.
            var asset = RunFaceDetectionJob(@"C:\supportFiles\FaceDetection\BigBuckBunny.mp4",
                                        @"C:\supportFiles\FaceDetection\config.json");

            // Download the job output asset.
            DownloadAsset(asset, @"C:\supportFiles\FaceDetection\Output");
        }

        static IAsset RunFaceDetectionJob(string inputMediaFilePath, string configurationFile)
        {
            // Create an asset and upload the input media file to storage.
            IAsset asset = CreateAssetAndUploadSingleFile(inputMediaFilePath,
                "My Face Detection Input Asset",
                AssetCreationOptions.None);

            // Declare a new job.
            IJob job = _context.Jobs.Create("My Face Detection Job");

            // Get a reference to Azure Media Face Detector.
            string MediaProcessorName = "Azure Media Face Detector";

            var processor = GetLatestMediaProcessorByName(MediaProcessorName);

            // Read configuration from the specified file.
            string configuration = File.ReadAllText(configurationFile);

            // Create a task with the encoding details, using a string preset.
            ITask task = job.Tasks.AddNew("My Face Detection Task",
                processor,
                configuration,
                TaskOptions.None);

            // Specify the input asset.
            task.InputAssets.Add(asset);

            // Add an output asset to contain the results of the job.
            task.OutputAssets.AddNew("My Face Detectoion Output Asset", AssetCreationOptions.None);

            // Use the following event handler to check job progress.  
            job.StateChanged += new EventHandler<JobStateChangedEventArgs>(StateChanged);

            // Launch the job.
            job.Submit();

            // Check job execution and wait for job to finish.
            Task progressJobTask = job.GetExecutionProgressTask(CancellationToken.None);

            progressJobTask.Wait();

            // If job state is Error, the event handling
            // method for job progress should log errors.  Here we check
            // for error state and exit if needed.
            if (job.State == JobState.Error)
            {
                ErrorDetail error = job.Tasks.First().ErrorDetails.First();
                Console.WriteLine(string.Format("Error: {0}. {1}",
                                                error.Code,
                                                error.Message));
                return null;
            }

            return job.OutputMediaAssets[0];
        }

        static IAsset CreateAssetAndUploadSingleFile(string filePath, string assetName, AssetCreationOptions options)
        {
            IAsset asset = _context.Assets.Create(assetName, options);

            var assetFile = asset.AssetFiles.Create(Path.GetFileName(filePath));
            assetFile.Upload(filePath);

            return asset;
        }

        static void DownloadAsset(IAsset asset, string outputDirectory)
        {
            foreach (IAssetFile file in asset.AssetFiles)
            {
                file.Download(Path.Combine(outputDirectory, file.Name));
            }
        }

        static IMediaProcessor GetLatestMediaProcessorByName(string mediaProcessorName)
        {
            var processor = _context.MediaProcessors
                .Where(p => p.Name == mediaProcessorName)
                .ToList()
                .OrderBy(p => new Version(p.Version))
                .LastOrDefault();

            if (processor == null)
                throw new ArgumentException(string.Format("Unknown media processor",
                                                           mediaProcessorName));

            return processor;
        }

        static private void StateChanged(object sender, JobStateChangedEventArgs e)
        {
            Console.WriteLine("Job state changed event:");
            Console.WriteLine("  Previous state: " + e.PreviousState);
            Console.WriteLine("  Current state: " + e.CurrentState);

            switch (e.CurrentState)
            {
                case JobState.Finished:
                    Console.WriteLine();
                    Console.WriteLine("Job is finished.");
                    Console.WriteLine();
                    break;
                case JobState.Canceling:
                case JobState.Queued:
                case JobState.Scheduled:
                case JobState.Processing:
                    Console.WriteLine("Please wait...\n");
                    break;
                case JobState.Canceled:
                case JobState.Error:
                    // Cast sender as a job.
                    IJob job = (IJob)sender;
                    // Display or log error details as needed.
                    // LogJobStop(job.Id);
                    break;
                default:
                    break;
            }
        }
    }
}

Media Services のラーニング パスMedia Services learning paths

Azure Media Services のラーニング パスについて読む。Read about the Azure Media Services learning paths:

フィードバックの提供Provide feedback

フィードバック フォーラムでは、Azure Media Services の改善方法について、フィードバックの提供や提案を行うことができます。Use the User Voice forum to provide feedback and make suggestions on how to improve Azure Media Services. また、次のカテゴリのいずれかをクリックすると、そのカテゴリのフォーラムに直接アクセスすることもできます。You also can go directly to one of the following categories:

Azure Media Services Analytics の概要Azure Media Services Analytics Overview

Azure Media Analytics デモAzure Media Analytics demos