总算是到了这一天了!假期里算法想不出来,或者被BUG折磨得死去活来的时候,老是YY着何时能心情愉快地坐在电脑前写一篇项目总结,今天总算是抽出时间来总结一下这神奇的几个月。javascript
如今回过头来看,上学期退出ACM集训队果真是对的,此次开发学到的东西太多太多,之前在ACM的时候,感受不会的东西好多啊,真正来本身试着开发个东西,发现不会的东西果真好多。不过要是几个老师知道我上午给新生作完ACM宣讲报告下午就跟教练说退出,他们会是什么心情啊哈哈。html
这些是第一次尝试开发,若是ACM是练内功的话,那么练了三年也总该让我拿出来用用了,否则学了三年仍是只在个控制台里玩甚是寂寞,本身亲手从无到有创造出一个东西来的感受, 实在太爽了!java
先说一下此次项目印象最深的几个教训:算法
好了,如今正式开始介绍一下项目自己。小程序
这个项目本来是用来参加2016年的微软创新杯,可是在上一周,也就是3月20号的四川省区域赛中未获奖,只能直接参战中国区半决赛。此次区域赛失败的缘由有不少,虽然做品已经完成得差很少了,可是没能优秀地将其展现出来,在现成演示的时候还遇到了一个巨大失误,中途才发现,因此没等通知结果就知道多半是悲剧了。第一次参加这类开发类的比赛,就当交学费好了,不过此次区域赛给个人感受是,微软仍是想找几个最有商业前途的做品,这个项目炫是很炫酷,可是实际意义不大的样子,因此感受中国区半决赛但愿也不大。不过无所谓啦,我本身玩得嗨就好了,微软欣不欣赏那是另一回事,说不定哪天我就搭建出个钢铁侠那样的实验室不是?啊哈哈,最近也顺便把这个项目报成了大学生创新创业训练计划,成功申请到国家级,算是能够安慰一下。测试
简单来讲,此项目就是要把投影仪投出的投影变得能够直接用裸手操控,就好像投影变成了一块大型的平板电脑,投影能够是在投影幕上、墙上甚至桌子上,任何光滑且不是反射材质的平面都行,至于为何不能是反射材质,等下会有介绍。刚开始是计划达到能用手指直接在投影上写字的精度,后来发现很难作到,瓶颈在于指尖的识别算法不够精确,这是我本身构思的一个简单算法,将来应该会用更高级更精确的算法来替代。优化
Kinect for Windows V2
+ Kinect SDK 2.0
+ OpenCV 3.0
+ Visual Studio Community 2015
spa
项目里利用到的一个很是重要的东西就是Kinect for Windows V2
,一款微软的动做感应器,能够算成是一类现实加强设备,发布时主要是搭配XBox
来玩体感游戏,可是这么厉害的一个东西只能用来玩游戏实在太惋惜,因此微软在前几天发布了它的Windows
版本,让它可以在PC上进行开发。就是下面这么个东西:版本控制
原理其实并不算难,主要能够参考下面这张图。code
一开始我是基于Kinect
中BodyIndex
这个数据源来寻找指尖,首先定位出腕关节在哪,而后根据腕关节的位置向上寻找复合指尖特征的点,能够说效果很好,识别很是精确和稳定,并且能同时识别出5个指尖,这部分是我在假期里完成的,原本觉得来到学校后将程序根据投影仪调整下就差很少能够用了,然而到校测试后才发现一个致命的问题,就是当手臂贴近墙壁时,整个手臂的BodyIndex
数据都丢失了。由于微软彷佛认为,若是某个点要是属于人体的话,那么它和背景的深度差至少要有二三十厘米左右(正好是人体的厚度)。这个问题让我失眠了几晚上...不过也是在失眠的时候想出了如今用的解决方法。ds
如今用的方法是基于`Depth`数据来找指尖的,简单来讲就是根据指尖的特色找出全部吻合的点,而后取 位置最高的那个(由于操做的时候用的基本都是一根手指),这样作能够减小不少工做量,由于不少非法点都直接被略去了。
由于想达到手指指哪,鼠标就点击哪的效果,因此必须把手指在投影上的位置,映射成鼠标在电脑里相应的位置,这个其实简单推导一下就能够得出。
黑色框为投影屏幕,大写的X和Y表明的是屏幕的宽和高,红色框为电脑屏幕,假设人的手指在的位置,若是想将鼠标也映射到一样的位置,那么就有
的等比关系成立。这里投影屏幕的宽和高在上面第一步中获取,而电脑屏幕的宽和高,其实是不须要考虑分辨率的,由于在鼠标的坐标系下,电脑的宽和高都被分红了65535个单位,因此宽和高能够视为65535。根据这些,就能够算出
的值来。
Kinect
是带有深度摄像头的,也就是说它可以知道画面中的每一点到它的距离。彷佛是利用三组红外发射器来实现,因此也就要求物体不能是反射材质,否则会获取不到距离。由于可以知道屏幕的距离,也能知道手指的距离,因此若是手指距离屏幕足够近,那么就能够判断为点击。可是,屏幕有可能不是绝对垂直的,Kinect
也有摆歪的可能性,同时深度数据也不是100%精确,因此在计算屏幕距离时,须要考虑一个容错值,在这个范围内都被视为屏幕,在这里我设置的值是10cm,虽然看上去不少,可是实际效果还不错。可是,这也带来一个很严重的问题,就是手指在离屏幕的位置小于10cm的时候,也被视为了屏幕,这时候指尖就丢失了,手指变成了手指中部(由于手指不是彻底平行于墙面的,而是有必定角度,因此指根的地方距离屏幕更远),这就会产生很不稳定的现象,至今没有解决。上面就是核心的功能,除此以外,还要加入一些鼠标的抖动消除、偏差消除的处理,同时我还调用了Kinect
的手势识别功能,直接用手势来完成撤销的操做。这段时间忙着找实习,之后有时间的话,应该会优化指尖识别的算法,同时加入更多的手势来调用操做。
(博客园的MarkDown
竟然不能够插视频,差评)
直接在墙上玩割绳子:
用手在墙上书写(外加用手势来调用撤销):
直接裸手操控PPT:
这个项目差很少就这么多啦,剩下的只是优化下各个功能,或者加点新东西进去。从假期里就构思了一个比较有意思的小程序,等这段时间忙结束,应该就会把它敲出来。真是愈来愈好玩了!