【问题标题】:Drawing Lines Using Kinect v2 c# wpf使用 Kinect v2 c# wpf 绘制线条
【发布时间】:2016-03-21 03:12:24
【问题描述】:

我正在尝试使用我的 KINECT v2 右手提示位置在画布上绘制线条。我从这行代码中得到了我的右手提示位置。

CameraSpacePoint handtipPosition = handtip.Position;
ColorSpacePoint handtipPoint = _sensor.CoordinateMapper.MapCameraPointToColorSpace(handtipPosition);

这是我绘制线条的代码 sn-p,我已经定义了另一个点来将 X1 和 Y1 坐标提供给我的线条

ColorSpacePoint PreviousPoint;

      line.X1 = PreviousPoint.X; // ERROR 'Use of possibly Unassigned field X'   
      line.Y1 = PreviousPoint.Y; // ERROR 'Use of possibly Unassigned field Y'   
      line.X2 = handtipPoint.X;                                 
      line.Y2 = handtipPoint.Y;                            
      PreviousPoint = handtipPoint;                        
      canvas.Children.Add(line);

但是当我使用 PreviousPoint 为我的 X1 和 Y1 参数分配坐标时,我得到错误“使用可能未分配的字段 X”(我猜这是因为 PreviousPoint 在开始时没有值)并且如果我修复了 previousPoint 值对于 X 和 Y 到 0,在我的画布上,我从一个固定点 (0,0) 画线,因为只有 X2 和 Y2 跟随我的手位置。

请帮我纠正这种情况,感谢任何建议和帮助。

【问题讨论】:

  • 从您发布的小代码来看,错误是正确的:您声明了一个局部变量PreviousPoint,然后在初始化之前尝试使用它。如果没有一个好的minimal reproducible example,就不清楚你需要修复什么。如果您想要上一点,则需要将变量放在可以持续更长时间的地方(例如实例字段),将其初始化一次,然后在收到两个之前不要画线不同的点。我看不出这个问题与 Kinect 有什么关系。您从 Kinect API 获得积分似乎与实际问题无关。
  • 我希望只初始化一次previouspoint值,因为一开始它没有值。但是在事件处理程序触发后,kinect 传感器将提供关节位置,最终将填充上一个点。在那之前我只想实例化它一次,这样我就不会收到空对象错误。

标签: c# wpf canvas kinect lines


【解决方案1】:

我仍然不清楚这里的确切问题是什么。但是,根据您对另一个答案的评论,我在一小时前的评论中的猜测似乎是正确的。在那种情况下,这样的事情应该适合你:

class Form1 : Form // making assumption your code is in a Form
{
    ColorSpacePoint? PreviousPoint;

    // I have no idea what the actual event handler is supposed to look like.
    // This is just a wild guess based on the little bit of code you posted.
    void KinectEventHandler(object sender, KinectEventArgs handtip)
    {
        CameraSpacePoint handtipPosition = handtip.Position;
        ColorSpacePoint handtipPoint = _sensor.CoordinateMapper
            .MapCameraPointToColorSpace(handtipPosition);

        if (PreviousPoint != null)
        {
            ColorSpacePoint previousPointValue = (ColorSpacePoint)PreviousPoint;
            line.X1 = previousPointValue.X;
            line.Y1 = previousPointValue.Y;
            line.X2 = handtipPoint.X;                                 
            line.Y2 = handtipPoint.Y;                            
            canvas.Children.Add(line);
        }
        PreviousPoint = handtipPoint;                        
    }
}

上面声明了ColorSpacePoint 的“可空”实例,在事件处理程序方法之外。默认初始化为null。在事件处理程序中,仅当该值不仍为空时才添加一行,即已经接收到初始点。无论哪种情况,当前点都会替换PreviousPoint 的当前值,以便下次调用事件处理程序时可以使用该值。

请注意,我假设ColorSpacePoint 实际上是一个值类型(即struct)。我从您显示的错误消息中推断出这一点,它应该只来自值类型。但如果它是引用类型(即class),那么您不需要将该字段声明为“可为空”类型,因为引用类型已经可以为空。在这种情况下,您可以将该字段声明为ColorSpacePoint PreviousPoint,然后直接使用该字段(例如line.X1 = PreviousPoint.X;),而不是先将其复制到本地。

(实际上,您并不需要先将其复制到本地...您可以使用例如PreviousPoint.Value.X,但由于您要访问多个字段,我喜欢将其移动到本地变量清晰并减少对可空类型的访问)。

【讨论】:

  • 非常感谢彼得!这解决了问题!很抱歉没有提供足够的信息,我正在使用 wpf,是的,ColorSpacePoint 是一个结构,其中包含从传感器输入的 x 和 y 值。这解决了实例化问题,现在允许我在画布上绘图。我现在正在努力获得正确的坐标。非常感谢,非常感谢您抽出宝贵时间进行详细解释。一直很有帮助! @Nobody,也谢谢你
  • 很高兴您发现这个答案很有帮助。现在我对您要问的问题有了更好的了解:),我建议您返回并编辑您的帖子,以便代码示例提供更好的细节。特别要注意的是,当您提出问题时,您可以显示整个事件处理程序方法,并清楚地显示 PreviousPoint 变量声明的上下文,而不是将代码分成两个单独的部分,没有方法签名本身。这将大大有助于使问题更清晰。
【解决方案2】:

我假设绘制线条的代码在 KINECT 的事件处理程序中?如果是这样,只需在全局范围内实例化 PreviousPoint 对象。

public class whatever {

  private ColorSpacePoint PreviousPoint;
  // set the initial values, so you don't get a uninstantiated object error.
  PreviousPoint.X = 0; 
  PreviousPoint.Y = 0; 

  Private Void EventHandlerForMovingKinect(args e) {
    // If there is some sort of event handler that fires each time your move the kinect or whatever, we can put the rest of the code here.
    line.Y1 = PreviousPoint.Y;    
    line.X2 = handtipPoint.X;                                 
    line.Y2 = handtipPoint.Y;                            
    PreviousPoint = handtipPoint;                        
    canvas.Children.Add(line);
  }
}

显然,这是伪代码,这是我在没有更多实际代码的情况下能做的最好的事情。这应该可以防止您获取 null 对象,并且由于事件处理程序中的值没有被覆盖,因此值应该正确更新以绘制线条。

这些文章也可能有帮助:

understanding-kinect-coordinate-mapping/

kinect-painting-c-wpf-sdk-kinect

【讨论】:

  • 这是一个很好的答案,代码位于 Kinect 的事件处理程序中,其中获取身体框架并输入关节位置。您已经理解我的问题,我相信您的解决方案应该工作,但我把前三行实例化为这样的下一个Previouspoint - public partial class MainWindow : Window { private ColorSpacePoint PreviousPoint; PreviousPoint.X = 0; PreviousPoint.Y = 0; //其次是其他事件处理程序和成员变量声明我再次收到错误说在类结构或接口成员中无效令牌'='。跨度>
  • @Sda:您收到编译器错误,因为答案的作者没有费心编写有效的 C# 代码。您可以使用自己的 C# 知识将上述无效代码翻译成可以编译的东西,或者希望并等待作者修改答案。
  • 是的,对不起,我对 C# 还很陌生,我还在学习,感谢您提供建设性的反馈,我现在正在查找错误以修复它。我确实理解没人建议的解决方案,它完全有道理,目前正在尝试实施它并解决错误。谢谢@Peter。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-16
  • 1970-01-01
  • 2013-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多