kinect实现抓取功能

kinect实现抓取功能

          无意中发现kinectv2中骨骼中有这样有趣的一个现象,手部只要呈抓取状态,手部的节点就会改变颜色,比如从红色变成绿色等,当手部呈张开状态时候,手部节点颜色就会变回原来的颜色-红色。今天来试下这个功能,还蛮有趣的,不过kinect中判断手部的状态的函数是微软提供的,我们只是调用。
          当判断手部呈现一种状态时候,我们注册一个时间,比如:让手部变换颜色,或者画一个圆在手部节点等,都可以。然后手部状态回归原来的状态时,该事件取消。我们在上一篇博客的基础上来实现这个功能,并呈现出来。上一篇博客是关于彩色图像和骨骼图像叠加。
          微软中给了手部状态一个枚举类Handsate,其中有四个状态:
     public enum HandState
    {
        Unknown = 0,//未知状态
        NotTracked = 1,//存在但是没有追踪到
        Open = 2,//打开状态
        Closed = 3,//抓取状态
        Lasso = 4,//这个我也不懂,哈哈
    }
          我们定义一个该类,用于判断手部的状态;在实现当中我是这样的:
      if (handstate == HandState.Closed) {//判断手部状态是否为抓取状态,如果是的话,进行下面的操作:画一个比较大型的圆
          Point temp = getjointpointscreen(handrightpoint);
          Ellipse handrighttempcircle = new Ellipse() { Width = 150, Height = 150, Fill = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0)) };
          bodyimage.Children.Add(handrighttempcircle);
          Canvas.SetLeft(handrighttempcircle, temp.X-75);//添加到canvas空间里面
          Canvas.SetTop(handrighttempcircle, temp.Y-75);
           }
          手部原来的状态是:
      Point headpoint1 = getjointpointscreen(headpoint);
      Point handright = getjointpointscreen(handrightpoint);
      Ellipse headcircle = new Ellipse() { Width = 150,Height = 150,Fill = new SolidColorBrush(Color.FromArgb(255,255,0,0))};
      Ellipse handrightcircle = new Ellipse() { Width = 30, Height = 30, Fill = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0)) };
      bodyimage.Children.Add(headcircle);
      bodyimage.Children.Add(handrightcircle);
      Canvas.SetLeft(headcircle, headpoint1.X - 75);
      Canvas.SetTop(headcircle, headpoint1.Y - 75);
      Canvas.SetLeft(handrightcircle, handright.X - 15);
      Canvas.SetTop(handrightcircle, handright.Y - 15);
          手部的位置原来只是捕捉一个手指和手部,我在手指位置画一个比较小的圆,在手部位置画一个比较大的圆。之后如果手部状态发生改变的话,手部会变成一个特大的圆,可以从运行图中明显的看出来。其他的基本和上篇博客一样。
          全部的源代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Kinect;

namespace 彩色图像和骨架图像联合
{
    /// 
    /// MainWindow.xaml 的交互逻辑
    /// 
    public partial class MainWindow : Window
    {
        private KinectSensor kinect1 = null;
        private MultiSourceFrameReader color_bodyframe = null;
        private FrameDescription color_bodydescription = null;
        private WriteableBitmap bitmap = null;
        private Byte[] color_bodydata;
        private Body[] bodies;
        public MainWindow()
        {
            InitializeComponent();
            this.kinect1 = KinectSensor.GetDefault();
            this.color_bodyframe = this.kinect1.OpenMultiSourceFrameReader(FrameSourceTypes.Color | FrameSourceTypes.Body);
            this.color_bodydescription = this.kinect1.ColorFrameSource.CreateFrameDescription(ColorImageFormat.Bgra);
            this.color_bodydata = new Byte[this.color_bodydescription.LengthInPixels*4];
            this.bitmap = new WriteableBitmap(this.color_bodydescription.Width,this.color_bodydescription.Height,
                96.0,96.0,PixelFormats.Bgra32,null);
            this.bodies = new Body[6];
            this.color_bodyframe.MultiSourceFrameArrived += color_bodyframe_multisourcearrived;
            color_bodyimage.Source = this.bitmap;
            this.kinect1.Open();
        }

        private void color_bodyframe_multisourcearrived(object sender, MultiSourceFrameArrivedEventArgs e)
        {
            MultiSourceFrame msf = e.FrameReference.AcquireFrame();    
            if (msf != null) {
                using (BodyFrame bodyframe = msf.BodyFrameReference.AcquireFrame()) {
                    using (ColorFrame colorframe = msf.ColorFrameReference.AcquireFrame())
                    {
                        if (colorframe != null&&bodyframe!=null)
                        {
                            colorframe.CopyConvertedFrameDataToArray(this.color_bodydata, ColorImageFormat.Bgra);
                            bodyframe.GetAndRefreshBodyData(this.bodies);
                            bodyimage.Children.Clear();
                            foreach (Body body in bodies) {
                                if (body.IsTracked) {
                                    Joint headpoint = body.Joints[JointType.Head];
                                    Joint handtipright = body.Joints[JointType.HandTipRight];
                                    Joint handrightpoint = body.Joints[JointType.HandRight];
                                    HandState handstate = body.HandRightState;
                                    if (headpoint.TrackingState == TrackingState.Tracked)
                                    {
                                        Point headpoint1 = getjointpointscreen(headpoint);
                                        Point handright = getjointpointscreen(handrightpoint);
                                        Ellipse headcircle = new Ellipse() { Width = 150,Height = 150,Fill = new SolidColorBrush(Color.FromArgb(255,255,0,0))};
                                        Ellipse handrightcircle = new Ellipse() { Width = 30, Height = 30, Fill = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0)) };
                                        bodyimage.Children.Add(headcircle);
                                        bodyimage.Children.Add(handrightcircle);
                                        Canvas.SetLeft(headcircle, headpoint1.X - 75);
                                        Canvas.SetTop(headcircle, headpoint1.Y - 75);
                                        Canvas.SetLeft(handrightcircle, handright.X - 15);
                                        Canvas.SetTop(handrightcircle, handright.Y - 15);

                                        if (handstate == HandState.Closed) {
                                            Point temp = getjointpointscreen(handrightpoint);
                                            Ellipse handrighttempcircle = new Ellipse() { Width = 150, Height = 150, Fill = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0)) };
                                            bodyimage.Children.Add(handrighttempcircle);
                                            Canvas.SetLeft(handrighttempcircle, temp.X-75);
                                            Canvas.SetTop(handrighttempcircle, temp.Y-75);
                                        }
                                        
                                    }
                                    if (handtipright.TrackingState == TrackingState.Tracked) {
                                        Point handtip = getjointpointscreen(handtipright);
                                        Ellipse handtipcircle = new Ellipse() { Width = 10,Height = 10,Fill = new SolidColorBrush(Color.FromArgb(255,255,0,0))};
                                        bodyimage.Children.Add(handtipcircle);
                                        Canvas.SetLeft(handtipcircle,handtip.X-5);
                                        Canvas.SetTop(handtipcircle,handtip.Y-5);
                                    }
                                }
                            }
                            this.bitmap.WritePixels(new Int32Rect(0, 0, this.bitmap.PixelWidth, this.bitmap.PixelHeight),
                                this.color_bodydata, this.color_bodydescription.Width * 4, 0);
                        }
                    }
                }
            }
        }

        private Point getjointpointscreen(Joint headpoint)
        {
            ColorSpacePoint colorpoint = this.kinect1.CoordinateMapper.MapCameraPointToColorSpace(headpoint.Position);
            colorpoint.X = (int)((colorpoint.X * bodyimage.Width) / 1920);
            colorpoint.Y = (int)((colorpoint.Y * bodyimage.Height) / 1080);
            return new Point(colorpoint.X,colorpoint.Y);
        }

        private void Windows_closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (this.color_bodyframe != null) {
                this.color_bodyframe.Dispose();
                this.color_bodyframe = null;
            }
            if (this.kinect1 != null) {
                this.kinect1.Close();
                this.kinect1 = null;
            }
        }
    }
}
          代码的详细解释上篇有,这里我就不再重复了。
下面直接上运行图片:
张开图片:
kinect实现抓取功能_第1张图片
手部抓取的图片:
kinect实现抓取功能_第2张图片

          下一步准备将静态的圆通过手部抓取后能够移动,先试试。

你可能感兴趣的:(科研立项)