2

2 つの異なるウィンドウがあります。1 つは画像にストリームを表示し、ユーザーのスケルトンの頭の位置を計算します (ウィンドウ A)。もう 1 つは、スケルトン データを使用してズームと変換 (アニメーション) を行う 3D ビジュアル モデルを表示します (ウィンドウ B)。 )。

しかし、私の問題は、これらのスケルトンの頭の位置データをウィンドウ A からウィンドウ B に渡し、更新し続けるにはどうすればよいでしょうか? 私は WPF と M'soft Kinect SDK を使用しています。もう 1 つの質問は、ビジュアル モデルにボタンやメニューなどのコントロールを表示するにはどうすればよいかということです。私の場合、モデルは画面全体に表示されます。

  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"/>
4

2 に答える 2

2

これは、さまざまな方法の1つで実行できます。それはすべて、プログラム内のコードをどのように分離するかによって異なります。

オプション1:パブリックイベントハンドラー

からイベントWindow Bをサブスクライブするパブリックイベントハンドラーを設定できます。たとえば、あなたを設定するクラスでは、次のようなものがあります。SkeletonFrameReadyKinectSensorKinectSensor

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。メインクラスから2番目のウィンドウを開くときは、センサーを次の場所に渡すだけです。

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

これにより、コールバックをプライベートにすることができます。

オプション3:フレームワークメッセンジャーを使用する

MVVMLightなどのフレームワークメッセンジャーを使用することもできます。MVVM Lightは、あるビューから次のビューにオブジェクトを簡単に渡すことができる軽量のメッセンジャーシステムを提供します。これはMVVM構造化プログラムでより便利ですが、それ以外では使用できないという意味ではありません。

SkeletonFrameReadyEventArgsメインクラスのSkeletonFrameReadyコールバックから全体をブロードキャストできます。

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ます。

何が一番?

君による。最終的にこれを行うことができる他のいくつかの方法があります。これらは私が考えた最初の3つです。それらはすべて同じことを達成します-あなたはあなたのプログラムスタイルのためにあなたが最も快適なものを使いたいだけです。

ウィンドウの最大化

ウィンドウを最大化するには、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;
}
于 2012-12-07T17:34:29.703 に答える
0
  1. スケルトンを2番目のウィンドウ(コンストラクターなど)に渡し、そのOnHeadPositionChanged-Eventを使用できます。

  2. xamlにコントロールを追加して、のようMargin="0,10,0,10"に修正位置を設定するか、Canvasを親として使用して、を介して位置を設定するだけCanvas.Top="0" Canvas.Left="20"です。

于 2012-12-07T09:35:29.493 に答える