Я создал приложение Kinect, используя WPF и Microsoft Kinect SDK v2.

Я успешно отобразил изображение на всех точках соединения, используя следующий код:

// 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) по моему мнению и наложить на них изображение, чтобы изображение вращалось в соответствии с изменением положения суставов.

Я попытался использовать код, описанный в этой статье, но безуспешно ...

Предположим, если мы наложим изображение поверх любого блока, как оно отображается как он будет вращаться 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
Neo 27 Фев 2016 в 15:07

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);
                }
            }
        }
    }
1
Vangos 4 Мар 2016 в 21:19

Вы можете использовать следующий алгоритм:

1) Найдите угол между стыками (код).

using LightBuzz.Vitruvius;

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

2) Добавьте RotateTransform к желаемому изображению и поверните изображение в соответствии с рассчитанным вами углом.

img.RenderTransformOrigin = new Point(0.5, 0.5);
img.RenderTransform = new RotateTransform(angle);
2
Vangos 1 Мар 2016 в 17:23