C# 在kinect类和opentk onrenderframe类之间共享值
我在应用程序中使用Kinect和C# 在kinect类和opentk onrenderframe类之间共享值,c#,kinect,opentk,C#,Kinect,Opentk,我在应用程序中使用Kinect和OpenTK。在一个类中,我使用WindowLoaded方法,该方法在循环中调用SensorSkeletonFrameReady并将右手的计算坐标写入控制台 在主窗口类中,我调用OnRenderFrame,它在循环中将立方体绘制到视口 所以基本上我需要将坐标从kinectControl中的SensorSkeletonFrameReady发送到主窗口类中的OnRenderFrame 我试着用线程来实现这一点,但我不知道如何发送值 编辑: 这是主窗口类:
OpenTK
。在一个类中,我使用WindowLoaded
方法,该方法在循环中调用SensorSkeletonFrameReady
并将右手的计算坐标写入控制台
在主窗口类中,我调用OnRenderFrame
,它在循环中将立方体绘制到视口
所以基本上我需要将坐标从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做些什么
就我个人而言,我使用follow核心结构
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工具包的一部分。使用上述方法,然后使用以下内容初始化my 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
}
#区域Kinect发现和设置
KinectSensorChanged上的私有无效(对象发送方,KinectSensorManagerEventArgs args)
{
if(null!=args.OldValue)
取消初始化KinectServices(args.OldValue);
if(null!=args.NewValue)
初始化KinectServices(KinectSensorManager,args.NewValue);
}
///
///初始化基于Kinect的服务。
///
///
///
private void InitializeKinectServices(Kinect传感器管理器Kinect传感器管理器,Kinect传感器)
{
//配置颜色流
kinectSensorManager.ColorFormat=ColorImageFormat.RgbResolution640x480Fps30;
kinectSensorManager.ColorStreamEnabled=true;
//配置深度流
kinectSensorManager.DepthStreamEnabled=true;
kinectSensorManager.TransformSmoothParameters=
新参数
{
//随着平滑值的增加,对原始数据的响应性增强
//减少;因此,增加平滑会导致延迟增加。
平滑度=0.5f,
//值越高,对原始数据的校正速度越快,
//值越小,校正速度越慢,看起来越平滑。
修正值=0.5f,
//要预测未来的帧数。
预测值=0.5f,
//确定从原始数据中删除抖动的力度。
吉特拉迪乌斯=0.05f,
//过滤位置可能偏离原始数据的最大半径(米)。
最大偏差半径=0.04f
};
//配置骨架流
sensor.SkeletonFrameReady+=OnSkeletonFrameReady;
kinectSensorManager.SkeletonStreamEnabled=true;
//初始化手势识别器
_gestureController=新的gestureController();
_gestureController.GestureReceignized+=OnGestureReceignized;
kinectSensorManager.KinectSensorEnabled=true;
如果(!kinectSensorManager.KinectSensorAppConflict)
{
//更多初始化
}
}
///
///取消初始化在InitializeKinect services中初始化的所有Kinect服务。
///
///
private void取消初始化Kinect服务(Kinect传感器)
{
//注销服务
}
在这里的示例代码中,我定义了一个SkeletonFrameReady
事件。这对于任何其他FrameReady
事件都是相同的。您可以设置适当的处理程序来获取数据,然后对其执行所需的操作。现在,您进入了OpenTK引用所在的主类
UI线程上发生的唯一事情是处理程序函数中的内容,或者它调用的内容。您能在这里发布您正在讨论的适用代码吗?在循环中使用
SensorSkeletonFrameReady
没有意义——这是一个事件。您可以在与您的OnRenderFrame
相同的类中跟踪SensorSkeletonFrameReady
事件。有一些代码来查看您的逻辑将有助于理解您的最终目标。是的,您是对的,这是事件而不是循环,我错了。我的简短回答是,Kinect处理不需要在自己的线程中。看看Kinect for Windows工具包中的所有示例——没有一个使用线程,因为所有处理都已在UI线程之外完成;这些事件允许您捕获信息并在UI线程上进行处理。我很快会得到一个更详细的答案。