Search code examples
c#wpfc#-4.0kinectkinect-sdk

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


I have created a Kinect app using WPF and Microsoft Kinect SDK v2.

I have successfully displayed an image on all joint points using the following code:

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

Now instead of an image on each joint, I want to merge 3 joints (spine_shoulder - center joint , shoulder right , shoulder left) its my opinion and overlay an image onto them, so that image rotates according to how joint positions change.

I tried using the code explained in this article, with no luck...

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

As suggested by @Vangos I tried like below

 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
}

Solution

  • Your XAML code:

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

    Your Event Handler:

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