如何合并 3 个关节并将图像叠加到其上,以便图像旋转

How merge 3 joints and overlay a image onto it so that image rotates

我使用 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 中解释的代码,但没有成功...

lets assume if we overlay the image on top of any block how it show how it will rotate 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
}

您可以使用以下算法:

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);

您的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);
                }
            }
        }
    }