守望者--AIR技术交流

标题: Kinect4AirV2基于Kinect 2.0的AS3开发ANE组件 [打印本页]

作者: 破晓    时间: 2014-12-30 21:36
标题: Kinect4AirV2基于Kinect 2.0的AS3开发ANE组件
大家知道Kinect 2.0 / Xbox Kinect One更新也有些许时间了,对于C++或者C#开发者而言并不是很麻烦的一件事情,当然对于Unity用户甚至是福音(官方推出了支持U3D的开发组件),但是对于AS3的开发人员,灾难性的事情来临了,airKinect在Kinect v1 1.6时代就已经不更新了,大伦子的Kinect4Air虽然支持v1.8的握拳、面部、抠像等等高级功能,但是也仅仅支持kinect v1,接下来好吧。。。福利来了。。


首先让我们看下基于Kinect v2硬件的新版Kinect4AirV2都有哪些新特性:
1.      RGB图像支持(也仅支持)1920*1080的高清彩色位图;
2.      Depth深度图像512*424图像;
3.      6人25个骨骼点的全面支持(之前虽然也支持6人追踪,但是仅仅有2人的全身21个骨骼);
4.      与之请的Kinect V1一样,默认支持用户的握拳识别;
5.      仅需要ane一个文件,不在需要庞大的外部opencv库文件;
6.      接口方面全面兼容airkinect 类与接口(基础结构基本一样,当然还是有许多差别的,什么我是不是抄的?好吧。。。让我怎么说呢。。。我要是抄,前提也得是他做完了V2的开发了呀,对吧。。)

功能预览:http://v.youku.com/v_show/id_XODM0MzYyNDI4.html
http://player.youku.com/player.php/sid/XODM0MzYyNDI4/v.swf
看个视频大家乐呵乐呵,没办法,录屏软件仅支持转出1280p的视频,好吧,它尽力了,大家体谅下它们吧,1920p的录屏软件如果你有,请联系我。


视频看完了,再品鉴品鉴代码:

读取RGB图像

  1. [/align][align=left]package dreamers.kinect.examples.cameras {
  2. import dreamers.kinect.Kinect;
  3. import dreamers.kinect.constants.CameraResolution;
  4. import dreamers.kinect.events.CameraImageEvent;
  5. import dreamers.kinect.events.DeviceErrorEvent;
  6. import dreamers.kinect.events.DeviceEvent;
  7. import dreamers.kinect.events.DeviceInfoEvent;
  8. import dreamers.kinect.examples.DemoBase;
  9. import dreamers.kinect.frameworks.mssdk.MSKinectSettings;

  10. import flash.display.Bitmap;

  11. public class RGBCameraDemo extends DemoBase {

  12.     private var rgbBitmap:Bitmap;
  13.     private var device:Kinect;

  14.     override protected function startDemoImplementation():void {        
  15.             device = Kinect.getDevice();

  16.             rgbBitmap = new Bitmap();
  17.                         rgbBitmap.x = 0;
  18.                         rgbBitmap.y = 0;

  19.             addChild(rgbBitmap);

  20.             device.addEventListener(CameraImageEvent.RGB_IMAGE_UPDATE, rgbImageUpdateHandler, false, 0, true);
  21.                         device.addEventListener(DeviceInfoEvent.INFO, deviceInfoHandler, false, 0, true);
  22.                         device.addEventListener(DeviceErrorEvent.ERROR, deviceErrorHandler, false, 0, true);
  23.             device.addEventListener(DeviceEvent.STARTED, kinectStartedHandler, false, 0, true);
  24.             device.addEventListener(DeviceEvent.STOPPED, kinectStoppedHandler, false, 0, true);

  25.             var settings:MSKinectSettings = new MSKinectSettings();
  26.             settings.rgbEnabled = true;
  27.                         settings.rgbResolution = CameraResolution.RESOLUTION_1920_1080;

  28.             device.start(settings);
  29.     }
  30.          
  31.         protected function deviceErrorHandler(event:DeviceErrorEvent):void
  32.         {
  33.                 trace("[RGBCameraDemo] ERROR: " + event.message);
  34.         }
  35.          
  36.         protected function deviceInfoHandler(event:DeviceInfoEvent):void
  37.         {
  38.                 trace("[RGBCameraDemo] INFO: " + event.message);
  39.         }
  40.          
  41.     protected function kinectStartedHandler(event:DeviceEvent):void {
  42.         trace("[RGBCameraDemo] Device started");
  43.     }

  44.     protected function kinectStoppedHandler(event:DeviceEvent):void {
  45.         trace("[RGBCameraDemo] Device stopped");
  46.     }

  47.     override protected function stopDemoImplementation():void {
  48.         if (device != null) {
  49.             device.stop();
  50.             device.removeEventListener(CameraImageEvent.RGB_IMAGE_UPDATE, rgbImageUpdateHandler);
  51.             device.removeEventListener(DeviceEvent.STARTED, kinectStartedHandler);
  52.             device.removeEventListener(DeviceEvent.STOPPED, kinectStoppedHandler);
  53.                         device.removeEventListener(DeviceInfoEvent.INFO, deviceInfoHandler);
  54.                         device.removeEventListener(DeviceErrorEvent.ERROR, deviceErrorHandler);
  55.         }
  56.     }

  57.     protected function rgbImageUpdateHandler(event:CameraImageEvent):void {
  58.         rgbBitmap.bitmapData = event.imageData;
  59.                  
  60.                 rgbBitmap.width = stage.stageWidth;
  61.                 rgbBitmap.height = stage.stageHeight;
  62.     }

  63. }
  64. }
复制代码
解析6人25全骨骼信息的代码片段
  1. for each(var user:User in device.users) {
  2.                 //遍历用户信息
  3.     closestUser ||= user;
  4.     if (user.position.world.z < closestUser.position.world.z) closestUser = user;

  5.     if (user.hasSkeleton) {
  6.                         //用户左手状态
  7.                         if(user.handLeftState == HandSate.HAND_CLOSE)
  8.                         {
  9.                                 rgbSkeletonContainer.graphics.beginFill(0x00ff00, user.leftHand.positionConfidence);
  10.                                 rgbSkeletonContainer.graphics.drawCircle(user.leftHand.position.rgb.x, user.leftHand.position.rgb.y, 35);
  11.                                 rgbSkeletonContainer.graphics.endFill();
  12.                         }
  13.                         else
  14.                         {
  15.                                 rgbSkeletonContainer.graphics.beginFill(0x000000, user.leftHand.positionConfidence);
  16.                                 rgbSkeletonContainer.graphics.drawCircle(user.leftHand.position.rgb.x, user.leftHand.position.rgb.y, 35);
  17.                                 rgbSkeletonContainer.graphics.endFill();
  18.                         }
  19.                         //用户右手状态
  20.                         if(user.handRightState == HandSate.HAND_CLOSE)
  21.                         {
  22.                                 rgbSkeletonContainer.graphics.beginFill(0x00ff00, user.rightHand.positionConfidence);
  23.                                 rgbSkeletonContainer.graphics.drawCircle(user.rightHand.position.rgb.x, user.rightHand.position.rgb.y, 35);
  24.                                 rgbSkeletonContainer.graphics.endFill();
  25.                         }
  26.                         else
  27.                         {
  28.                                 rgbSkeletonContainer.graphics.beginFill(0x000000, user.rightHand.positionConfidence);
  29.                                 rgbSkeletonContainer.graphics.drawCircle(user.rightHand.position.rgb.x, user.rightHand.position.rgb.y, 35);
  30.                                 rgbSkeletonContainer.graphics.endFill();
  31.                         }
  32.                         
  33.                         //为每个骨骼点位着色
  34.         for each(var joint:SkeletonJoint in user.skeletonJoints) {
  35.             rgbSkeletonContainer.graphics.beginFill(0xFF0000, joint.positionConfidence);
  36.             rgbSkeletonContainer.graphics.drawCircle(joint.position.rgb.x, joint.position.rgb.y, 5);
  37.             rgbSkeletonContainer.graphics.endFill();

  38.             depthSkeletonContainer.graphics.beginFill(0xFF0000, joint.positionConfidence);
  39.             depthSkeletonContainer.graphics.drawCircle(joint.position.depth.x, joint.position.depth.y, 5);
  40.             depthSkeletonContainer.graphics.endFill();
  41.         }
  42.     }
复制代码
好吧,给大家放个读取高清RGB图像和Depth图像的demo示例解解馋

示例下载方法

Demo下载:群共享里面,大家加QQ群:221849157 , 群共享里面即有demo和更多资料下载。

如果您需要该组件的更多功能,请联系大伦子,并支持他的工作,联系方式:

    大伦子 QQ:123685049
    http://www.dalunzi.com

目前Kinect4Air暂时由于精力问题没有发布免费的学习版本,请见谅,最近确实忙完一波又一波,计划元旦跨年期间发布更多功能以及提供学习版和教程文章等等资料,目前首先欢迎广大的AS3开发企业加入内测。

最后列举下接下来的开发计划,大家可以留意投票看看那些需求是你最需要的:
1.      高清抠像
2.      Infrade图像
3.      点云
4.      面部识别
5.      语音识别

本文来自:http://bbs.9ria.com/thread-421397-1-1.html


作者: 破晓    时间: 2015-1-21 09:46
本帖最后由 破晓 于 2015-1-21 09:56 编辑

Kinect4Air体感射击游戏-SDK1.8新特性之一握拳手势
  Kinect v1版本发布至今已有3-4年之久,随着1代硬件的极限已被发挥,微软将在下一个月发布Kinect v2的正式版本,体感图像、人物捕捉人数、处理速度上都有了较大提升,但是对于我们ASer来说,提供给我们Air平台开发的接口却仍然非常至少,在2代kinect到来之前,我们先看看还有那些新特性是我们AS3还没有利用到的呢?

    我们知道,对于体感摄像头而言,一直有几个常规数据是我们拿来设计、开发游戏来使用的,分别是RGB图像、Depth深度图、2个人物的20个人体骨骼信息点,这几个数据已经足够我们完成一个体感游戏的常规开发工作,但是在微软kinect sdk1.6-1.8以后陆续提供了几个有意思的功能,分别是握拳(及松手、Push推等)手势,抠像功能,以及面部识别等新功能支持(当然fusion等3维重建功能也是极其漂亮的)。这里我们就先以握拳(及松手)的手势开发来切入今天的主题。

    在之前的体感控制程序中,如果我们需要和界面的UI组件进行交互,一般的方式是利用鼠标和可视化组件进行区域或坐标的碰撞检测(hitTestObject/hitTestPoint)来进行交互的判断,为了识别的稳定性,一般又会设置一段时间的悬停来减少误操作,但是如果利用握拳操作,可以将手保持在原有坐标的基础上,快速而稳定的进行按钮操作,也不是为一个新的操作方式。

    首先,我们看一个示例,Kinect体感射击小游戏,国际惯例,我们先来看下视频效果:

http://player.youku.com/player.php/sid/XNzI1NTk0MTcy/v.swf
   那么我们来看下通过Kinect4Air组件如何使用握拳手势的识别:
1.添加ane拓展,并导入id(设置方法大家在文档中循迹);
2.导入kinect类与消息事件类
  1. import dreamers.kinect.KinectEvent;
复制代码
3.初始化kinect单例对象
  1. public var m_kinect:kinect = Kinect.getInstance() ;
复制代码
4.打开kinect设备
  1. m_kinect.InitKinect(stage.nativeWindow ,0 , 0,0);
复制代码
InitKinect方法
参数1:stage.nativeWindow为必填参数,将会影响后续骨骼点位转化为屏幕坐标,设备关闭相关消息的接受等功能。
参数2:0/1的整型数字,表示是否输出debug信息,如果设置的值为1,拓展程序将默认在进入拓展执行函数之初进行函数名的输出,调试消息在FB的控制台中输出,类似trace方法。测试阶段,该输出对性能不太明显,正式工程发布请关闭该调试选项,以免影响性能发挥。
参数3:0/1的整型数字,如果参数为1,表明启用面部关键点捕捉,这里需要注意,非必要的情况下不要开启,面部识别和追踪比较消耗资源,我们将在第八部分详细讲解面部识别的具体方法。
参数4:0/1的整型数字,如果参数为1,表明启用背景抠像功能,这里需要注意,非必要的情况下请置空或设置为0,背景抠像功能同样比较消耗资源,我们将在第九部分详细介绍背景抠像的具体使用方法。



5.添加监听握拳手势的消息事件
  1. m_kinect.addEventListener(KinectEvent.GET_DATA_HANDSTATE , onHandState);
复制代码
6.处理手势消息
  1. public function onHandState(e:KinectEvent=null):void
  2. {
  3.                 //设置左手状态
  4.                 if(m_kinect.m_HandLeftState == 2)                //握拳
  5.                 {
  6.                         m_LeftHand.gotoAndStop(2);
  7.                 }
  8.                 else if(m_kinect.m_HandLeftState == 1)                //松手
  9.                 {
  10.                         m_LeftHand.gotoAndStop(1);
  11.                 }

  12.                 //设置右手状态
  13.                 if(m_kinect.m_HandRightState == 2)                //握拳
  14.                 {
  15.                         m_RightHand.gotoAndStop(2);
  16.                 }
  17.                 else if(m_kinect.m_HandRightState == 1)                //松手
  18.                 {
  19.                         m_RightHand.gotoAndStop(1);
  20.                 }

  21. }         
复制代码
打完收工,真的就是这么简单;至此,你已经可以使用握拳及松手的手势去开发游戏了。最后,一定有人会问“LZ,游戏源码呢?”,好吧,体感射击游戏源码送给大家作为研究学习使用。
如果还有小伙伴把例子和文档都研究透了,还有强烈的研究欲望,请加群:221849157,相信你们一定可以找到在Kinect体感技术、Stage3D技术方面的知己。
下载资料整理如下:

1.体感射击游戏运行版本 -- 下载2.体感射击游戏源代码  -- 下载3.Kinect4Air v1.8.3版本ANE组件  -- 下载4.Kinect4Air v1.8.3版本文档  -- 下载5.Kinect4Air v1.8.3版本完整版HelloWorld -- 下载

TeamWork:体感设计游戏代码开发:杭州梦树文化艺术策划有限公司 邹爱敏 小伙伴编写                         设计师:杭州梦树文化艺术策划有限公司 设计部门 小伙伴们制作                      项目经理:杭州梦树文化艺术策划有限公司 诸城梁 大牛督阵            组件提供及指导:LZ大伦子就是了  http://www.dalunzi.com            杭州梦树文化官方主页:http://www.dreamers.com.cn
下周,我们将会看到另外两个特性,面部识别及背景抠像功能的展示demo和代码讲解,届时精心奉上,敬请关注。



作者: 破晓    时间: 2015-1-21 09:49
本帖最后由 破晓 于 2015-1-21 09:55 编辑

Kinect4Air体感游戏开发-SDK1.8新特性之二面部识别跟踪
上周我们展示并讲解了利用Kinect4Air开发的体感射击游戏,通过握拳手势的操作来实现射击动作(对游戏或者代码感兴趣的的小伙伴,请传送至Kinect体感射击游戏-SDK1.8新特性之一握拳手势),这一次我们来看一下使用微软Kinect SDK 1.8的另外一个新特性FaceTracking如何使用。


首先,我们来看一个视频效果:
http://player.youku.com/player.php/sid/XNzMzNzYwMzIw/v.swf

原理说明:
首先在初始化Kinect设备的时候,打开面部追踪的开关,回顾下initKinect方法的使用方法:

InitKinect方法


参数1:stage.nativeWindow为必填参数,将会影响后续骨骼点位转化为屏幕坐标,设备关闭相关消息的接受等功能。


参数2:0/1的整型数字,表示是否输出debug信息,如果设置的值为1,拓展程序将默认在进入拓展执行函数之初进行函数名的输出,调试消息在FB的控制台中输出,类似trace方法。测试阶段,该输出对性能不太明显,正式工程发布请关闭该调试选项,以免影响性能发挥。


参数3:0/1的整型数字,如果参数为1,表明启用面部关键点捕捉,这里需要注意,非必要的情况下不要开启,面部识别和追踪比较消耗资源,我们将在第八部分详细讲解面部识别的具体方法。


参数4:0/1的整型数字,如果参数为1,表明启用背景抠像功能,这里需要注意,非必要的情况下请置空或设置为0,背景抠像功能同样比较消耗资源,我们将在第九部分详细介绍背景抠像的具体使用方法。

1.   面部识别简介
面部识别之前,微软限定我们必须要先进行骨骼识别,因此对于程序的最终操作者而言,也要其位置能够进行骨骼识别;
在骨骼识别的基础上,微软制定了所谓的ROI的区域,也就是将操作者头部区域的图像作为关注区域的图像,进行算法分解,注意,即使是这样子,这个功能的CPU消耗也是颇为惊人的;
这样子我们从微软Kinect SDK的识别中,得到了121个面部识别点,最终将它们的坐标转换成相对于RGB图像(640X480)内的相对坐标(这也是绝大多数示例程序中,很容易将RGB图像中人物的面部和点位连线图对应的原因),下面看看具体代码。
2.   导入事件类
  1. import dreamers.kinect.KinectEvent;
复制代码
3.   打开面部识别
  1. //初始化Kinect
  2. var ret:int =m_kinect.InitKinect(stage.nativeWindow, 0 , 1,0);
复制代码
上面我们也介绍过了,初始化函数的第三个非必选的函数,指定为1即可。
4.   监听数据流的消息
  1. m_kinect.addEventListener(KinectEvent.GET_DATA_FACE,onGetFaceData);
  2. m_kinect.addEventListener(KinectEvent.GET_DATA_FACEUSERMISSED,onMissedFaceData);
复制代码
GET_DATA_FACE消息:顾名思义就是监视进程成功获取了面部数据,此时可以对数据进一步进行分析和操作。
GET_DATA_FACEUSERMISSED消息:提供了面部数据失去跟踪后,程序进行必要的操作。
5.   处理面部数据
在收到GET_DATA_FACE消息后,可以通过m_kinect对象的m_FaceDataAry成员获取数据,该成员是一个长度为121的Point数组,其x,y坐标就是在640X480分辨率的RGB图像内的相对坐标,如果变换其他大小,也可以在该事件中自行进行坐标的变换。
       以唇部的4个关键可被跟踪的点位举例说明:
  1. * 7 - 上唇居中 :m_kinect.m_FaceDataAry[7](x,y)
  2. * 8 - 下唇居中 :m_kinect.m_FaceDataAry[8] (x,y)
  3. * 31  -  左嘴角 :m_kinect.m_FaceDataAry[31] (x,y)

  4. * 64  -  右嘴角 :m_kinect.m_FaceDataAry[64] (x,y)
复制代码
那么接下来,我们看下完整的视频中的示例代码:
  1. package
  2. {
  3.         import dreamers.kinect.KinectEvent;
  4.         import dreamers.kinect.kinect;
  5.         
  6.         import flash.display.Sprite;
  7.         import flash.events.Event;
  8.         import flash.events.MouseEvent;
  9.         
  10.         [SWF(width="800",height="600",backgroundColor="#FFFFFF")]
  11.         public class KinectFaceAR extends Sprite
  12.         {
  13.                 public var m_kinect:kinect = kinect.getInstance()  ;        //Kinect单例对象
  14.                
  15.                 //表情动画组件
  16.                 private var _nosePigSel:ClassNosePig = new ClassNosePig;
  17. //                private var _eyesSel:ClassEyesFirst = new ClassEyesFirst;
  18.                 private var _eyesSel:ClassEyeSecond = new ClassEyeSecond;
  19.                 private var _mouthSel:ClassMouth = new ClassMouth;
  20.                
  21.                 //表情动画组件
  22.                 private var _nosePig:ClassNosePig = new ClassNosePig;
  23. //                private var _eyes:ClassEyesFirst = new ClassEyesFirst;
  24.                 private var _LeftEye:ClassEyeSecond = new ClassEyeSecond;
  25.                 private var _RightEye:ClassEyeSecond = new ClassEyeSecond;
  26.                 private var _mouth:ClassMouth = new ClassMouth;
  27.                
  28.                 public function KinectFaceAR()
  29.                 {
  30.                         this.addEventListener(Event.ADDED_TO_STAGE , onAddToStage);
  31.                 }
  32.                
  33.                 protected function onAddToStage(event:Event):void
  34.                 {
  35.                         InitKinectDevice();
  36.                         AddEventListener();
  37.                         AddUI();
  38.                 }
  39.                
  40.                 private function InitKinectDevice():void
  41.                 {
  42.                         //初始化Kinect设备,并打开面部追踪功能
  43.                         var ret:int = m_kinect.InitKinect(stage.nativeWindow , 0 , 1 , 0);

  44.                         //加载Rgb图像
  45.                         m_kinect.m_RgbImg.width = 640;
  46.                         m_kinect.m_RgbImg.height = 480;
  47.                         m_kinect.m_RgbImg.x = 0;
  48.                         m_kinect.m_RgbImg.y = 0;
  49.                         this.addChild(m_kinect.m_RgbImg);
  50.                 }
  51.                
  52.                 private function AddEventListener():void
  53.                 {
  54.                         stage.nativeWindow.addEventListener(Event.CLOSING,closeWindow);
  55.                         
  56.                         //监听面部数据捕捉、丢失的消息
  57.                         m_kinect.addEventListener(KinectEvent.GET_DATA_FACE , onGetFaceData);
  58.                         m_kinect.addEventListener(KinectEvent.GET_DATA_FACEUSERMISSED , onMissedFaceData);
  59.                 }
  60.                
  61.                 public function AddUI():void
  62.                 {
  63.                         //////////////////////////////////////////////////////////////////////////////////
  64.                         //表情选择按钮
  65.                         this.addChild(_nosePigSel);
  66.                         _nosePigSel.gotoAndStop(1);
  67.                         _nosePigSel.x = 720;
  68.                         _nosePigSel.y = 150;

  69.                         this.addChild(_eyesSel);
  70.                         _eyesSel.gotoAndStop(1);
  71.                         _eyesSel.x = 720;
  72.                         _eyesSel.y = 150 + 100;

  73.                         this.addChild(_mouthSel);
  74.                         _mouthSel.gotoAndStop(2);
  75.                         _mouthSel.x = 720;
  76.                         _mouthSel.y = 150 + 100  + 100;

  77.                         //////////////////////////////////////////////////////////////////////////////////
  78.                         //表情AR组件
  79.                         _nosePig.scaleX = 1.3;
  80.                         _nosePig.scaleY = 1.3;
  81.                         
  82.                         this.addChild(_nosePig);
  83.                         this.addChild(_LeftEye);
  84.                         this.addChild(_RightEye);
  85.                         this.addChild(_mouth);
  86.                         
  87.                         _nosePig.visible = true;
  88.                         _LeftEye.visible = true;
  89.                         _RightEye.visible = true;
  90.                         _mouth.visible = true;
  91.                         
  92.                         _nosePig.gotoAndStop(1);
  93.                         _LeftEye.gotoAndStop(1);
  94.                         _RightEye.gotoAndStop(1);
  95.                         _mouth.gotoAndStop(2);
  96.                 }
  97.                
  98.                 //面部数据的不能被捕捉或者丢失用户时,清除界面UI组件
  99.                 protected function onMissedFaceData(event:Event):void
  100.                 {
  101.                         _nosePig.visible = false;
  102.                         _LeftEye.visible = false;
  103.                         _RightEye.visible = false;
  104.                         _mouth.visible = false;
  105.                 }
  106.                
  107.                 //处理接收到面部数据的消息事件响应
  108.                 protected function onGetFaceData(event:Event):void
  109.                 {               
  110.                         _nosePig.visible = true;
  111.                         _LeftEye.visible = true;
  112.                         _RightEye.visible = true;
  113.                         _mouth.visible = true;
  114.                         
  115.                         //设置鼻子的位置
  116.                         _nosePig.x = m_kinect.m_FaceDataAry[5].x;
  117.                         _nosePig.y = m_kinect.m_FaceDataAry[5].y;
  118.                         
  119.                         //设置左眼睛的位置
  120.                         _LeftEye.x = m_kinect.m_FaceDataAry[21].x;
  121.                         _LeftEye.y = m_kinect.m_FaceDataAry[21].y;
  122.                         
  123.                         //设置右眼睛的位置
  124.                         _RightEye.x = m_kinect.m_FaceDataAry[54].x;
  125.                         _RightEye.y = m_kinect.m_FaceDataAry[54].y;
  126.                         
  127.                         //设置嘴巴的位置
  128.                         _mouth.x = m_kinect.m_FaceDataAry[41].x;
  129.                         _mouth.y = m_kinect.m_FaceDataAry[41].y;
  130.                 }
  131.                
  132.                 //关闭窗口,安全起见,请关闭消息监听
  133.                 private function closeWindow(e:Event):void
  134.                 {
  135.                         m_kinect.removeEventListener(KinectEvent.GET_DATA_FACE , onGetFaceData);
  136.                         m_kinect.removeEventListener(KinectEvent.GET_DATA_FACEUSERMISSED , onMissedFaceData);
  137.                 }
  138.                
  139.         }
  140. }
复制代码
资源及素材下载:

1.KinectFaceAR示例源文件  ---------------------------- 下载2.KinectFaceAR示例运行文件下载  -------------------- 下载3.Kinect4Air v1.8.3版本ANE组件   ------------------- 下载4.Kinect4Air v1.8.3版本文档   ------------------------- 下载5.Kinect4Air v1.8.3版本完整版HelloWorld  -------- 下载
如果还有小伙伴把例子和文档都研究透了,还有强烈的研究欲望,请加群: 221849157 ,相信你们一定可以找到在Kinect体感技术、Stage3D技术方面的知己。
官方的文档和更新的信息,请及时访问作者主页 http://www.dalunzi.com



作者: 破晓    时间: 2015-1-21 09:53
本帖最后由 破晓 于 2015-1-21 09:54 编辑

Kinect4Air体感游戏开发-SDK1.8新特性之三背景抠像
好吧,复习一下,上两周我们都做了什么?
第一章,我们已经将握拳这个手势操作融入到了我们日常体感的开发中,
第二章,我们也已经可以使用Kinect面部追踪的功能,开发面部AR,表情互动等应用(甚至眨眼、张嘴等动作),


今天,我们来看下Kinect4Air SDK 1.8.3版本的最后一个重要功能 -- 背景抠像,大家知道,Kinect通过深度图和RGB图像进行分割以后,不仅边缘会有一层轮廓,还会产生边缘上的毛刺。为了配合讲解背景抠像效果,我特地制作了4个滤镜效果的展示代码,给大家介绍下如何使用AS3的滤镜进行图像的优化处理:
1.精细版抠图效果:将人体和背景抠像分离并减薄人体轮廓外面的阴影,使抠像效果更接近绿屏/蓝屏抠像效果。
2.外轮廓发光效果:就是传说中的隐身效果。
3.内轮廓发光效果:将抠像外围的轮廓改变颜色,使之成为有色轮廓。
4.模糊效果:就人像变模糊效果。

http://player.youku.com/player.php/sid/XNzMxNzc2MzE2/v.swf



1.关于初始化Kinect硬件的方法,之前的两个示例已经讲解的非常详细,不再赘述了。
2.将组件获取的抠像数据备份出来
  1.   //抠像的克隆处理图像
  2.                 private var m_composeImgProcessData:BitmapData = new BitmapData(640,480,true,0x00FFFFFF);
  3.                 private var m_composeImgProcess:Bitmap  = new Bitmap(m_composeImgProcessData);
复制代码

3.将4个滤镜添加数组,方便切换。
  1.   //滤镜特效
  2.                 private var m_filterArray:Array = new Array();
  3.                
  4.                 private var m_filter1:GlowFilter = new GlowFilter(0x000000);
  5.                 private var m_filter2:GlowFilter = new GlowFilter(0x000000);
  6.                 private var m_filter3:GlowFilter = new GlowFilter(0x000000);
  7.                 private var m_filter4:BlurFilter;
  8.                 private var m_filterNum:int = 0;
复制代码

4.为4个滤镜设置参数并压入数组
  1.    //滤镜效果1 - 精细版抠图效果
  2.                         m_filter1.blurX = 20;
  3.                         m_filter1.blurY = 20;
  4.                         m_filter1.strength = 0.6;
  5.                         m_filter1.quality = BitmapFilterQuality.HIGH;
  6.                         m_filter1.alpha = 0;
  7.                         m_filter1.knockout = false;
  8.                         m_filter1.inner = true;
  9.                         m_filterArray.push(m_filter1);
  10.                         
  11.                         //滤镜效果2 - 内轮廓效果
  12.                         m_filter2.blurX = 15;
  13.                         m_filter2.blurY = 15;
  14.                         m_filter2.strength = 3.5;
  15.                         m_filter2.quality = BitmapFilterQuality.HIGH;
  16.                         m_filter2.color = 0x00FF00;                                                                        //修改外轮廓颜色
  17.                         m_filter2.alpha = 0.5;
  18.                         m_filter2.knockout = true;
  19.                         m_filter2.inner = false;
  20.                         m_filterArray.push(m_filter2);
  21.                         
  22.                         //滤镜效果3 - 外轮廓发光效果
  23.                         m_filter3.blurX = 15;
  24.                         m_filter3.blurY = 15;
  25.                         m_filter3.strength = 3.5;
  26.                         m_filter3.quality = BitmapFilterQuality.HIGH;
  27.                         m_filter3.color = 0xFF0000;                                                                        //修改外轮廓颜色
  28.                         m_filter3.alpha = 0.8;
  29.                         m_filter3.knockout = false;
  30.                         m_filter3.inner = false;
  31.                         m_filterArray.push(m_filter3);
  32.                         
  33.                         //滤镜效果4 - 模糊效果
  34.                         var blurX:Number=5;
  35.                         var blurY:Number=5;
  36.                         m_filter4 = new BlurFilter(blurX,blurY,BitmapFilterQuality.HIGH);
  37.                         m_filterArray.push(m_filter4);
复制代码
5.初始化kinect相关函数及事件
  1.    //初始化Kinect
  2.                         var ret:int = m_kinect.InitKinect(stage.nativeWindow , 0 , 0 , 1);
  3.                         
  4.                         //背景抠像后的图像,使用滤镜的情况下,尽量不要直接使用m_kinect.m_ComposeImg
  5.                         //避免被多线程数据快速覆盖,影响效果;
  6.                         //最好将其clone到其他bitmap对象中处理、显示。
  7.                         //                        m_kinect.m_ComposeImg.width = 640;
  8.                         //                        m_kinect.m_ComposeImg.height = 480;
  9.                         //                        m_kinect.m_ComposeImg.x = 0;
  10.                         //                        m_kinect.m_ComposeImg.y = 0;
  11.                         //                        this.addChild(m_kinect.m_ComposeImg);
  12.                         
  13.                         //将抠像图像添加舞台
  14.                         this.addChild(m_composeImgProcess);
  15.                         
  16.                         //添加kinect背景抠像消息
  17.                         m_kinect.addEventListener(KinectEvent.GET_IMAGE_COMPOSE , onGetComposeImg);
  18.                         //添加kinect手势消息
  19.                         m_kinect.addEventListener(KinectEvent.GET_DATA_HANDSTATE , onGetHandState);        
复制代码
6.通过之前我们学习过的握拳手势来控制效果的切换
  1. //监听到成功获取手势消息
  2.                 private var RightHandGrip:Boolean = false;
  3.                 protected function onGetHandState(event:Event):void
  4.                 {
  5.                         // 右手握拳、松手控制切换滤镜
  6.                         //设置右手状态
  7.                         if(m_kinect.m_HandRightState == 1)                //松手
  8.                         {
  9.                                 RightHandGrip = false;
  10.                         }
  11.                         else if(m_kinect.m_HandRightState == 2)                //握拳
  12.                         {
  13.                                 if(RightHandGrip)
  14.                                         return;
  15.                                 else
  16.                                 {
  17.                                         RightHandGrip = true;
  18.                                        
  19.                                         //切换滤镜
  20.                                         m_filterNum ++;
  21.                                         if(m_filterNum >= m_filterArray.length)
  22.                                                 m_filterNum = 0;
  23.                                        
  24.                                         //更新标题
  25.                                         switch(m_filterNum)
  26.                                         {
  27.                                                 case 0:
  28.                                                         m_titleTxtField.text = "精细抠图效果";
  29.                                                         break;
  30.                                                 case 1:
  31.                                                         m_titleTxtField.text = "外轮廓发光效果";
  32.                                                         break;
  33.                                                 case 2:
  34.                                                         m_titleTxtField.text = "内轮廓置空效果";
  35.                                                         break;
  36.                                                 case 3:
  37.                                                         m_titleTxtField.text = "模糊效果";
  38.                                                         break;
  39.                                         }//end switch
  40.                                 }//end else
  41.                         }//end else
  42.                 }
复制代码
7.在成功获取了抠像图像后,我们将抠图图像备份出来,留作处理,为什么这么做,上面代码的注释中也已阐述。

  1.   //监听到成功获取了背景抠像的消息
  2.                 protected function onGetComposeImg(event:Event):void
  3.                 {
  4.                         //克隆抠像图像数据
  5.                         m_composeImgProcess.bitmapData = m_kinect.m_ComposeImg.bitmapData.clone();
  6.                         //设置当前滤镜
  7.                         m_composeImgProcess.filters = [ m_filterArray[m_filterNum] ];
  8.                 }
复制代码
8.注意:抠像功能比较耗费CPU,谨慎使用,在我的3代I7上,CPU消耗在60%左右。



如果还有小伙伴把例子和文档都研究透了,还有强烈的研究欲望,请加群: 221849157 ,相信你们一定可以找到在Kinect体感技术、Stage3D技术方面的知己。

官方的文档和更新的信息,请及时访问作者主页 http://www.dalunzi.com

1.KinectBackgroundRemoval示例源文件  ---------------------------- 下载
2.KinectBackgroundRemoval示例运行文件下载  -------------------- 下载
3.Kinect4Air v1.8.3版本ANE组件   ------------------- 下载
4.Kinect4Air v1.8.3版本文档   ------------------------- 下载
5.Kinect4Air v1.8.3版本完整版HelloWorld -------- 下载






欢迎光临 守望者--AIR技术交流 (http://www.airmyth.com/)