C# kinect v2学习笔记(五)骨骼图像和彩色图像的叠加

      这次为大家带来骨骼和彩色图像的叠加,其实很简单,就是将获取的骨骼点对应到彩色图像上,方式用到以前的基础,还是老的步骤和调调!

      在实际运用中,最多的就是采用kinect v2的骨骼数据进行实际的交互了,十分有趣的东东。

      先取上骨骼类型,用于画骨骼图像;骨架图像的连接顺序为 主躯干->左手->右手->左脚->右脚 从SDK提供的骨架点构成数组存储,如下:

        private JointType[] _JointType = new JointType[]{
            JointType.SpineBase,JointType.SpineMid,
            JointType.SpineMid,JointType.SpineShoulder,
            JointType.SpineShoulder,JointType.Neck,
            JointType.Neck,JointType.Head,

            JointType.SpineShoulder,JointType.ShoulderLeft,
            JointType.ShoulderLeft,JointType.ElbowLeft,
            JointType.ElbowLeft,JointType.WristLeft,
            JointType.WristLeft,JointType.HandLeft,
            JointType.HandLeft,JointType.HandTipLeft,
            JointType.HandLeft,JointType.ThumbLeft,

            JointType.SpineShoulder,JointType.ShoulderRight,
            JointType.ShoulderRight,JointType.ElbowRight,
            JointType.ElbowRight,JointType.WristRight,
            JointType.WristRight,JointType.HandRight,
            JointType.HandRight,JointType.HandTipRight,
            JointType.HandRight,JointType.ThumbRight,

            JointType.SpineBase,JointType.HipLeft,
            JointType.HipLeft,JointType.KneeLeft,
            JointType.KneeLeft,JointType.AnkleLeft,
            JointType.AnkleLeft,JointType.FootLeft,

            JointType.SpineBase,JointType.HipRight,
            JointType.HipRight,JointType.KneeRight,
            JointType.KneeRight,JointType.AnkleRight,
            JointType.AnkleRight,JointType.FootRight
        };

构成了骨架后,打开kinect多种数据流模式,采用彩色和骨架数据流图像的叠加;打开方式可参照之前系列文章,或者微软的PPT。

 以下是处理画骨骼和显示彩色图像:

 //打开多种帧
            MultiSourceFrame msf = e.FrameReference.AcquireFrame();

            //不为空
            if (msf != null)
            {
                //打开骨骼帧和彩色帧
                using (BodyFrame bodyFrame = msf.BodyFrameReference.AcquireFrame())
                {
                    using (ColorFrame colorFrame = msf.ColorFrameReference.AcquireFrame())
                    {
                        //骨骼帧和彩色帧都不为空
                        if (bodyFrame != null && colorFrame != null)
                        {
                            //彩色帧拷贝到数组
                            colorFrame.CopyConvertedFrameDataToArray(this._ColorPixelData, ColorImageFormat.Bgra);

                            //数组写到位图
                            this._ColorBitmap.WritePixels(this._ColorBitmapRect, this._ColorPixelData, this._ColorBitmapStride, 0);

                            //骨骼数据拷贝到数组
                            bodyFrame.GetAndRefreshBodyData(this._Bodies);

                            //清空,保证每一帧都画一次
                            CanvasBody.Children.Clear();

                            
                            //画骨架
                            DrawBodies();

                        }
                    }
                }
            }
        }

        //画骨架,六个人
        private void DrawBodies()
        {
            //遍历6个玩家
            for (int i = 0; i < 6; i++)
            {
                if (this._Bodies[i].IsTracked == true)
                {
                    lState.Content = "状态"+this._Bodies[i].Joints[JointType.SpineBase].TrackingState.ToString();
                    Brush color = ColorBody[i % 6];
                    Body oneBody = this._Bodies[i];
                    //通过循环将关节点两两连接,
                    for (int j = 0; j < this._JointType.Length; j += 2)
                    {
                        Line line = new Line();
                        line.Stroke = color;
                        line.StrokeThickness = 5;

                        //起点的屏幕坐标和终点的屏幕坐标
                        Point StartP = GetJointPointScreen(oneBody.Joints[this._JointType[j]]);
                        Point EndP = GetJointPointScreen(oneBody.Joints[this._JointType[j + 1]]);

                        Ellipse sp = new Ellipse();
                        Ellipse ep = new Ellipse();

                        sp.Width = 15;
                        sp.Height = 15;
                        sp.HorizontalAlignment = HorizontalAlignment.Left;
                        sp.VerticalAlignment = VerticalAlignment.Top;
                        sp.Fill = Brushes.Red;
                        ep.Width = 15;
                        ep.Height = 15;
                        ep.HorizontalAlignment = HorizontalAlignment.Left;
                        ep.VerticalAlignment = VerticalAlignment.Top;
                        ep.Fill = Brushes.Red;

                        sp.Margin = new Thickness(StartP.X - sp.Width / 2, StartP.Y - sp.Height / 2, 0, 0);
                        ep.Margin = new Thickness(EndP.X - ep.Width / 2, EndP.Y - ep.Height / 2, 0, 0);

                        //设置起点、终点的坐标
                        line.X1 = StartP.X;
                        line.Y1 = StartP.Y;
                        line.X2 = EndP.X;
                        line.Y2 = EndP.Y;

                        //把起点、终点及连接添加到网格中。
                        CanvasBody.Children.Add(sp);
                        CanvasBody.Children.Add(ep);
                        CanvasBody.Children.Add(line);
                    }
                }
            }
以及坐标转换的处理:(用到SDK自带的coordinatemapping类)

最后,最最重要的是由于不同数据流之间的分辨率不同,要采取图像重合就必须进行坐标转换,以下将骨骼图像升为彩色图像的方式。

附:本应用建立在.net4.0 .net4.5,采用WPF编写; Kinect中图像在实际中相当于镜像关系,类似照镜子,骨架流中存储着很多信息,比如追踪状态等。


	    //骨骼坐标转化为彩色图像坐标
            ColorSpacePoint colorPoint = this._KinectDevice.CoordinateMapper.MapCameraPointToColorSpace(oneJoint.Position);

            //彩色图像坐标转化为屏幕坐标

            colorPoint.X = (int)((colorPoint.X * CanvasBody.Width) / 1920);
            colorPoint.Y = (int)((colorPoint.Y * CanvasBody.Height) / 1080);

            //返回Point类型变量
            return new Point(colorPoint.X, colorPoint.Y);


以下是部分效果图:C# kinect v2学习笔记(五)骨骼图像和彩色图像的叠加_第1张图片C# kinect v2学习笔记(五)骨骼图像和彩色图像的叠加_第2张图片



你可能感兴趣的:(C#,Kinect,v2)