kinect/codes/Azure-Kinect-Samples/build2019/csharp/4 - CognitiveServices/MainWindow.xaml.cs

305 lines
10 KiB
C#
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//------------------------------------------------------------------------------
// <copyright file="MainWindow.xaml.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace Microsoft.Samples.AzureKinectBasics
{
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Microsoft.Azure.Kinect.Sensor;
using Microsoft.Azure.CognitiveServices.Vision.ComputerVision;
using Microsoft.Azure.CognitiveServices.Vision.ComputerVision.Models;
using System.Collections.Generic;
/// <summary>
/// Interaction logic for MainWindow
/// </summary>
public partial class MainWindow : Window, INotifyPropertyChanged
{
/// <summary>
/// Azure Kinect sensor
/// </summary>
private readonly Device kinect = null;
/// <summary>
/// Azure Kinect transformation engine
/// </summary>
private readonly Transformation transform = null;
/// <summary>
/// Bitmap to display
/// </summary>
private readonly WriteableBitmap bitmap = null;
/// <summary>
/// Current status text to display
/// </summary>
private string statusText = null;
/// <summary>
/// The width in pixels of the color image from the Azure Kinect DK
/// </summary>
private readonly int colorWidth = 0;
/// <summary>
/// The height in pixels of the color image from the Azure Kinect DK
/// </summary>
private readonly int colorHeight = 0;
/// <summary>
/// Status of the application
/// </summary>
private bool running = true;
/// <summary>
/// Subscription key for Cognitive Services
/// </summary>
private const string subscriptionKey = "YOUR SUBSCRIPTION KEY HERE";
/// <summary>
/// Connection to Azure Computer Vision Cognitive Service
/// </summary>
private ComputerVisionClient computerVision;
/// <summary>
/// Bounding box of the person
/// </summary>
BoundingRect boundingBox;
/// <summary>
/// List of features to find in images
/// </summary>
private static readonly List<VisualFeatureTypes> features =
new List<VisualFeatureTypes>()
{
VisualFeatureTypes.Categories, VisualFeatureTypes.Description,
VisualFeatureTypes.Faces, VisualFeatureTypes.ImageType,
VisualFeatureTypes.Tags, VisualFeatureTypes.Objects
};
/// <summary>
/// Initializes a new instance of the MainWindow class.
/// </summary>
public MainWindow()
{
// Open the default device
this.kinect = Device.Open();
// Configure camera modes
this.kinect.StartCameras(new DeviceConfiguration
{
ColorFormat = ImageFormat.ColorBGRA32,
ColorResolution = ColorResolution.R1080p,
DepthMode = DepthMode.NFOV_2x2Binned,
SynchronizedImagesOnly = true
});
// Initialize the transformation engine
this.transform = this.kinect.GetCalibration().CreateTransformation();
this.colorWidth = this.kinect.GetCalibration().ColorCameraCalibration.ResolutionWidth;
this.colorHeight = this.kinect.GetCalibration().ColorCameraCalibration.ResolutionHeight;
// Create the computer vision client
computerVision = new ComputerVisionClient(
new ApiKeyServiceClientCredentials(subscriptionKey),
new System.Net.Http.DelegatingHandler[] { })
{
// You must use the same region as you used to get  
// your subscription keys.
Endpoint = "https://westus.api.cognitive.microsoft.com/"
};
this.bitmap = new WriteableBitmap(colorWidth, colorHeight, 96.0, 96.0, PixelFormats.Bgra32, null);
this.DataContext = this;
this.InitializeComponent();
}
/// <summary>
/// INotifyPropertyChangedPropertyChanged event to allow window controls to bind to changeable data
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Gets the bitmap to display
/// </summary>
public ImageSource ImageSource
{
get
{
return this.bitmap;
}
}
/// <summary>
/// Gets or sets the current status text to display
/// </summary>
public string StatusText
{
get
{
return this.statusText;
}
set
{
if (this.statusText != value)
{
this.statusText = value;
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs("StatusText"));
}
}
}
}
/// <summary>
/// Execute shutdown tasks
/// </summary>
/// <param name="sender">object sending the event</param>
/// <param name="e">event arguments</param>
private void MainWindow_Closing(object sender, CancelEventArgs e)
{
running = false;
if (this.kinect != null)
{
this.kinect.Dispose();
}
}
/// <summary>
/// Handles the user clicking on the screenshot button
/// </summary>
/// <param name="sender">object sending the event</param>
/// <param name="e">event arguments</param>
private void ScreenshotButton_Click(object sender, RoutedEventArgs e)
{
// Create a render target to which we'll render our composite image
RenderTargetBitmap renderBitmap = new RenderTargetBitmap((int)CompositeImage.ActualWidth, (int)CompositeImage.ActualHeight, 96.0, 96.0, PixelFormats.Pbgra32);
DrawingVisual dv = new DrawingVisual();
using (DrawingContext dc = dv.RenderOpen())
{
VisualBrush brush = new VisualBrush(CompositeImage);
dc.DrawRectangle(brush, null, new System.Windows.Rect(new Point(), new Size(CompositeImage.ActualWidth, CompositeImage.ActualHeight)));
}
renderBitmap.Render(dv);
BitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(renderBitmap));
string time = System.DateTime.Now.ToString("hh'-'mm'-'ss", CultureInfo.CurrentUICulture.DateTimeFormat);
string myPhotos = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
string path = Path.Combine(myPhotos, "KinectScreenshot-" + time + ".png");
// Write the new file to disk
try
{
using (FileStream fs = new FileStream(path, FileMode.Create))
{
encoder.Save(fs);
}
this.StatusText = string.Format(Properties.Resources.SavedScreenshotStatusTextFormat, path);
}
catch (IOException)
{
this.StatusText = string.Format(Properties.Resources.FailedScreenshotStatusTextFormat, path);
}
}
private Stream StreamFromBitmapSource(BitmapSource bitmap)
{
Stream jpeg = new MemoryStream();
BitmapEncoder enc = new JpegBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(bitmap));
enc.Save(jpeg);
jpeg.Position = 0;
return jpeg;
}
private async void Window_Loaded(object sender, RoutedEventArgs e)
{
int count = 0;
while (running)
{
using (Image transformedDepth = new Image(ImageFormat.Depth16, colorWidth, colorHeight, colorWidth * sizeof(UInt16)))
using (Capture capture = await Task.Run(() => { return this.kinect.GetCapture(); }))
{
count++;
this.transform.DepthImageToColorCamera(capture, transformedDepth);
this.bitmap.Lock();
var color = capture.Color;
var region = new Int32Rect(0, 0, color.WidthPixels, color.HeightPixels);
unsafe
{
using (var pin = color.Memory.Pin())
{
this.bitmap.WritePixels(region, (IntPtr)pin.Pointer, (int)color.Size, color.StrideBytes);
}
if (boundingBox != null)
{
int y = (boundingBox.Y + boundingBox.H / 2);
int x = (boundingBox.X + boundingBox.W / 2);
this.StatusText = "The person is:" + transformedDepth.GetPixel<ushort>(y, x) + "mm away";
}
}
this.bitmap.AddDirtyRect(region);
this.bitmap.Unlock();
if (count % 30 == 0)
{
var stream = StreamFromBitmapSource(this.bitmap);
_ = computerVision.AnalyzeImageInStreamAsync(stream, MainWindow.features).ContinueWith((Task<ImageAnalysis> analysis) =>
{
try
{
foreach (var item in analysis.Result.Objects)
{
if (item.ObjectProperty == "person")
{
this.boundingBox = item.Rectangle;
}
}
}
catch (System.Exception ex)
{
this.StatusText = ex.ToString();
}
}, TaskScheduler.FromCurrentSynchronizationContext());
}
}
}
}
}
}