`
什么世道
  • 浏览: 219284 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

Kinect开发之获取彩色摄像头数据

阅读更多

 

 

 刚接触到Kinect,简要地介绍一下其摄像头相关的结构功能;

 

    Kinect 有两类摄像头,近红外摄像头和普通的视频摄像头。视频摄像头提供了一般摄像

 

头类似的彩色影像。这种数据流是三中数据流中使用和设置最简单的。因此我也最先接触彩色摄

 

像头

 

    使用Kinect 数据流也有三部。首先是数据流必须可用。一旦数据流可用,应用程序就

 

可以从数据量中读取数据并对数据进行处理和展现。一旦有新的数据帧可用,这两个步骤就

 

会一直进行,下面的代码展现了如何初始化ColorImage 对象。

 

  public KinectSensor Kinect
        {
            get { return this.kinect; }
            set
            {
                //如果带赋值的传感器和目前的不一样
                if (this.kinect != value)
                {
                    //如果当前的传感对象不为null
                    if (this.kinect != null)
                    {
                        
                        //uninitailize 当前对象
                        this.kinect = null;
                    }//如果传入的对象不为空,且状态为连接状态
                    if (value != null && value.Status == KinectStatus.Connected)
                    {
                        this.kinect = value;
                       
                    }
                }
            }
        }

 

 

 

      标记红色的两行调用了两个方法,分别初始化和释放KinectSensor 和ColorImageStream 对象。

 

InitializeKinectSensor对象调用ColorImageStream 的Enable 方法,注册ColorFrameReady 事件并调用

 

start 方法。

 

一旦打开了传感器,当新数据帧大道是就会触发frameready 事件,该事件触发频率是每秒30次。

 

 

 

	//初始化Kinect对象
        private void InitializeKinectSensor(KinectSensor kinectSensor)
        {
            if (kinectSensor != null)
            {
                kinectSensor.ColorStream.Enable();
                kinectSensor.ColorFrameReady += new EventHandler<ColorImageFrameReadyEventArgs>;(kinectSensor_ColorFrameReady);
                kinectSensor.Start();
            }
        }

 

 

 

 

 

	//未初始化Kinect对象
        private void UninitializeKinectSensor(KinectSensor kinectSensor)
        {
            if (kinectSensor != null)
            {
                kinectSensor.Stop();
                kinectSensor.ColorFrameReady -= new
                EventHandler<ColorImageFrameReadyEventArgs>;(kinectSensor_ColorFrameReady);
            }
        }

 

 

 

 

在实现Kinect_ColorFrameReady 方法前,我们先在XAML 窗体中添加一些空间来展现获取

 

到的数据,代码如下:

 

 

 

	<Window x:Class="KinectWPF.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525";
   Grid>;
        <Image x:Name="ColorImageElement">;</Image>;
    </Grid>;
</Window>;

 

 

 

 

然后,在Kinect_ColorFrameReady 方法中,我们首先通过打开或者获取一个frame 来提

 

取获Frame 数据。ColorImageFrameReadyEventArgs 对象的OpenColorImageFrame 属性返回

 

一个当前的ColorImageFrame 对象。这个对象实现了IDisposable 接口。所以可以将这个对

 

象抱在using 语句中的原因,在提取像素数据之前需要使用一个Byte 数组保存获取到的数据

FrameObject 对象的PixelDataLength 对象返回数据和序列的具体大小。调用CopyPixelDataTo

 

方法可以填充像素数据,然后将数据展示到image 控件上,具体代码如下:

 

 

      

  /// <summary>;
        /// 将获取的图像在窗体上显示出来
        /// </summary>;
        /// <param name="sender">;</param>;
        /// <param name="e">;</param>;
        void kinectSensor_ColorFrameReady(object sender,
            ColorImageFrameReadyEventArgs e)
        {
            using (ColorImageFrame frame = e.OpenColorImageFrame())
            {
                if (frame != null)
                {
                    byte[] pixelData = new byte[frame.PixelDataLength];
                    frame.CopyPixelDataTo(pixelData);
                    ColorImageElement.Source = BitmapImage.Create(frame.Width,
                    frame.Height, 96, 96, PixelFormats.Bgr32,
                    null, pixelData, frame.Width * frame.BytesPerPixel);
                }
            }
        }

 

 

 

 

如果需要运行获取视频信息,还需要加上以下一段代码:

 

 

首先创建一个WPF 应用程序来展示如何发现,获取Kinect 传感器的状态。先建

 

按一个WPF 项目,并添加Microsoft.Kinect.dll。写上加上以上的代码就OK啦~~~。

 

 

主窗体

      

 public MainWindow()
        {
            InitializeComponent();
            this.Loaded += (s, e) =>; DiscoverKinectSensor();
            this.Unloaded += (s, e) =>; this.kinect = null;

        }

 

 

 

 

 

获取Kinect 传感器的状态

 

 

//搜索Kinect设备        
private void DiscoverKinectSensor()
        {
            KinectSensor.KinectSensors.StatusChanged += KinectSensors_StatusChanged;
            this.Kinect = KinectSensor.KinectSensors.FirstOrDefault(x =>; x.Status == KinectStatus.Connected);
        }

 

 

 

 

       

 //KinectSensor连接的状态
        private void KinectSensors_StatusChanged(object sender, StatusChangedEventArgs e)
        {
            switch (e.Status)
            {
                case KinectStatus.Connected:
                    if (this.kinect == null)
                        this.kinect = e.Sensor;
                    break;
                case KinectStatus.Disconnected:
                    if (this.kinect == e.Sensor)
                    {
                        this.kinect = null;
                        this.kinect = KinectSensor.KinectSensors.FirstOrDefault(x =>; x.Status == KinectStatus.Connected);
                        if (this.kinect == null)
                        {
                            //TODO:通知用于Kinect已拔出
                        }
                    }
                    break;
                //TODO:处理其他情况下的状态
            }
        }

 

 

 

 

在构造函数中有两个匿名方法,一个用来监听Loaded 事件,一个用来监听Unloaded 事

 

件。当卸载时应该将Kinect 属性置为空。在窗口的Loaded 事件中程序通过

 

DiscoverKinectSensor 方法试图调用一个连接了的传感器。在窗体的Loaded 和Unloaded 事

 

件中注册这两个事件用来初始化和释放Kinect 对象,如果应用程序没有找到Kinect 对象,

 

将会通知用户。

 

DiscoverKinectSensor 方法只有两行代码,第一行代码注册StatusChanged 事件,第二行

 

代码通过lambda 表达式查询集合中第一个处在Connected 状态的传感器对象,并将该对象

 

复制给Kinect 属性。Kinect 属性的set 方法确保能都赋值一个合法的Kinect 对象。

 

StatusChanged 事件中值得注意的是,当状态为KinectSensor.Connected 的时候,if 语句限

 

制了应用程序只能有一个kinect 传感器,他忽略了电脑中可能连接的其他Kinect 传感器。

 

运行程序,就能得到从Kinect 获取的视频信息,如下图所示这是从Kinect 彩色摄像头

 

获取的我寝室的照片。和一般的视频没什麽两样,只不过这个是从Kinect 的视频摄像头产

 

 



 

 

小花絮:开始用VS 建工程写C#真的挺麻烦的,很多语法不太清楚,特别是WPF,后来一步一步

 

搜索讨论慢慢熟悉了,这不是主要问题,更主要的是Kinect硬件与电脑连接始终不稳定,特别

 

是之前该开始运行的时候连接了电脑没有反应,一开始以为代码的问题引用胡(啊)哥的那段

 

代码监控双手的动作的代码,我想这下应该不会有问题了吧!!!结果会抛

 

InvalidOperationException 异常。反复观察了下发现Kinect硬件的绿色的灯居然没有

 

亮!!!果断花了许久才稳定地连接上...

 

果然有一种山穷水尽疑无路,柳暗花明又一村的感觉。于是, 本人就特记下本篇博客。

 

附上完整的代码,希望大家给出宝贵的意见、

 

 

Kinect开发系列博文:

Kinect开发之 Interaction交互设计  
 
Kinect开发之结合Unity3D进行游戏应用开发
 
Kinect开发之体感举起手来程序设计(Kinect俄罗斯方块)
 
Kinect开发之简单姿势识别
 
Kinect开发之获取骨骼关节数据并绘制成火柴人
 
Kinect开发之获取彩色摄像头数据 
  • 大小: 38 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics