C# Kinect 2.0 SDK 学习笔记(1)——彩色影像数据流

彩色影像数据流是Kinect摄像头最基本的数据,图像相当于一般的摄像头(废话)。

本节主要是获取Kinect摄像头的彩色影像数据,在Image控件上将其展示出来。


新建WPF项目KinectColorStreamTest

C# Kinect 2.0 SDK 学习笔记(1)——彩色影像数据流_第1张图片

通过Nuget添加Kinect的相关程序包

C# Kinect 2.0 SDK 学习笔记(1)——彩色影像数据流_第2张图片

这里简要说明下Kinect 2.0 SDK 的结构:

Microsoft Kinect 是基础API,所有的高级命名空间全都要基于此API,不区分X86和X64(好吧是我没仔细研究,我也不知道是不区分还是都基于X86的架构)

Microsoft Kinect Fusion 是3D扫描相关的API集合

Microsoft Kinect Face Tracking 顾名思义是面部识别相关的API集合

Microsoft Kinect WPF Controls 是基于WPF的手势控制API集合

剩下的没太深入研究,不敢下定论。

我们先从Microsoft Kinect 学起,在后面将接触3D扫描或面部识别相应的API


书归正传,添加好程序包后,在MainWindow.xaml.cs里引用一下:

using Microsoft.Kinect;


在MainWindow类下做几个声明:

        private KinectSensor kinect = null; //用来标记kinect摄像头的实例
        private ColorFrameReader colorFrame = null; //用来处理和保存摄像头传过来的彩色影像帧数据
        private WriteableBitmap colorBitmap = null; //用来向Image控件中填充彩色影像数据
        private FrameDescription colorFrameDescription = null; //用来描述彩色影响帧数据形态的参数


接下来,在窗口初始化前,要做一些数据绑定,添加监听事件,MainWindow方法的代码如下:

        public MainWindow()
        {
            this.kinect = KinectSensor.GetDefault(); //获取第一个或默认的Kinect摄像头
            this.colorFrame = kinect.ColorFrameSource.OpenReader(); //打开彩色影像数据的获取接口
            this.colorFrame.FrameArrived += colorFrame_FrameArrived; //建立监听事件,当有彩色影像数据帧到达时触发
            this.colorFrameDescription = this.kinect.ColorFrameSource.CreateFrameDescription(ColorImageFormat.Bgra); //按照Bgra格式设定数据帧的描述信息(B:Blue,G:Green,R:Red,A:Alpha)
            this.colorBitmap = new WriteableBitmap(colorFrameDescription.Width, colorFrameDescription.Height, 96.0, 96.0, PixelFormats.Bgr32, null); //根据数据帧的宽高创建colorBitmap的实例
            this.kinect.Open(); //启动kinect摄像头
            InitializeComponent();
        }


在这段代码中,展示了Kinect摄像头启动的一般历程:

捕获摄像头,打开数据接口,监听接口过来的数据并交由响应函数处理,启动摄像头。

下面来写colorFrame_FrameArrived函数,处理摄像头送过来的帧数据:

        void colorFrame_FrameArrived(object sender, ColorFrameArrivedEventArgs e)
        {
            using(ColorFrame frame=e.FrameReference.AcquireFrame()) //建立一个ColorFrame的实例frame保存送过来的帧,通过using保证走完函数后及时释放相应资源
            {

                this.colorBitmap.Lock(); //锁定一下数据文件,准备进行填充
                frame.CopyConvertedFrameDataToIntPtr(this.colorBitmap.BackBuffer, (uint)(this.colorFrameDescription.Width * this.colorFrameDescription.Height * 4), ColorImageFormat.Bgra);
                //提供给函数一个空间接收帧数据,将数据储存进colorBitmap的后台缓存中
                this.colorBitmap.AddDirtyRect(new Int32Rect(0, 0, this.colorBitmap.PixelWidth, this.colorBitmap.PixelHeight));
                //设定colorBitmap需要更改的位图区域,此处设定为整个图片
                this.colorBitmap.Unlock(); //解锁位图资源
            }
        }


colorFrame_FrameArrived处理了前面建立的监听事件给出的触发信号,将获取到的摄像头帧信息传给了colorBitmap。

接下来将colorBitmap展示到窗口,窗口新建一个Image控件,绑定一个ColorSource对象:

ColorSource的代码很简单,只有一个get:

        public ImageSource ColorSource
        {
            get
            {
                return this.colorBitmap;
            }
        }

代码结构就初步完成了,运行一下,可用!

C# Kinect 2.0 SDK 学习笔记(1)——彩色影像数据流_第3张图片

光着膀子就不露脸了,看看哥们的掌纹是不是有点乱?一千多的摄像头清晰度绝对够,1080p啊!

但是在关闭测试程序的时候,程序会报错:

C# Kinect 2.0 SDK 学习笔记(1)——彩色影像数据流_第4张图片

简单研究了下,是由于关闭程序的时候摄像头数据已中断,但又触发了之前建立的监听(this.colorFrame.FrameArrived),导致监听函数获取了一个空的帧数据,以致于报错,简单修改代码,在获取帧数据时增加一个判断frame!=null就可以了。

到这里,我们已经用Kinect摄像头获取到了最简单的彩色影像数据流,当然这只是最基本的,在实际应用中还要考虑摄像头突然掉线、上线以及内存占用等问题,在可靠性上再增加一些代码,尽量保证程序的可能性枚举与现实情况吻合,下一章就来讨论摄像头的工作状态变化获取及实际情况处理。

CS文件中的完整代码如下:

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 KinectColorStreamTest
{
    /// 
    /// MainWindow.xaml 的交互逻辑
    /// 
    public partial class MainWindow : Window
    {
        private KinectSensor kinect = null; //用来标记kinect摄像头的实例
        private ColorFrameReader colorFrame = null; //用来处理和保存摄像头传过来的彩色影像帧数据
        private WriteableBitmap colorBitmap = null; //用来向Image控件中填充彩色影像数据
        private FrameDescription colorFrameDescription = null; //用来描述彩色影响帧数据形态的参数

        public MainWindow()
        {
            this.kinect = KinectSensor.GetDefault(); //获取第一个或默认的Kinect摄像头
            this.colorFrame = kinect.ColorFrameSource.OpenReader(); //打开彩色影像数据的获取接口
            this.colorFrame.FrameArrived += colorFrame_FrameArrived; //建立监听事件,当有彩色影像数据帧到达时触发
            this.colorFrameDescription = this.kinect.ColorFrameSource.CreateFrameDescription(ColorImageFormat.Bgra); 
            //按照Bgra格式设定数据帧的描述信息(B:Blue,G:Green,R:Red,A:Alpha)
            this.colorBitmap = new WriteableBitmap(colorFrameDescription.Width, colorFrameDescription.Height, 96.0, 96.0, PixelFormats.Bgr32, null);
            //根据数据帧的宽高创建colorBitmap的实例
            this.kinect.Open(); //启动kinect摄像头
            this.DataContext = this;
            InitializeComponent();
        }
        void colorFrame_FrameArrived(object sender, ColorFrameArrivedEventArgs e)
        {
            using(ColorFrame frame=e.FrameReference.AcquireFrame()) //建立一个ColorFrame的实例frame保存送过来的帧,通过using保证走完函数后及时释放相应资源
            {
                if (frame != null)
                {
                    this.colorBitmap.Lock(); //锁定一下数据文件,准备进行填充
                    frame.CopyConvertedFrameDataToIntPtr(this.colorBitmap.BackBuffer, (uint)(this.colorFrameDescription.Width * this.colorFrameDescription.Height * 4), ColorImageFormat.Bgra);
                    //提供给函数一个空间接收帧数据,将数据储存进colorBitmap的后台缓存中
                    this.colorBitmap.AddDirtyRect(new Int32Rect(0, 0, this.colorBitmap.PixelWidth, this.colorBitmap.PixelHeight));
                    //设定colorBitmap需要更改的位图区域,此处设定为整个图片
                    this.colorBitmap.Unlock(); //解锁位图资源
                }
            }
        }
        public ImageSource ColorSource
        {
            get
            {
                return this.colorBitmap;
            }
        }
    }
}





你可能感兴趣的:(Kinect,2.0,SDK,C#,wpf,C#,kinect,microsoft)