I have two different windows, one will to display streams on a image and calculate a user’s skeleton head position (window A), and another is display a 3D visual model that will use the skeleton data to zoom and translate(animation)(window B).
However, my problem is how can I suppose to pass and keep updating these skeleton head position data from window A to window B? I am using WPF and M’soft Kinect SDK. My another question is that how can I display a control like a button or a menu on the visual model as for my case the model is filled up the whole screen.
foreach (Skeleton skeleton in skeletons)
{
if (skeleton.TrackingState == SkeletonTrackingState.Tracked)
{
ht.GetHeadPosition(skeleton, out message, out headPosition);
this.headPoint.X = headPosition.X;
this.headPoint.Y = headPosition.Y;
this.headPoint.Z = headPosition.Z;
this.StatusTextBlock.Text = message;
}
Edit
public void newSensor_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{
using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
{
if (skeletonFrame == null)
return;
GetSkeletons(skeletonFrame, ref skeletons);
if (skeletons.All(s => s.TrackingState == SkeletonTrackingState.NotTracked))
return;
//skeletonManager.Draw(skeletons);
}
foreach (Skeleton skeleton in skeletons)
{
if (skeleton.TrackingState == SkeletonTrackingState.Tracked)
{
Joint headJoint = skeleton.Joints[JointType.Head];
Joint hipCenter = skeleton.Joints[JointType.HipCenter];
headPosition = headJoint.Position;
this.headPoint.X = headPosition.X;
this.headPoint.Y = headPosition.Y;
this.headPoint.Z = headPosition.Z;
message = string.Format("Head: X:{0:0.0} Y:{1:0.0} Z:{2:0.0}",
headPoint.X,
headPoint.Y, headPoint.Z);
//MessageBox.Show(message);
this.HeadPosition.Text = message;
}
}
}
I can’t get the HeadPosition.Text update with the data.What actually happened?
kinect changed event handler at window A
private void sensorChooser_KinectChanged(object sender, KinectChangedEventArgs e)
{
KinectSensor oldSensor = (KinectSensor)e.OldSensor;
StopKinect(oldSensor);
KinectSensor newSensor = (KinectSensor)e.NewSensor;
if (newSensor == null)
{
return;
}
//Register for event and enable Kinect Sensor features you want
newSensor.DepthFrameReady += newSensor_DepthFrameReady;
newSensor.SkeletonFrameReady += mw.newSensor_SkeletonFrameReady;
//newSensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
newSensor.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30);
....
newSensor.SkeletonStream.Enable(parameter);
StartKinect(newSensor);
}
XAML____________________________________________________________
<Grid x:Name="firstGrid">
<Viewport3D x:Name="viewPort" Grid.Column="0" Grid.Row="0" ClipToBounds="False" Width="2048"
....
.....
</Viewport3D>
<TextBox x:Name="IndexPosition" HorizontalAlignment="Left" Height="23" Margin="485,2,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="69"/>
<TextBox x:Name="CameraPosition" HorizontalAlignment="Left" Height="23" Margin="570,2,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="142"/>
<TextBlock Name="HeadPosition" HorizontalAlignment="Left" Margin="492,23,0,0" Text="Text" VerticalAlignment="Top" Width="182" Height="29"
Foreground="Tomato" FontSize="20"/>
You can do this in one of many different ways. It all depends on how you want to seperate the code in your program.
Option 1: Public Event Handlers
You could set up public event handlers in
Window Bthat subscribe to theSkeletonFrameReadyevent from theKinectSensor. For example, in the class that sets up yourKinectSensoryou might have something like:Then in your
WindowBclass you would have the event callback:Option 2: Pass the Sensor
You could set up your window(s) to accept a reference to the
KinectSensor. When you open the second window from your main class, just pass the sensor in:With your constructor of
WindowBtaking aKinectSensorand then setting up the callback from above:Notice this allows your callback to be private.
Option 3: Using a Framework Messenger
You could also use a framework messenger, such as MVVM Light. MVVM Light provides a lightweight messenger system that allows you to easily pass objects around from one view to the the next. While this is more useful in a MVVM structured program that doesn’t mean you can’t use it outside one.
You can broadcast the entire
SkeletonFrameReadyEventArgsout from your main classesSkeletonFrameReadycallback:Then you just need to subscribe to it from you
WindowB:Or you could just send the individual
Skeleton, fromo your main class:Your
WindowBwould then register, as shown above, on aSkeletonFrameinstead of the event args. The callback would do what it needs to do with theSkeletonFrameobject.What’s Best?
Up to you. There are several other ways you could ultimately do this. These are the first three I thought of. They will all accomplish the same thing — you just want to use the one your are most comfortable with for your program style.
Maximizing the Window
To maximize the window, you can place a button in your XAML and setup a callback to toggle between the
MaximizedandNormalwindow state.XAML:
Code Behind: