mirror of
https://github.com/kingomarnajjar/Cognitive-Samples-VideoFrameAnalysis.git
synced 2026-07-25 22:27:34 +10:00
* Fix VideoFrameAnalysis project * Accept endpoint name, to accomodate new regions * Update package dependencies * Tidy up trailing whitespace * Fix Vision API host label
173 lines
6.8 KiB
C#
173 lines
6.8 KiB
C#
//
|
|
// Copyright (c) Microsoft. All rights reserved.
|
|
// Licensed under the MIT license.
|
|
//
|
|
// Microsoft Cognitive Services: http://www.microsoft.com/cognitive
|
|
//
|
|
// Microsoft Cognitive Services Github:
|
|
// https://github.com/Microsoft/Cognitive
|
|
//
|
|
// Copyright (c) Microsoft Corporation
|
|
// All rights reserved.
|
|
//
|
|
// MIT License:
|
|
// Permission is hereby granted, free of charge, to any person obtaining
|
|
// a copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to
|
|
// permit persons to whom the Software is furnished to do so, subject to
|
|
// the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be
|
|
// included in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND,
|
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
//
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows;
|
|
using System.Windows.Media;
|
|
using System.Windows.Media.Imaging;
|
|
using Microsoft.ProjectOxford.Common.Contract;
|
|
using Microsoft.ProjectOxford.Emotion.Contract;
|
|
using Microsoft.ProjectOxford.Face.Contract;
|
|
using Microsoft.ProjectOxford.Vision.Contract;
|
|
|
|
namespace LiveCameraSample
|
|
{
|
|
public class Visualization
|
|
{
|
|
private static SolidColorBrush s_lineBrush = new SolidColorBrush(new System.Windows.Media.Color { R = 255, G = 185, B = 0, A = 255 });
|
|
private static Typeface s_typeface = new Typeface(new FontFamily("Segoe UI"), FontStyles.Normal, FontWeights.Bold, FontStretches.Normal);
|
|
|
|
private static BitmapSource DrawOverlay(BitmapSource baseImage, Action<DrawingContext, double> drawAction)
|
|
{
|
|
double annotationScale = baseImage.PixelHeight / 320;
|
|
|
|
DrawingVisual visual = new DrawingVisual();
|
|
DrawingContext drawingContext = visual.RenderOpen();
|
|
|
|
drawingContext.DrawImage(baseImage, new Rect(0, 0, baseImage.Width, baseImage.Height));
|
|
|
|
drawAction(drawingContext, annotationScale);
|
|
|
|
drawingContext.Close();
|
|
|
|
RenderTargetBitmap outputBitmap = new RenderTargetBitmap(
|
|
baseImage.PixelWidth, baseImage.PixelHeight,
|
|
baseImage.DpiX, baseImage.DpiY, PixelFormats.Pbgra32);
|
|
|
|
outputBitmap.Render(visual);
|
|
|
|
return outputBitmap;
|
|
}
|
|
|
|
public static BitmapSource DrawTags(BitmapSource baseImage, Tag[] tags)
|
|
{
|
|
if (tags == null)
|
|
{
|
|
return baseImage;
|
|
}
|
|
|
|
Action<DrawingContext, double> drawAction = (drawingContext, annotationScale) =>
|
|
{
|
|
double y = 0;
|
|
foreach (var tag in tags)
|
|
{
|
|
// Create formatted text--in a particular font at a particular size
|
|
FormattedText ft = new FormattedText(tag.Name,
|
|
CultureInfo.CurrentCulture, FlowDirection.LeftToRight, s_typeface,
|
|
42 * annotationScale, Brushes.Black);
|
|
// Instead of calling DrawText (which can only draw the text in a solid colour), we
|
|
// convert to geometry and use DrawGeometry, which allows us to add an outline.
|
|
var geom = ft.BuildGeometry(new System.Windows.Point(10 * annotationScale, y));
|
|
drawingContext.DrawGeometry(s_lineBrush, new Pen(Brushes.Black, 2 * annotationScale), geom);
|
|
// Move line down
|
|
y += 42 * annotationScale;
|
|
}
|
|
};
|
|
|
|
return DrawOverlay(baseImage, drawAction);
|
|
}
|
|
|
|
public static BitmapSource DrawFaces(BitmapSource baseImage, Microsoft.ProjectOxford.Face.Contract.Face[] faces, EmotionScores[] emotionScores, string[] celebName)
|
|
{
|
|
if (faces == null)
|
|
{
|
|
return baseImage;
|
|
}
|
|
|
|
Action<DrawingContext, double> drawAction = (drawingContext, annotationScale) =>
|
|
{
|
|
for (int i = 0; i < faces.Length; i++)
|
|
{
|
|
var face = faces[i];
|
|
if (face.FaceRectangle == null) { continue; }
|
|
|
|
Rect faceRect = new Rect(
|
|
face.FaceRectangle.Left, face.FaceRectangle.Top,
|
|
face.FaceRectangle.Width, face.FaceRectangle.Height);
|
|
string text = "";
|
|
|
|
if (face.FaceAttributes != null)
|
|
{
|
|
text += Aggregation.SummarizeFaceAttributes(face.FaceAttributes);
|
|
}
|
|
|
|
if (emotionScores?[i] != null)
|
|
{
|
|
text += Aggregation.SummarizeEmotion(emotionScores[i]);
|
|
}
|
|
|
|
if (celebName?[i] != null)
|
|
{
|
|
text += celebName[i];
|
|
}
|
|
|
|
faceRect.Inflate(6 * annotationScale, 6 * annotationScale);
|
|
|
|
double lineThickness = 4 * annotationScale;
|
|
|
|
drawingContext.DrawRectangle(
|
|
Brushes.Transparent,
|
|
new Pen(s_lineBrush, lineThickness),
|
|
faceRect);
|
|
|
|
if (text != "")
|
|
{
|
|
FormattedText ft = new FormattedText(text,
|
|
CultureInfo.CurrentCulture, FlowDirection.LeftToRight, s_typeface,
|
|
16 * annotationScale, Brushes.Black);
|
|
|
|
var pad = 3 * annotationScale;
|
|
|
|
var ypad = pad;
|
|
var xpad = pad + 4 * annotationScale;
|
|
var origin = new System.Windows.Point(
|
|
faceRect.Left + xpad - lineThickness / 2,
|
|
faceRect.Top - ft.Height - ypad + lineThickness / 2);
|
|
var rect = ft.BuildHighlightGeometry(origin).GetRenderBounds(null);
|
|
rect.Inflate(xpad, ypad);
|
|
|
|
drawingContext.DrawRectangle(s_lineBrush, null, rect);
|
|
drawingContext.DrawText(ft, origin);
|
|
}
|
|
}
|
|
};
|
|
|
|
return DrawOverlay(baseImage, drawAction);
|
|
}
|
|
}
|
|
}
|