【3D技术宅公社】XR数字艺术论坛  XR技术讨论 XR互动电影 定格动画

 找回密码
 立即注册

QQ登录

只需一步,快速开始

调查问卷
论坛即将给大家带来全新的技术服务,面向三围图形学、游戏、动画的全新服务论坛升级为UTF8版本后,中文用户名和用户密码中有中文的都无法登陆,请发邮件到324007255(at)QQ.com联系手动修改密码

3D技术论坛将以计算机图形学为核心,面向教育 推出国内的三维教育引擎该项目在持续研发当中,感谢大家的关注。

查看: 3167|回复: 1

[体感与外设] Kinect v2.0 for Unity---红外线帧

[复制链接]
发表于 2016-2-1 15:16:03 | 显示全部楼层 |阅读模式
本帖最后由 ycyipman 于 2016-2-16 14:09 编辑

一、使用方式:
红外线帧获取需要两个脚本,InfraredSourceManager和InfraredSourceView,使用时新建一个空物体,并为其添加InfraredSourceManager,在新建一个plane或者cube,添加InfraredSourceView作为输出展示载体。InfraredSourceView需要一个公共变量,将InfraredSourceManager所在的空物体拖入即可。
二、脚本执行过程:
InfraredSourceManager脚本:
过程大致与彩色帧一致,唯一一个不同的地方在于frameDesc对象的得到的_Data数据需要再做一次转换,由于从Kinect直接得到的数据为一个16位无符号整数,这个整数直接代表了这个点的灰度值。而这16位整数只有高10位为有效值,但是能够显示10位灰度值的显示器不多,因此大多数情况下只需要取高8位即可,即16位整数向右移动8位作为最后的灰度值结果。然后,将该值赋予对应的点的RGB三个值,alpha通道则固定位255.具体代码表示如下:
[mw_shl_code=csharp,true]    void Update()
    {
        if (_Reader != null)
        {
            var frame = _Reader.AcquireLatestFrame();
            if (frame != null)
            {
                frame.CopyFrameDataToArray(_Data);

                int index = 0;
                foreach (var ir in _Data)
                {
                    //intensity代表每一个点的灰度值
                    //从Kinect获得的红外红外数据是一个16位无符号整数,这个整数直接代表了这个点的灰度值。
                    //这16位只有高10位是有效的,10位灰度,只有高级显示器才能显示,
                    //我们这一般的显示只能显示256级即8位灰度,所以我们应该舍弃其中2位。舍弃的是最低的两位
                    byte intensity = (byte)(ir >> 8);
                    //RGB相同时,颜色都在灰阶上
                    _RawData[index++] = intensity;//R
                    _RawData[index++] = intensity;//G
                    _RawData[index++] = intensity;//B
                    _RawData[index++] = 255; // Alpha
                }

                _Texture.LoadRawTextureData(_RawData);
                _Texture.Apply();

                frame.Dispose();
                frame = null;
            }
        }
   }
[/mw_shl_code]

由于_RawData数组中每四个值代表一个点,因此在Start函数中_RawData数组长度应为_Data数组的4倍,即:
[mw_shl_code=csharp,true]    void Start()
    {
        _Sensor = KinectSensor.GetDefault();
        if (_Sensor != null)
        {
            _Reader = _Sensor.InfraredFrameSource.OpenReader();
            var frameDesc = _Sensor.InfraredFrameSource.FrameDescription;
            _Data = new ushort[frameDesc.LengthInPixels];
            //_RawData里的元素排列顺序为R/G/B/Alpha,每四位代表一个点的灰度值,因此长度为_Data长度的4倍
            _RawData = new byte[frameDesc.LengthInPixels * 4];
            _Texture = new Texture2D(frameDesc.Width, frameDesc.Height, TextureFormat.BGRA32, false);

            if (!_Sensor.IsOpen)
            {
                _Sensor.Open();
            }
        }
    }
[/mw_shl_code]

除此之外,再建立两个函数,一个用于向InfraredSourceView脚本提供最后的结果,另一个执行应用程序关闭后的操作,此处与彩色帧相同:
[mw_shl_code=csharp,true]    public Texture2D GetInfraredTexture()
    {
        return _Texture;
    }

    void OnApplicationQuit()
    {
        if (_Reader != null)
        {
            _Reader.Dispose();
            _Reader = null;
        }

        if (_Sensor != null)
        {
            if (_Sensor.IsOpen)
            {
                _Sensor.Close();
            }

            _Sensor = null;
        }
    }
[/mw_shl_code]

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|3D数字艺术论坛 ( 沪ICP备14023054号 )

GMT+8, 2024-11-23 15:26

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表