Kinect学习笔记一ColorFrame

开发学习笔记(C#)第一篇

ColorFream的获取与显示

(找到的二代笔记居然是C++,可恶自己来写C#Code摘自SDK。来熟悉程序工作调用流程。 )(XXX?)皆为待议  若看代码底色不爽,剪切粘贴在txt,再粘回来,格式就取消了,是不是很神奇?

 

 

然而二代我找了半天楞没找到那个一代多个kinect遍历的东西的存在,战五渣不解释,以后发现了再补。

色彩图有RGB/YUV2种,Kinect V2 采用USB3.0Fps与质量都有提高。最高:1920*1080

从「Frame」取得Color图像的数据时,Kinect SDK v1是预先指定图像尺寸和格式Kinect SDK v2不能指定图像尺寸。因此,取得数据后可以按任意形状来整理。

 

数据流获取的两种模型

轮询模型:程序定期检查数据,若有帧数据返回,可请求下一帧。

事件模型:注册帧FrameReady事件,帧到达触发事件,调用事件的属性FrameReadyEventArgs来获得数据帧,但也要检查是否为空。本例采用事件模型。

 

直接上彩色帧读取显示代码(WPF项目):

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;//添加对Kinect对象的引用

引用空间不多介绍,在自动生成的上加了kinect 

 

 

namespace myKinectColorViewer

{

    /// <summary>

    /// MainWindow.xaml 的交互逻辑

    /// </summary>

    public partial class MainWindow : Window

    {

        private KinectSensor kinectSensor = null;

        private ColorFrameReader colorFrameReader = null;

        private WriteableBitmap colorBitmap = null;

        public MainWindow()

        {

            默认KinectSensor对象

            this.kinectSensor = KinectSensor.GetDefault();

            //ReaderForColor打开kinectsensor的色彩帧源的reader

            this.colorFrameReader = this.kinectSensor.ColorFrameSource.OpenReader();

            //注册色彩帧到达后的发生事件,绑定执行函数Reader_ColorFreamArrived

            this.colorFrameReader.FrameArrived += this.Reader_ColorFrameArrived;

            //获得对色彩帧的描述,以Rgba格式

            FrameDescription colorFrameDescription = this.kinectSensor.ColorFrameSource.CreateFrameDescription(ColorImageFormat.Bgra);

            //创造用于显示的bitmap,图宽,图高,水平/垂直每英寸像素点数,像素点格式,调色板为空?

            this.colorBitmap = new WriteableBitmap(colorFrameDescription.Width, colorFrameDescription.Height, 96.096.0PixelFormats.Bgr32, null);

            //Kinect传感器是否可用

            this.kinectSensor.Open();

            this.DataContext = this;//将此窗口对象作为视窗

            InitializeComponent();

        }

以上部分为初始化+事件触发执行方法

 

 

 

以下是Reader_ColorFrameArrived方法的构造

Using表示使用完就释放资源,从传来的色彩帧事件参数得到色彩帧,然后由FrameDescription得到对他的描述,

锁定位图数据

{用于处理。

将数据以所需格式拷至指定区域,

然后调用位图数据刷新(更改),

}

最后解锁

Imageource绑定输出。

在这里陈述下LockUnlock,是锁定数据用于某一线程,一定要解锁啊!

{}内具体是先通过把传来的色彩帧数据传到色彩位图的缓冲区,然后使用This.colorBitmap.AddDirtyRec()更新指定区域的色彩帧位图数据,Int32Recdt(x0,y0,width,height) 指定原点与宽高,确定矩形范围。

 

 

 

        private void Reader_ColorFrameArrived(object sender,ColorFrameArrivedEventArgs e)

        {

            using(ColorFrame colorFrame=e.FrameReference.AcquireFrame())

            {

                if(colorFrame!=null)

                {

                    FrameDescription colorFreamDescription = colorFrame.FrameDescription;

                    using(KinectBuffer colorBuffer=colorFrame.LockRawImageBuffer())

                    {

                        this.colorBitmap.Lock();

                        if((colorFreamDescription.Width==this.colorBitmap.PixelWidth)&&(colorFreamDescription.Height==this.colorBitmap.Height))

                        {

                            colorFrame.CopyConvertedFrameDataToIntPtr(

                                this.colorBitmap.BackBuffer,

                                (uint)(colorFreamDescription.Width * colorFreamDescription.Height * 4),

                                ColorImageFormat.Bgra);

                            this.colorBitmap.AddDirtyRect(new Int32Rect(00this.colorBitmap.PixelWidth, this.colorBitmap.PixelHeight));

                        }

                        this.colorBitmap.Unlock();

                    }

                }

            }

        }

 

 

以下为wpf的显示提供图源

        public ImageSource ImageSource

        {

            get

            {

                return this.colorBitmap;

            }

        }

 

以下为在窗口关闭后关闭传感与释放从传感器得到的数据,关闭之前先检查,变成好习惯。此段不多述。

        private void Window_Closed(object sender, EventArgs e)

        {

            if (this.colorFrameReader != null)

            {

                this.colorFrameReader.Dispose();

                this.colorFrameReader = null;

            }

            if (this.kinectSensor != null)

            {

                this.kinectSensor.Close();

                this.kinectSensor = null;

            }

        }

     

    }

}

 

 

效果图如下:

 


数据流程:

 

程序流程:

1.KinectSensor.open()开启传感器。

2.获取KinectSensor传感器对象,初始化

Reader FrameDescriptionbitmap、窗口、注册帧到达事件

3.打开对应的this.kinectSensor.ColorFrameSource.OpenReader(),选定所用的流,(说明Kinect V2会将流都扔给你。FrameDescription获得对色彩帧的描述,在这里是以何种格式。

4.注册色彩帧到达后的处理事件,绑定的方法要自己写,

5.使用WriteableBitmap初始化bitmap(提前),在4.的方法中画出相应的位图。

6.写返回BitmapImageSource函数,可用其他替带。

7.收尾,释放资源,KinectSensor.close()关闭传感器。

 

 

 

补充:

后续代码中附加计算显示FPS

取出的Color图像的数据如果指定的是BGRA格式就会像图一样的排列着。蓝(B)绿(G)(R)和无效值(A)的共计32bit构成1像素。

 

WriteableBitmap之于Bitmap,就好像StringBuilder之于String重写复制?。可以减少内存消耗。WriteableBitmap在初始化时需要指定高度,宽度和格式。

BitmapSource WPF中图片的核心类型所以在Mainwindows

        private void Window_Loaded(object sender, RoutedEventArgs e)

        {

            this.kinectSensor = KinectSensor.GetDefault();

            this.colorFrameReader = this.kinectSensor.ColorFrameSource.OpenReader();

            this.colorFrameReader.FrameArrived += this.Reader_ColorFrameArrived;

            FrameDescription colorFrameDescription = this.kinectSensor.ColorFrameSource.CreateFrameDescription(ColorImageFormat.Bgra);

            this.colorBitmap = new WriteableBitmap(colorFrameDescription.Width, colorFrameDescription.Height, 96.096.0PixelFormats.Bgr32, null);

            this.kinectSensor.Open();

            this.DataContext = this;

        } 

 

先调用构造函数MainWindow(),在窗体加载时才会引发MainWindow_Loaded()事件 WinForm 中的 Form_Load函数和他的构造函数

public Form()有区别: (1): public Form():程序入口,它的InitializeComponent为你的程序作了必要的初始化工作,所以Load才能成为一个事件, (2) Form_Load:装载窗口事件是窗体启动时触发的事件 总的来讲: 程序先执行InitializeComponent(); 后执行Form1_LoadInitializeComponent是进行一系列的初始化,Form1_Load是在窗体装载时发生的一个事件。

 

 

xaml添加部分的代码:

    <Grid>

        <Image  HorizontalAlignment="Left"

               Source="{Binding ImageSource}" Stretch="Fill" VerticalAlignment="Top" />

                <!--若变形严重修改stretch为Uniform-->

     </Grid>

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值