C# 如何在WPF kinect应用程序中使用colorstream在图像上传输RGB数据?
我想在WPF kinect应用程序中查看图像上RGB数据“颜色流”的流,如何才能做到这一点 谢谢C# 如何在WPF kinect应用程序中使用colorstream在图像上传输RGB数据?,c#,kinect,C#,Kinect,我想在WPF kinect应用程序中查看图像上RGB数据“颜色流”的流,如何才能做到这一点 谢谢 这是我的代码和xaml,您可以看到骨架是在图像上绘制的,我想要的是在图像上除了骨架之外添加颜色流,那么我如何才能做到这一点呢 非常感谢, namespace Microsoft.Samples.Kinect.SkeletonBasics { using System.IO; using System.Windows; using System.Windows.Media;
这是我的代码和xaml,您可以看到骨架是在图像上绘制的,我想要的是在图像上除了骨架之外添加颜色流,那么我如何才能做到这一点呢 非常感谢,
namespace Microsoft.Samples.Kinect.SkeletonBasics
{
using System.IO;
using System.Windows;
using System.Windows.Media;
using Microsoft.Kinect;
using System.Windows.Media.Media3D;
using System;
using System.Data;
using System.Globalization;
using System.Linq;
public partial class MainWindow : Window
{
private const float RenderWidth = 640.0f;
private const float RenderHeight = 480.0f;
private const double JointThickness = 3;
private const double BodyCenterThickness = 10;
private const double ClipBoundsThickness = 10;
private readonly Brush centerPointBrush = Brushes.Blue;
private readonly Brush trackedJointBrush = new SolidColorBrush(Color.FromArgb(255, 68, 192, 68));
private readonly Brush inferredJointBrush = Brushes.Yellow;
private readonly Pen trackedBonePen = new Pen(Brushes.Green, 6);
private readonly Pen trackedBonePenwrong = new Pen(Brushes.White, 6);
private readonly Pen inferredBonePen = new Pen(Brushes.Gray, 1);
private KinectSensor sensor;
private DrawingGroup drawingGroup;
private DrawingImage imageSource;
public MainWindow()
{
InitializeComponent();
}
private static void RenderClippedEdges(Skeleton skeleton, DrawingContext drawingContext)
{
if (skeleton.ClippedEdges.HasFlag(FrameEdges.Bottom))
{
drawingContext.DrawRectangle(
Brushes.Red,
null,
new Rect(0, RenderHeight - ClipBoundsThickness, RenderWidth, ClipBoundsThickness));
}
if (skeleton.ClippedEdges.HasFlag(FrameEdges.Top))
{
drawingContext.DrawRectangle(
Brushes.Red,
null,
new Rect(0, 0, RenderWidth, ClipBoundsThickness));
}
if (skeleton.ClippedEdges.HasFlag(FrameEdges.Left))
{
drawingContext.DrawRectangle(
Brushes.Red,
null,
new Rect(0, 0, ClipBoundsThickness, RenderHeight));
}
if (skeleton.ClippedEdges.HasFlag(FrameEdges.Right))
{
drawingContext.DrawRectangle(
Brushes.Red,
null,
new Rect(RenderWidth - ClipBoundsThickness, 0, ClipBoundsThickness, RenderHeight));
}
}
private void WindowLoaded(object sender, RoutedEventArgs e)
{
// Create the drawing group we'll use for drawing
this.drawingGroup = new DrawingGroup();
// Create an image source that we can use in our image control
this.imageSource = new DrawingImage(this.drawingGroup);
// Display the drawing using our image control
Image.Source = this.imageSource;
// Look through all sensors and start the first connected one.
// This requires that a Kinect is connected at the time of app startup.
// To make your app robust against plug/unplug,
// it is recommended to use KinectSensorChooser provided in Microsoft.Kinect.Toolkit
foreach (var potentialSensor in KinectSensor.KinectSensors)
{
if (potentialSensor.Status == KinectStatus.Connected)
{
this.sensor = potentialSensor;
break;
}
}
if (null != this.sensor)
{
// Turn on the skeleton stream to receive skeleton frames
this.sensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
// this.sensor.ColorFrameReady += this.SensorColorSkeletonFrameReady;
this.sensor.SkeletonStream.Enable();
// this.sensor.ColorFrameReady += new EventHandler<ColorImageFrameReadyEventArgs>(kinectSensor_ColorFrameReady);
// Add an event handler to be called whenever there is new color frame data
this.sensor.SkeletonFrameReady += this.SensorSkeletonFrameReady;
// Start the sensor!
try
{
this.sensor.Start();
}
catch (IOException)
{
this.sensor = null;
}
}
if (null == this.sensor)
{
this.statusBarText.Text = Properties.Resources.NoKinectReady;
}
}
private void WindowClosing(object sender, System.ComponentModel.CancelEventArgs e)
{
if (null != this.sensor)
{
this.sensor.Stop();
}
}
private void SensorSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{
Skeleton[] skeletons = new Skeleton[0];
using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
{
if (skeletonFrame != null)
{
skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
skeletonFrame.CopySkeletonDataTo(skeletons);
}
}
using (DrawingContext dc = this.drawingGroup.Open())
{
// Draw a transparent background to set the render size
//dc.DrawImage();
dc.DrawRectangle(Brushes.Black, null, new Rect(0.0, 0.0, RenderWidth, RenderHeight));
if (skeletons.Length != 0)
{
foreach (Skeleton skel in skeletons)
{
Skeleton first = FindSkeleton(e);
if (first == null)
return;
int firstSkeleton = first.TrackingId;
RenderClippedEdges(skel, dc);
if (skel.TrackingState == SkeletonTrackingState.Tracked)
{
this.DrawBonesAndJoints(skel, dc);
}
else if (skel.TrackingState == SkeletonTrackingState.PositionOnly)
{
dc.DrawEllipse(
this.centerPointBrush,
null,
this.SkeletonPointToScreen(skel.Position),
BodyCenterThickness,
BodyCenterThickness);
}
}
}
// prevent drawing outside of our render area
this.drawingGroup.ClipGeometry = new RectangleGeometry(new Rect(0.0, 0.0, RenderWidth, RenderHeight));
}
}
private void DrawBonesAndJoints(Skeleton skeleton, DrawingContext drawingContext)
{
// Render Torso
this.DrawBone(skeleton, drawingContext, JointType.Head, JointType.ShoulderCenter);
this.DrawBone(skeleton, drawingContext, JointType.ShoulderCenter, JointType.ShoulderLeft);
this.DrawBone(skeleton, drawingContext, JointType.ShoulderCenter, JointType.ShoulderRight);
this.DrawBone(skeleton, drawingContext, JointType.ShoulderCenter, JointType.Spine);
this.DrawBone(skeleton, drawingContext, JointType.Spine, JointType.HipCenter);
this.DrawBone(skeleton, drawingContext, JointType.HipCenter, JointType.HipLeft);
this.DrawBone(skeleton, drawingContext, JointType.HipCenter, JointType.HipRight);
// Left Arm
this.DrawBone(skeleton, drawingContext, JointType.ShoulderLeft, JointType.ElbowLeft);
this.DrawBone(skeleton, drawingContext, JointType.ElbowLeft, JointType.WristLeft);
this.DrawBone(skeleton, drawingContext, JointType.WristLeft, JointType.HandLeft);
// Right Arm
this.DrawBone(skeleton, drawingContext, JointType.ShoulderRight, JointType.ElbowRight);
this.DrawBone(skeleton, drawingContext, JointType.ElbowRight, JointType.WristRight);
this.DrawBone(skeleton, drawingContext, JointType.WristRight, JointType.HandRight);
// Left Leg
this.DrawBone(skeleton, drawingContext, JointType.HipLeft, JointType.KneeLeft);
this.DrawBone(skeleton, drawingContext, JointType.KneeLeft, JointType.AnkleLeft);
this.DrawBone(skeleton, drawingContext, JointType.AnkleLeft, JointType.FootLeft);
// Right Leg
this.DrawBone(skeleton, drawingContext, JointType.HipRight, JointType.KneeRight);
this.DrawBone(skeleton, drawingContext, JointType.KneeRight, JointType.AnkleRight);
this.DrawBone(skeleton, drawingContext, JointType.AnkleRight, JointType.FootRight);
// Render Joints
foreach (Joint joint in skeleton.Joints)
{
Brush drawBrush = null;
if (joint.TrackingState == JointTrackingState.Tracked)
{
drawBrush = this.trackedJointBrush;
}
else if (joint.TrackingState == JointTrackingState.Inferred)
{
drawBrush = this.inferredJointBrush;
}
if (drawBrush != null)
{
drawingContext.DrawEllipse(drawBrush, null, this.SkeletonPointToScreen(joint.Position), JointThickness, JointThickness);
}
}
}
private Point SkeletonPointToScreen(SkeletonPoint skelpoint)
{
// Convert point to depth space.
// We are not using depth directly, but we do want the points in our 640x480 output resolution.
DepthImagePoint depthPoint = this.sensor.MapSkeletonPointToDepth(
skelpoint,
DepthImageFormat.Resolution640x480Fps30);
return new Point(depthPoint.X, depthPoint.Y);
}
private void DrawBone(Skeleton skeleton, DrawingContext drawingContext, JointType jointType0, JointType jointType1)
{
Joint joint0 = skeleton.Joints[jointType0];
Joint joint1 = skeleton.Joints[jointType1];
// If we can't find either of these joints, exit
if (joint0.TrackingState == JointTrackingState.NotTracked ||
joint1.TrackingState == JointTrackingState.NotTracked)
{
return;
}
// Don't draw if both points are inferred
if (joint0.TrackingState == JointTrackingState.Inferred &&
joint1.TrackingState == JointTrackingState.Inferred)
{
return;
}
// We assume all drawn bones are inferred unless BOTH joints are tracked
Pen drawPen = this.inferredBonePen;
if (joint0.TrackingState == JointTrackingState.Tracked && joint1.TrackingState == JointTrackingState.Tracked)
{
// int uuu=0;
//if (uuu==0)
// drawPen = this.trackedBonePenwrong;
//else
drawPen = this.trackedBonePen;
}
drawingContext.DrawLine(drawPen, this.SkeletonPointToScreen(joint0.Position), this.SkeletonPointToScreen(joint1.Position));
}
private void CheckBoxSeatedModeChanged(object sender, RoutedEventArgs e)
{
if (null != this.sensor)
{
if (this.checkBoxSeatedMode.IsChecked.GetValueOrDefault())
{
this.sensor.SkeletonStream.TrackingMode = SkeletonTrackingMode.Seated;
}
else
{
this.sensor.SkeletonStream.TrackingMode = SkeletonTrackingMode.Default;
}
}
}
private void button1_Click(object sender, RoutedEventArgs e)
{
Application.Current.Shutdown();
}
}
}
namespace Microsoft.Samples.Kinect.SkeletonBasics
{
使用System.IO;
使用System.Windows;
使用System.Windows.Media;
使用Microsoft.Kinect;
使用System.Windows.Media.Media3D;
使用制度;
使用系统数据;
利用制度全球化;
使用System.Linq;
公共部分类主窗口:窗口
{
private const float RenderWidth=640.0f;
私有常量浮动渲染灯光=480.0f;
私有常数双接头厚度=3;
私人建筑双车身中心厚度=10;
private const双剪贴簿厚度=10;
私有只读画笔中心点画笔=画笔。蓝色;
private readonly Brush trackedJointBrush=新的SolidColorBrush(Color.FromArgb(255,68,192,68));
private readonly Brush InferedJointBrush=笔刷。黄色;
private readonly Pen trackedBonePen=新笔(刷子绿色,6);
private readonly Pen TrackedBonepEnError=新笔(刷子。白色,6);
private readonly Pen inferredBonePen=新笔(刷子为1.Gray);
专用运动传感器;
私人提款集团提款集团;
私有绘图图像源;
公共主窗口()
{
初始化组件();
}
私有静态空心渲染裁剪边(骨架骨架、DrawingContext DrawingContext)
{
if(skeleton.clippedGes.HasFlag(frameEdge.Bottom))
{
drawingContext.DrawRectangle(
刷子,红色,
无效的
新的Rect(0,renderRight-剪贴簿厚度,RenderWidth,剪贴簿厚度));
}
if(skeleton.clippedGes.HasFlag(frameEdge.Top))
{
drawingContext.DrawRectangle(
刷子,红色,
无效的
新的矩形(0,0,渲染宽度,剪贴簿厚度);
}
if(skeleton.ClippedGes.HasFlag(FrameEdge.Left))
{
drawingContext.DrawRectangle(
刷子,红色,
无效的
新的Rect(0,0,剪贴簿厚度,RenderHeight));
}
if(skeleton.clippedGes.HasFlag(frameEdge.Right))
{
drawingContext.DrawRectangle(
刷子,红色,
无效的
新的Rect(RenderWidth-clipboondshickness,0,clipboondshickness,RenderHeight));
}
}
已加载私有void窗口(对象发送器,RoutedEventArgs e)
{
//创建我们将用于绘图的绘图组
this.drawingGroup=新的drawingGroup();
//创建可以在图像控件中使用的图像源
this.imageSource=新的DrawingImage(this.drawingGroup);
//使用图像控件显示图形
Image.Source=this.imageSource;
//检查所有传感器并启动第一个连接的传感器。
//这需要在应用程序启动时连接Kinect。
//要使您的应用程序具有强大的防插拔功能,
//建议使用Microsoft.Kinect.Toolkit中提供的KinectSensorChooser
foreach(Kinect传感器中的var电位传感器。Kinect传感器)
{
如果(potentialSensor.Status==KinectStatus.Connected)
{
此传感器=电位传感器;
打破
}
}
如果(空!=此传感器)
{
//启用骨架流以接收骨架帧
这个.sensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
//this.sensor.ColorFrameReady+=this.SensorColorSkeletonFrameReady;
this.sensor.SkeletonStream.Enable();
//this.sensor.ColorFrameReady+=新事件处理程序(kinectSensor\u ColorFrameReady);
//添加一个事件处理程序,以便在有新的颜色框数据时调用
this.sensor.SkeletonFrameReady+=this.SensorSkeletonFrameReady;
//启动传感器!
尝试
{
这个.sensor.Start();
}
捕获(IOException)
{
该传感器=零;
}
}
if(null==此传感器)
{
this.statusBarText.Text=Properties.Resources.nokinecready;
}
}
私有无效窗口关闭(对象发送方,System.ComponentModel.CancelEventArgs e)
{
如果(空!=此传感器)
{
这个.sensor.Stop();
}
}
专用void传感器SkeletonFrameReady(对象发送器,SkeletonFrameReadyEventArgs e)
{
骨架[]骨架=新骨架[0];
使用(SkeletonFrame SkeletonFrame=e.OpenSkeletonFrame())
{
如果(skeletonFrame!=null)
{
skeletons=新骨架[skeletonFrame.SkeletonArrayleLength];
skeletonFrame.CopySkeletonDataTo(骨架);
}
}
使用(DrawingContext dc=this.drawingGroup.Open())
{
//绘制透明背景以设置渲染大小
//dc.DrawImage();
DrawRectangle(画笔。黑色,空,新矩形(0.0,0。
<Window x:Class="Microsoft.Samples.Kinect.SkeletonBasics.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Skeleton Basics" Height="735" Width="1151" Loaded="WindowLoaded" Closing="WindowClosing">
<Window.Resources>
<SolidColorBrush x:Key="MediumGreyBrush" Color="#ff6e6e6e"/>
<SolidColorBrush x:Key="KinectPurpleBrush" Color="#ff52318f"/>
<SolidColorBrush x:Key="KinectBlueBrush" Color="#ff00BCF2"/>
<Style TargetType="{x:Type CheckBox}" x:Key="SquareCheckBox" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Grid>
<StackPanel Orientation="Horizontal" Background="Transparent">
<Grid x:Name="SquareCheckBoxChecked">
<Image x:Name="CheckedNormal" Source="Images\CheckedNormal.png" Stretch="None" HorizontalAlignment="Center"/>
<Image x:Name="CheckedHover" Source="Images\CheckedHover.png" Stretch="None" HorizontalAlignment="Center" Visibility="Collapsed"/>
</Grid>
<Grid x:Name="SquareCheckBoxUnchecked" Visibility="Collapsed">
<Image x:Name="UncheckedNormal" Source="Images\UncheckedNormal.png" Stretch="None" HorizontalAlignment="Center"/>
<Image x:Name="UncheckedHover" Source="Images\UncheckedHover.png" Stretch="None" HorizontalAlignment="Center" Visibility="Collapsed"/>
</Grid>
<TextBlock x:Name="SquareCheckBoxText" Text="{TemplateBinding Content}" TextAlignment="Left" VerticalAlignment="Center" Foreground="{StaticResource KinectPurpleBrush}" FontSize="15" Margin="9,0,0,0"/>
</StackPanel>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="false">
<Setter Property="Visibility" Value="Collapsed" TargetName="SquareCheckBoxChecked"/>
<Setter Property="Visibility" Value="Visible" TargetName="SquareCheckBoxUnchecked"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Visibility" Value="Collapsed" TargetName="CheckedNormal"/>
<Setter Property="Visibility" Value="Collapsed" TargetName="UncheckedNormal"/>
<Setter Property="Visibility" Value="Visible" TargetName="CheckedHover"/>
<Setter Property="Visibility" Value="Visible" TargetName="UncheckedHover"/>
<Setter Property="Foreground" Value="{StaticResource KinectBlueBrush}" TargetName="SquareCheckBoxText"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid Name="layoutGrid" Margin="10 0 10 0" Width="1094">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<DockPanel Grid.Row="0" Margin="0 0 0 20">
<Image DockPanel.Dock="Left" Source="Images\Logo.png" Stretch="None" Margin="0 10 0 5"/>
<TextBlock DockPanel.Dock="Right" VerticalAlignment="Bottom" Foreground="{StaticResource MediumGreyBrush}" FontFamily="Segoe UI" FontSize="18">Skeleton Basics</TextBlock>
<Image Grid.Column="1" Source="Images\Status.png" Stretch="None" HorizontalAlignment="Center" Margin="0 0 0 5"/>
</DockPanel>
<Viewbox Grid.Row="1" Stretch="Uniform" HorizontalAlignment="Left">
<Image Name="Image" Width="640" Height="480"/>
</Viewbox>
<CheckBox Grid.Row="2" Style="{StaticResource SquareCheckBox}" Content="Seated Mode" Height="Auto" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="0 10 10 10" Name="checkBoxSeatedMode" Checked="CheckBoxSeatedModeChanged" Unchecked="CheckBoxSeatedModeChanged"/>
<StatusBar Grid.Row="3" HorizontalAlignment="Stretch" Name="statusBar" VerticalAlignment="Bottom" Background="White" Foreground="{StaticResource MediumGreyBrush}">
<StatusBarItem Padding="0 0 0 10">
<TextBlock Name="statusBarText" Margin="0">Click 'Seated' to change skeletal pipeline type!</TextBlock>
</StatusBarItem>
</StatusBar>
</Window>
KinectSensor kinectSensor = KinectSensor.KinectSensors[0];
kinectSensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
kinectSensor.Start();
kinectSensor.ColorFrameReady += this.ColorImageReady;
private static readonly int Bgr32BytesPerPixel = (PixelFormats.Bgr32.BitsPerPixel + 7) / 8;
private byte[] pixelData;
private WriteableBitmap CameraSource;
private void ColorImageReady(object sender, ColorImageFrameReadyEventArgs e)
{
bool receivedData = false;
using (ColorImageFrame imageFrame = e.OpenColorImageFrame())
{
if (imageFrame != null)
{
if (pixelData == null)
{
this.pixelData = new byte[imageFrame.PixelDataLength];
}
imageFrame.CopyPixelDataTo(this.pixelData);
receivedData = true;
// A WriteableBitmap is a WPF construct that enables resetting the Bits of the image.
// This is more efficient than creating a new Bitmap every frame.
if (receivedData)
{
this.CameraSource.WritePixels(
new Int32Rect(0, 0, imageFrame.Width, imageFrame.Height),
this.pixelData,
imageFrame.Width * Bgr32BytesPerPixel,
0);
}
}
}
}
<Image Name="Camera" Width="160" Height="120" Margin="0,0,0,0" RenderOptions.BitmapScalingMode="HighQuality" />
kinectSensor.ColorFrameReady += new EventHandler<Microsoft.Kinect.ColorImageFrameReadyEventArgs>(ColorImageFrameReady_handler);
public void ColorImageFrameReady_handler(object sender, Microsoft.Kinect.ColorImageFrameReadyEventArgs e)
{
Camera.Source = CameraSource;
}