我想在WPF kinect应用程序中的图像上查看RGB数据“颜色流”的流,该怎么办?
谢谢
这是我的代码和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();
}
}
}
xaml:
<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>
最佳答案
您是否尝试过Microsoft示例?甚至是互联网样本(那里有很多样本)
由于您使用c#进行开发,因此我假设您使用的是WPF和SDK1.0(或更高版本):
这是一种解决方案:
首先启用颜色流:
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);
}
}
}
}
在您的xaml中:
<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;
}
关于c# - 如何在WPF kinect应用程序中使用颜色流在图像上传输RGB数据?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11114125/