在kinect类和opentk onrenderframe类之间共享值
本文关键字:之间 共享 onrenderframe kinect 类和 opentk | 更新日期: 2023-09-27 17:53:58
我在我的应用程序中使用Kinect和OpenTK
。在一个类中,我使用WindowLoaded
方法,它在循环中调用SensorSkeletonFrameReady
并写入控制台计算的右手坐标。
在主窗口类中,我调用OnRenderFrame
,它在循环中将立方体绘制到viewport。
所以基本上我需要将坐标从kinectControl中的SensorSkeletonFrameReady
发送到主窗口类中的OnRenderFrame
。
我尝试用线程完成这个,但是我不知道如何发送值。
编辑:这是主窗口类:
...
public class MainWindow : GameWindow
{
...
/*Kinect thread start*/
kinectControl kinectObject = new kinectControl();
Thread oThread = new Thread(new ThreadStart(kinectObject.WindowLoaded));
oThread.Start();
...
protected override void OnRenderFrame(FrameEventArgs e)
{
...
//Here I need get coordinates from kinectControl
DrawCube();
...
这是kinectControl类:
...
private void SensorSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{
...
foreach (Skeleton skeleton in skeletons)
{
Joint rightHand = skeleton.Joints[JointType.HandRight];
Joint leftHand = skeleton.Joints[JointType.HandLeft];
Joint head = skeleton.Joints[JointType.Head];
double leftY = leftHand.Position.Y;
double headY = head.Position.Y;
// get the individual points of the right hand
double rightX = rightHand.Position.X;
double rightY = rightHand.Position.Y;
double rightZ = rightHand.Position.Z;
//here I need send this coordinates to mainwindow class
…
Edit2:我找到了解决方案,而不是注册事件,我在OnRenderFrame方法中使用OpenNextFrame方法进行轮询。
public void findSkeleton()//random name of function
{
Skeleton[] skeletons = new Skeleton[0];
SkeletonFrame skeletonFrame = this.sensor.SkeletonStream.OpenNextFrame(0);
if (skeletonFrame != null)
{
skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
skeletonFrame.CopySkeletonDataTo(skeletons);
}
...//rest is the same as in SensorSkeletonFrameReady event
轮询是一种选择,但我仍然不清楚是否有必要将Kinect代码放在一个单独的线程中。所有由Kinect完成的轮询和处理都是在UI线程之外完成的,只有当你捕捉到一个FrameReady
事件时,你才会将UI线程带入其中。当你捕获那个事件时,你通常会想要用UI做一些事情。
private readonly KinectSensorChooser _sensorChooser = new KinectSensorChooser();
public MainViewModel()
{
KinectSensorManager = new KinectSensorManager();
KinectSensorManager.KinectSensorChanged += OnKinectSensorChanged;
_sensorChooser.Start();
if (_sensorChooser.Kinect == null)
{
MessageBox.Show("Unable to detect an available Kinect Sensor");
Application.Current.Shutdown();
}
// Bind the KinectSensor from the sensorChooser to the KinectSensor on the KinectSensorManager
var kinectSensorBinding = new Binding("Kinect") { Source = _sensorChooser };
BindingOperations.SetBinding(this.KinectSensorManager, KinectSensorManager.KinectSensorProperty, kinectSensorBinding);
}
KinectSensorManager
是KinectWpfViewers
示例项目中的辅助函数;Kinect for Windows工具包的一部分。使用上面的方法,我的Kinect会被初始化如下:
#region Kinect Discovery & Setup
private void OnKinectSensorChanged(object sender, KinectSensorManagerEventArgs<KinectSensor> args)
{
if (null != args.OldValue)
UninitializeKinectServices(args.OldValue);
if (null != args.NewValue)
InitializeKinectServices(KinectSensorManager, args.NewValue);
}
/// <summary>
/// Initialize Kinect based services.
/// </summary>
/// <param name="kinectSensorManager"></param>
/// <param name="sensor"></param>
private void InitializeKinectServices(KinectSensorManager kinectSensorManager, KinectSensor sensor)
{
// configure the color stream
kinectSensorManager.ColorFormat = ColorImageFormat.RgbResolution640x480Fps30;
kinectSensorManager.ColorStreamEnabled = true;
// configure the depth stream
kinectSensorManager.DepthStreamEnabled = true;
kinectSensorManager.TransformSmoothParameters =
new TransformSmoothParameters
{
// as the smoothing value is increased responsiveness to the raw data
// decreases; therefore, increased smoothing leads to increased latency.
Smoothing = 0.5f,
// higher value corrects toward the raw data more quickly,
// a lower value corrects more slowly and appears smoother.
Correction = 0.5f,
// number of frames to predict into the future.
Prediction = 0.5f,
// determines how aggressively to remove jitter from the raw data.
JitterRadius = 0.05f,
// maximum radius (in meters) that filtered positions can deviate from raw data.
MaxDeviationRadius = 0.04f
};
// configure the skeleton stream
sensor.SkeletonFrameReady += OnSkeletonFrameReady;
kinectSensorManager.SkeletonStreamEnabled = true;
// initialize the gesture recognizer
_gestureController = new GestureController();
_gestureController.GestureRecognized += OnGestureRecognized;
kinectSensorManager.KinectSensorEnabled = true;
if (!kinectSensorManager.KinectSensorAppConflict)
{
// more initialization
}
}
/// <summary>
/// Uninitialize all Kinect services that were initialized in InitializeKinectServices.
/// </summary>
/// <param name="sensor"></param>
private void UninitializeKinectServices(KinectSensor sensor)
{
// unregister services
}
在我的示例代码中,我定义了一个SkeletonFrameReady
事件。这对于任何其他FrameReady
事件都是相同的。您可以设置适当的处理程序来获取数据,然后对数据执行需要执行的操作。你现在处于OpenTK引用所在的主类中。
UI线程上唯一发生的事情是你的handler函数内部发生的事情,或者它调用的东西。