kinectで人物と骨格の検出をし、検出した人物情報をファイルに保存したいと思っています。(出来たらその後、保存した数値をビットマップ化して、また人物映像として表示したいです。)プログラミング初心者なので、本やネットのプログラムを繋げただけなのでうまくいきません。
人物と骨格の検出はできたのですが、ファイルに保存するプログラムを追加して実行すると、DrawBodyFrameの所の b => b.IsTracked の所にNullReferenceExceptionはユーザーコードによってハンドルされませんでした。と出て実行してもらえません。
ビルドの際にはエラーはなく、実行したら上のような警告が出ます。
追加したのは最後の2017,11,27の所と、ボディインデックスフレームのBGRAデータに変換するという所のWriteFile("test.txt",body);のところです。
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Navigation;
using Windows.UI.Xaml.Shapes;
using WindowsPreview.Kinect;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.Storage.Streams;
namespace FirstKinectSample
{
public sealed partial class MainPage : Page
{
BodyIndexFrameReader bodyIndexFrameReader;
FrameDescription bodyIndexFrameDesc;
//データ取得用 byte[] bodyIndexBuffer; //表示用 int bodyIndexColorBytesPerPixels = 4; byte[] bodyIndexColorBuffer; WriteableBitmap bodyIndexColorBitmap; Color[] bodyIndexColors; BodyFrameReader bodyFrameReader; Body[] bodies; private KinectSensor kinect; public MainPage() { this.kinect = KinectSensor.GetDefault(); this.kinect.Open(); this.InitializeComponent(); } protected override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); try { kinect = KinectSensor.GetDefault(); kinect.Open(); bodyIndexFrameReader = kinect.BodyIndexFrameSource.OpenReader(); bodyIndexFrameReader.FrameArrived += bodyIndexFrameReader_FrameArrived; //表示のためのデータを作成 bodyIndexFrameDesc = kinect.BodyIndexFrameSource.FrameDescription; //ビットマップ bodyIndexColorBitmap = new WriteableBitmap(bodyIndexFrameDesc.Width, bodyIndexFrameDesc.Height); ImageBodyIndex.Source = bodyIndexColorBitmap; //ボディインデックデータ用のバッファ bodyIndexBuffer = new byte[bodyIndexFrameDesc.LengthInPixels]; //ボディインデックデータをBGRA(カラー)データにするためのバッファ bodyIndexColorBuffer = new byte[bodyIndexFrameDesc.LengthInPixels * bodyIndexColorBytesPerPixels]; //色付けするために色の配列を作成する bodyIndexColors = new Color[]{ Colors.Red, Colors.Blue, Colors.Green, Colors.Yellow, Colors.Pink, Colors.Purple, }; // Body用のバッファを作成 bodies = new Body[kinect.BodyFrameSource.BodyCount]; bodyFrameReader = kinect.BodyFrameSource.OpenReader(); bodyFrameReader.FrameArrived += bodyFrameReader_FrameArrived; } catch (Exception ex) { MessageDialog dlg = new MessageDialog(ex.Message); dlg.ShowAsync(); } } void bodyIndexFrameReader_FrameArrived(BodyIndexFrameReader sender, BodyIndexFrameArrivedEventArgs args) { UpdateBodyIndexFrame(args); DrawBodyIndexFrame(); } private void UpdateBodyIndexFrame(BodyIndexFrameArrivedEventArgs args) { //ボディインデックスフレームを取得する using (var bodyIndexFrame = args.FrameReference.AcquireFrame()) { if (bodyIndexFrame == null) { return; } //ボディインデックスデータを取得する bodyIndexFrame.CopyFrameDataToArray(bodyIndexBuffer); } } private void DrawBodyIndexFrame() { //ボディインデックスデータをBGRAデータに変換する for (int i = 0; i < bodyIndexBuffer.Length; i++) { var index = bodyIndexBuffer[i]; int colorindex = i * 4; if (index != 255) { var color = bodyIndexColors[index]; bodyIndexColorBuffer[colorindex + 0] = color.B; bodyIndexColorBuffer[colorindex + 1] = color.G; bodyIndexColorBuffer[colorindex + 2] = color.R; bodyIndexColorBuffer[colorindex + 3] = 255; } else { bodyIndexColorBuffer[colorindex + 0] = 0; bodyIndexColorBuffer[colorindex + 1] = 0; bodyIndexColorBuffer[colorindex + 2] = 0; bodyIndexColorBuffer[colorindex + 3] = 255; } byte body = BodyIndexBuffer[i]; WriteFile("test.txt", body); } //ビットマップにする var stream = bodyIndexColorBitmap.PixelBuffer.AsStream(); stream.Write(bodyIndexColorBuffer, 0, bodyIndexColorBuffer.Length); bodyIndexColorBitmap.Invalidate(); } void bodyFrameReader_FrameArrived(BodyFrameReader sender, BodyFrameArrivedEventArgs args) { UpdateBodyFrame(args); DrawBodyFrame(); } //ボディの更新 private void UpdateBodyFrame(BodyFrameArrivedEventArgs e) { using (var bodyFrame = e.FrameReference.AcquireFrame()) { if (bodyFrame == null) { return; } bodyFrame.GetAndRefreshBodyData(bodies); } } private void DrawBodyFrame() { CanvasBody.Children.Clear(); foreach ( var body in bodies.Where( b => b.IsTracked ) ) { foreach (var joint in body.Joints) { //手の位置が追跡状態 if (joint.Value.TrackingState == TrackingState.Tracked) { DrawEllipse(joint.Value, 10, Colors.Blue); } //手の位置が推測状態 else if (joint.Value.TrackingState == TrackingState.Inferred) { DrawEllipse(joint.Value, 10, Colors.Yellow); } } } } private void DrawEllipse(Joint joint, int R, Color color) { var ellipse = new Ellipse() { Width = R, Height = R, Fill = new SolidColorBrush(color), }; // カメラ座標系をDepth座標系に変換する var point = kinect.CoordinateMapper.MapCameraPointToDepthSpace(joint.Position); if ((point.X < 0) || (point.Y < 0)) { return; }
// Depth座標系で円を配置する
Canvas.SetLeft(ellipse, point.X - (R / 2));
Canvas.SetTop(ellipse, point.Y - (R / 2));
CanvasBody.Children.Add(ellipse); } protected override void OnNavigatedFrom(NavigationEventArgs e) { base.OnNavigatedFrom(e); if (bodyIndexFrameReader != null) { bodyIndexFrameReader.Dispose(); bodyIndexFrameReader = null; } if (bodyFrameReader != null) { bodyFrameReader.Dispose(); bodyFrameReader = null; } if (kinect != null) { kinect.Close(); kinect = null; } } //2017,11,27 private static async void WriteFile(string fileName, byte body) { // ローミングフォルダ StorageFolder folder = ApplicationData.Current.RoamingFolder; // ファイル(存在すれば上書き) StorageFile file = await folder.CreateFileAsync( fileName, CreationCollisionOption.ReplaceExisting ); using (IRandomAccessStream rStream = await file.OpenAsync(FileAccessMode.ReadWrite)) using (IOutputStream oStream = rStream.GetOutputStreamAt(0)) { DataWriter writer = new DataWriter(oStream); writer.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8; writer.WriteByte(body); await writer.StoreAsync(); } } // }
}
visualstudio2013でC#でやっています。
ちなみにXAMLはこのようになっています。
<Page
x:Class="FirstKinectSample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:FirstKinectSample"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
</Page><Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Image x:Name="ImageBodyIndex" Width="512" Height="424" /> <Canvas x:Name="CanvasBody" Width="512" Height="424"/> </Grid>
あなたの回答
tips
プレビュー