现在的位置: 首页 > 综合 > 正文

基于kinect的展板软件开发实录(一)

2013年10月09日 ⁄ 综合 ⁄ 共 3658字 ⁄ 字号 评论关闭

       基于Kinect的开发现在已经不是个什么新奇玩意儿了,记得在六月份时,微软向各大高校推出Kinect pioneer项目,鼓励同学们能够利用SDK for PC开发出各种对社会有重要意义和价值的的应用。作为今年最热卖的单品,我觉得Kinect对于以后进一步改变人类生活可能有很大潜力,所以想在大三先接触一下。

       为此我们报名参加微软精英挑战赛,和两个同学一起组成“穗城木棉”队,穗城当然就是广州了,木棉也就是广州的市花,它的另一个名字叫做英雄花,寓意大家都懂得了吧~~因为比赛需要完善自己代表队的博客,我决定根据迭代开发的周期,每期做出一个能run的demo就写一篇博客记录我们开发所查阅的资料,参考的样例和在调试中遇到的问题和解决方法,希望对同样在探索kinect开发的同学有所帮助。

       我们从上周正式开始,初步的创意是做一个图片展板软件,用途暂定学院楼下面的展板上。仅仅从这个功能上来讲是非常简单的,但界面效果必须炫,现在一般用户更看重的就是时尚炫丽的UI设计,不过这个得放在后面完善。到项目后期可能考虑采用图像处理算法,把用途拓展到更多的地方。整个开发周期为5周,采用迭代开发,每周完成一个可以运行的demo,添加新的功能和界面设计。

       上周完成了项目的第一期demo,也就是软件最核心的功能:用Kinect跟踪左右手,翻动图片。需要完成的工作是,一个简单的读取图片的界面,和Kinect部分跟踪返回的信号。然后用得到的数据来调用图片的翻动就可以了。

       因为刚刚起步,给我帮助最大的就是马宁的入门教程:

       安装配置--> http://www.cnblogs.com/aawolf/archive/2011/06/17/2083249.html

       操作camera-->

http://www.cnblogs.com/aawolf/archive/2011/06/18/2084352.html

       骨骼追踪-->

http://www.cnblogs.com/aawolf/archive/2011/06/21/2086139.html

       深度数据-->

http://www.cnblogs.com/aawolf/archive/2011/08/25/2153827.html

       在按照他的教程配置完后,运行3个demo,基本对于怎样通过Kinect获取数据有了一定的了解。在网上能够搜索到的中文教程并不多,入门靠马宁的就可以了。下面就是看官方文档,我觉得其中programming guide有必要通览一遍,然后就是skeletalviewer-walkthrough比较重要,其它关于audio方面的资料暂时并不需要。

       但是只运行那4个demo有些简单,想要了解更多的,我找到这个官方的入门网站,里面有几个视频和代码非常经典。可以作为参考。http://channel9.msdn.com/Series/KinectSDKQuickstarts#tab_sortBy_sequential 
其实马宁的博客教程也是参考了channel9里面的Quickstarts的视频做出来的。

       除此之外,在http://channel9.msdn.com/coding4fun/kinect?page=2里面还有非常多的项目,都是各种大牛利用Kinect开发出来的应用,公布了源代码,可能里面有很多非常有帮助的哦。

       好了,说了这么多怎么学习,说回我们这周的工作。思路非常简单,主要用到了骨骼追踪的内容,用canvas画3个椭圆球,分别跟踪头和左右手,算法就是如果左手与头的距离大于45厘米,则图片翻到前一张,如果是右手,则翻到后一张。然后把小球在界面上隐藏,把控制翻页的按钮隐藏,就得到图片和骨骼追踪的videoStream。在界面WPF那部分,主要是一个open图片的操作,和向前翻向后翻的操作,因为才接触C#和.NET表示非常不熟悉,下一步要攻克界面部分了。

        private void Open_Click(object sender, RoutedEventArgs e)
        {
            bitmapImageList.Clear();
            openFileDialog.Multiselect = true;
            if (openFileDialog.ShowDialog() == true)
            {
                if (openFileDialog.FileNames != null)
                {
                    for (int i = 0; i < openFileDialog.FileNames.Length; i++)
                    {
                        BitmapImage bitmapImg = new BitmapImage();
                        bitmapImg.BeginInit();
                        bitmapImg.UriSource = new Uri(@openFileDialog.FileNames[i]);
                        bitmapImg.EndInit();
                        bitmapImageList.Add(bitmapImg);
                    }
                }
                else
                {
                    BitmapImage bitmapImg = new BitmapImage();
                    bitmapImg.BeginInit();
                    bitmapImg.UriSource = new Uri(@openFileDialog.FileName);
                    bitmapImg.EndInit();
                    bitmapImageList.Add(bitmapImg);
                }
            }
            image1.Source = bitmapImageList[0];
        }

     
        private void Next_Click(object sender, RoutedEventArgs e)
        {
            Next_img();
        }

        private void Next_img()
        {
            currentImage = (currentImage + 1) % bitmapImageList.Count;

            image1.Source = bitmapImageList[currentImage];
        }

      private void Pre_Click(object sender, RoutedEventArgs e)
        {
            pre_img();
        }


        private void pre_img()
        {
            if (currentImage == 0)
            {
                currentImage = bitmapImageList.Count - 1;
            }
            else
            {
                currentImage -= 1;
            }

            image1.Source = bitmapImageList[currentImage];
        }


上面是打开图片和翻动图片的操作,因为是直接在界面上拖入button控件,对应的函数public void Pre_Click(object sender,RoutedEventArgs e)里面要传两个参数,在ProcessForwardBackGesture(Joint head, Joint rightHand, Joint leftHand)函数里要调用它时,我不知道sender和e到底要传什么,感觉什么都不用传,但不会解决,所以用了一个很笨的办法,就是把它用另一个没有参数的函数调用。如果有博友能够解决麻烦赐教,确实没有接触过WPF。

       其余kinect获取数据的代码请参考马宁的第三个教程。


       在调试中遇到的3个问题,希望对同样遇到的有所帮助:

       1、马宁的教程用的是beta1的SDK,在现在的beta2中,runtime不应该像Runtime nui = new Runtime()这样初始化。而应该是Runtime runtime = Runtime.Kinect[0];

       2、最初我给videoStream的分辨率是320*240,然后调试时会出现Failed in native DLL. HRESULT=0x80070057这个是因为kinect只支持NUI_IMAGE_RESOLUTION_1280x1024 和NUI_IMAGE_RESOLUTION_640x480的分辨率,所以改成640*480就对了。

       3、在debug时,对SkeletonData data = (from s in skeletonSet.Skeletons
                                 where s.TrackingState == SkeletonTrackingState.Tracked
                                 select s).FirstOrDefault();

            这一句它始终get不到data,但是直接运行程序又没有错。最后发现人站起来到kinect 2米外就OK了~也就是调试的时候也要找个人对着kinect,挺麻烦的吧。

       因为这第一次的demo比较简单,也就不上传项目了,也不截图了,下面会继续加油。希望有好的心得都可以拿出来分享一下,也都是很好的学习。


抱歉!评论已关闭.