gpt4 book ai didi

c# - 将kinect骨架位置数据传递到另一个窗口

转载 作者:太空宇宙 更新时间:2023-11-03 11:11:45 25 4
gpt4 key购买 nike

我有两个不同的窗口,一个将在图像上显示流并计算用户的骨骼头部位置(窗口 A),另一个显示将使用骨骼数据缩放和平移的 3D 视觉模型(动画) (窗口 B)。

但是,我的问题是如何将这些骨骼头部位置数据从窗口 A 传递到窗口 B 并不断更新?我正在使用 WPF 和 M'soft Kinect SDK。我的另一个问题是如何在视觉模型上显示像按钮或菜单这样的控件,就我而言,模型填满了整个屏幕。

  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;

}

编辑


  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;
}
}
}

我无法使用数据更新 HeadPosition.Text。到底发生了什么?

kinect 在窗口 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"/>

最佳答案

您可以通过多种不同的方式之一来完成此操作。这完全取决于您希望如何分隔程序中的代码。

选项 1:公共(public)事件处理程序

您可以在 Window B 中设置公共(public)事件处理程序,从 KinectSensor 订阅 SkeletonFrameReady 事件。例如,在设置您的 KinectSensor 的类中,您可能有如下内容:

WindowB windowB = new WindowB();

private void InitializeKinectServices(KinectSensor sensor)
{
// some setup code

sensor.SkeletonFrameReady += windowB.OnSkeletonFrameReady;

// some more setup code
}

然后在您的 WindowB 类中您将有事件回调:

public void OnSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{
using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
{
// do what you need
}
}

选项 2:传递传感器

您可以设置您的窗口以接受对 KinectSensor 的引用。当您从主类打开第二个窗口时,只需将传感器传入:

WindowB windowB = new WindowB(sensor);

WindowB 的构造函数采用 KinectSensor,然后从上方设置回调:

public WindowB(KinectSensor sensor) {
sensor.SkeletonFrameReady += OnSkeletonFrameReady;
}

private void OnSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{
using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
{
// do what you need
}
}

请注意,这允许您的回调是私有(private)的。

选项 3:使用 Framework Messenger

您还可以使用框架信使,例如 MVVM Light . MVVM Light 提供了一个轻量级的信使系统,允许您轻松地将对象从一个 View 传递到另一个 View 。虽然这在 MVVM 结构化程序中更有用,但这并不意味着您不能在外部使用它。

您可以从主类 SkeletonFrameReady 回调中广播整个 SkeletonFrameReadyEventArgs:

private void OnSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{
Messenger.Default.Send<SkeletonFrameReadyEventArgs>(e);

// do more stuff
}

然后你只需要从你的 WindowB 订阅它:

public WindowB() {
Messenger.Default.Register<SkeletonFrameReadyEventArgs>(this, OnSkeletonFrameReady);
}

private void OnSkeletonFrameReady(SkeletonFrameReadyEventArgs e)
{
// do what you need with the event arg, just as you would in a regular callback
}

或者您可以从您的主类发送单独的 Skeleton:

private void OnSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{
using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
{
// do checks for capturing the appropriate skeleton.

Messenger.Default.Send<SkeletonFrame>(skeletonFrame);

// do more stuff if you need.
}
}

然后,您的 WindowB 将在 SkeletonFrame 而不是事件参数上注册,如上所示。回调将执行它需要对 SkeletonFrame 对象执行的操作。

什么是最好的?

由你决定。您可以通过其他几种方式最终做到这一点。这是我最先想到的三个。它们都将完成相同的事情——您只想使用最适合您的程序风格的那个。

最大化窗口

要最大化窗口,您可以在 XAML 中放置一个按钮并设置回调以在MaximizedNormal 窗口状态之间切换。

XAML:

<Button Click="MyButton_Click">Click Me</Button>

代码隐藏:

bool _isMaxed = false;
public void MyButton_Click(object sender, RoutedEventArgs e)
{
if (_isMaxed)
this.WindowState = WindowState.Normal;
else
this.WindowState = WindowState.Maximized;

_isMaxed = !_isMaxed;
}

关于c# - 将kinect骨架位置数据传递到另一个窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13759659/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com