【问题标题】:How merge 3 joints and overlay a image onto it so that image rotates如何合并 3 个关节并在其上叠加图像以使图像旋转
【发布时间】:2016-03-05 05:19:43
【问题描述】:

我使用 WPF 和 Microsoft Kinect SDK v2 创建了一个 Kinect 应用程序。

我已使用以下代码成功在所有关节点上显示图像:

// Draw
 if (joint.JointType == JointType.SpineShoulder)
                                {
var bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.UriSource = new Uri(@"C:\Users\myimage.jpg", UriKind.Relative);
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.EndInit();
var img = new Image { Source = bitmap, Height = 50, Width = 50 };
Canvas.SetLeft(img, point.X - img.Width / 2);
Canvas.SetTop(img, point.Y - img.Height / 2);
canvas.Children.Add(img);}

现在不是每个关节上的图像,我想合并 3 个关节 (spine_shoulder - center joint , shoulder right , shoulder left) 这是我的意见并将图像叠加到它们上,以便图像根据关节位置的变化进行旋转。

我尝试使用this article 中解释的代码,但没有运气......

让我们假设如果我们将图像覆盖在任何块的顶部,它会如何显示 它将如何旋转https://www.youtube.com/watch?v=pAljofdcMw8

按照@Vangos 的建议,我尝试如下

 public partial class Window1 : Window
{
    public static ObservableCollection<string> selectedImg = new ObservableCollection<string>();

    KinectSensor _sensor;
    MultiSourceFrameReader _reader;
    IList<Body> _bodies;

    private static string imagepath = @"C:\Users\demo.png";
    CameraMode _mode = CameraMode.Color;

    public Window1()
    {
        InitializeComponent();
        imageItems.ItemsSource = Page1.folders;
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        _sensor = KinectSensor.GetDefault();

        if (_sensor != null)
        {
            _sensor.Open();

            _reader = _sensor.OpenMultiSourceFrameReader(FrameSourceTypes.Color | FrameSourceTypes.Depth | FrameSourceTypes.Infrared | FrameSourceTypes.Body);
            _reader.MultiSourceFrameArrived += Reader_MultiSourceFrameArrived;
        }
    }       

    void Reader_MultiSourceFrameArrived(object sender, MultiSourceFrameArrivedEventArgs e)
    {
        var reference = e.FrameReference.AcquireFrame();

        // Body
        using (var frame = reference.BodyFrameReference.AcquireFrame())
        {
            if (frame != null)
            {
                canvas.Children.Clear();

                _bodies = new Body[frame.BodyFrameSource.BodyCount];

                frame.GetAndRefreshBodyData(_bodies);

                foreach (var body in _bodies)
                {
                    if (body.IsTracked)
                    {
                        // COORDINATE MAPPING
                        foreach (Joint joint in body.Joints.Values)
                        {
                            if (joint.TrackingState == TrackingState.Tracked)
                            {
                                // 3D space point
                                CameraSpacePoint jointPosition = joint.Position;

                                // 2D space point
                                Point point = new Point();

                                if (_mode == CameraMode.Color)
                                {
                                    ColorSpacePoint colorPoint = _sensor.CoordinateMapper.MapCameraPointToColorSpace(jointPosition);

                                    point.X = float.IsInfinity(colorPoint.X) ? 0 : colorPoint.X;
                                    point.Y = float.IsInfinity(colorPoint.Y) ? 0 : colorPoint.Y;
                                }
                                else if (_mode == CameraMode.Depth || _mode == CameraMode.Infrared) // Change the Image and Canvas dimensions to 512x424
                                {
                                    DepthSpacePoint depthPoint = _sensor.CoordinateMapper.MapCameraPointToDepthSpace(jointPosition.);

                                    point.X = float.IsInfinity(depthPoint.X) ? 0 : depthPoint.X;
                                    point.Y = float.IsInfinity(depthPoint.Y) ? 0 : depthPoint.Y;
                                }


                                //// Draw a images based on joint type

                                JointType _start = JointType.SpineShoulder;
                                JointType _center = JointType.ShoulderRight;
                                JointType _end = JointType.ShoulderLeft;


                                if (joint.JointType == JointType.SpineShoulder)
                                {
                                    var bitmap = new BitmapImage();
                                    bitmap.BeginInit();
                                    bitmap.UriSource = new Uri(imagepath, UriKind.Relative);
                                    bitmap.CacheOption = BitmapCacheOption.OnLoad;
                                    bitmap.EndInit();
                                    var img = new Image { Source = bitmap, Height = 50, Width = 50 };
                                    //Add a RotateTransform
                                    img.RenderTransformOrigin = new Point(0.5, 0.5);
                                    double angle = Extension.Angle(body.Joints[_start], body.Joints[_center], body.Joints[_end]);
                                    img.RenderTransform = new RotateTransform(angle);
                                    Canvas.SetLeft(img, point.X - img.Width / 2);
                                    Canvas.SetTop(img, point.Y - img.Height / 2);
                                    canvas.Children.Add(img);
                                }

                            }
                        }
                    }
                }
            }
        }
    }    
}


enum CameraMode
{
    Color,
    Depth,
    Infrared
}

【问题讨论】:

  • @Vito Gentile 你能帮帮我吗?

标签: c# wpf c#-4.0 kinect kinect-sdk


【解决方案1】:

您可以使用以下算法:

1) 求关节之间的角度 (code)。

using LightBuzz.Vitruvius;

double angle = joint1.Angle(joint2, joint3);

2) 给想要的图片添加一个RotateTransform,根据你计算的角度旋转图片。

img.RenderTransformOrigin = new Point(0.5, 0.5);
img.RenderTransform = new RotateTransform(angle);

【讨论】:

  • 感谢我对.this 很陌生。我可以使用我的代码提供示例代码吗?
  • 使用我发给你的代码作为角度。然后将关于img的两行复制并粘贴到canvas.Children.Add行下方。
  • 更多帮助请`角度(这个关节中心,关节开始,关节结束)`我应该在这里考虑哪个关节(我的问题中的单个关节)以及如何传递值?
  • 您需要使用 LightBuzz.Vitruvius。检查更新的回复。
  • 你需要为每一帧设置渲染变换,只要你有身体数据。它应该可以工作。
【解决方案2】:

您的 XAML 代码:

<Grid>
    <Canvas Name="canvas" Width="1920" Height="1080">
        <Image Name="img" Width="50" Height="50" />
    </Canvas>
</Grid>

您的事件处理程序:

    void Reader_MultiSourceFrameArrived(object sender, MultiSourceFrameArrivedEventArgs e)
    {
        var reference = e.FrameReference.AcquireFrame();

        using (var frame = reference.BodyFrameReference.AcquireFrame())
        {
            if (frame != null)
            {
                var body = frame.Bodies().Closest();

                if (body != null)
                {
                    JointType _start = JointType.SpineShoulder;
                    JointType _center = JointType.ShoulderRight;
                    JointType _end = JointType.ShoulderLeft;

                    double angle = body.Joints[_center].Angle(body.Joints[_start], body.Joints[_end]);

                    Point point = new Point();
                    ColorSpacePoint colorPoint = _sensor.CoordinateMapper.MapCameraPointToColorSpace(body.Joints[_center].Position);
                    point.X = float.IsInfinity(colorPoint.X) ? 0 : colorPoint.X;
                    point.Y = float.IsInfinity(colorPoint.Y) ? 0 : colorPoint.Y;

                    img.Source = new BitmapImage(new Uri("your-image-path", UriKind.RelativeOrAbsolute));
                    img.RenderTransformOrigin = new Point(0.5, 0.5);
                    img.RenderTransform = new RotateTransform(angle);

                    Canvas.SetLeft(img, point.X - img.Width / 2);
                    Canvas.SetTop(img, point.Y - img.Height / 2);
                }
            }
        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-30
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多