<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<?xml-stylesheet type="text/css" href="css/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>CSK.Blog</title><link>http://www.csksoft.net/blog/</link><description>Make something different.</description><generator>RainbowSoft Studio Z-Blog 1.7 Laputa Build 70216</generator><language>zh-CN</language><copyright>Copyright Shikai Chen 2000-2012.</copyright><pubDate>Sat, 20 Jun 2015 10:05:00 +0800</pubDate><item><title>我眼中的Maker Faire Bay Area</title><author>csk@live.com (csk)</author><link>http://www.csksoft.net/blog/post/makerfaire.bayarea.2015.html</link><pubDate>Tue, 02 Jun 2015 09:36:49 +0800</pubDate><guid>http://www.csksoft.net/blog/post/makerfaire.bayarea.2015.html</guid><description><![CDATA[<p><strong>点击文章标题浏览全文</strong></p>
<p align="center"><img alt="" src="http://www.csksoft.net/data/pic/makerfaire2015ba/001.jpg" /></p>
<h1 class="std_h1">前言</h1>
<p>由于兴趣使然，从2008年开始我又重新开始在业余时间玩起各类电子制作。并在2009年底有幸与一群小伙伴创办了RoboPeak机器人团队，并且一路走到今天得以公司化运作。从一开始几个人业余小打小闹逐步成为一家专业从事服务机器人并以自主激光定位导航核心见长的公司SLAMTEC，在见证了这几年努力得到收获的同时，我也感受到了整个产业逐步向着硬件智能化方向的变革。</p>
<p>在这个过程当中，比较引人注目的是一个名词的流行：Maker。为了能够阐释这个名词最纯正的意味，我先暂不提及它目前在国内广泛使用的译名。Maker, 直接翻译就是&ldquo;动手做东西的人&rdquo;。从这个角度上看，包括我在内的很多从事DIY的爱好者就被划分到了这个群体内。<br />
Maker这个概念的出自美国的Make:杂志（<a href="http://makezine.com/">http://makezine.com/</a>），该杂志与国内的很多DIY类刊物如《无线电》类似，定期得向读者介绍从电子制作、艺术创作、有趣DIY等方向的文章。不过，Make:做的更进一步，他们将Maker作为一种文化潮流，并且每年定期的在世界各地举办属于Maker的聚会：Maker Faire。这个聚会给了全球所有DIY爱好者、艺术家乃至是企业/初创公司一次难得地对外展示自己作品的机会。随着半导体技术的革新，进行新硬件开发的门槛不断降低，更多人得以快速使用Arduino这样的平台进行原型作品开发，Maker Faire也顺着该趋势在全世界范围得以流行。</p>
<p>对国人而言，Maker这个名词被大众所认知也正是随着2012年第一届深圳举办的Shenzhen Mini Maker Faire开始的。相比后来国内举办的Maker Faire和创客嘉年华，2012年的那届Maker Faire的规模相对较小，但却第一次给了国内从事各类DIY创作的团体、个人展示自己的机会。我们的RoboPeak团队也是从那年开始，逐步开始在各类集会中进行作品的发布展示，并被大家所认知。</p>
<p>而在今年，我们RoboPeak团队来到了美国加州Bay Area，第一次参加了最原汁原味的Maker Faire Bay Area并进行了展出。在为期三天的参展过程中，我也体验到了作为Maker Faire发源地与国内的不同之处。特此写下此文，向大家分享我们这次的见闻以及我的感想。</p>
<p>&nbsp;</p>
<h1 class="std_h1">Maker Faire Bay Area 2015的简介</h1>
<p>本届Maker Faire Bay Area位于加州San Mateo郡的Event Center。<br />
</p>
<p align="center"><img alt="" src="http://www.csksoft.net/data/pic/makerfaire2015ba/002.jpg" /></p>
<p align="center">图：本届Maker Faire Bay Area的位置，地图来自某境外网站</p>
<p align="center">非常巧的是，我们正好赶上的是自第一届Maker Faire举办至今的第10个年头集会，主办方在活动上花了不少心思。整个展览为期两天半，分别是5.16 17 18三天，其中，16号是下午半天的展览。这样的设置用意为何？5.16那天是周五，按理说不会有特别多的游客。实际上这是本届Maker Faire主办方刻意安排，在对外的活动安排里，主办方只是写了17、18号两天的展览时间。而周五下午的半天展览是专门为前来展出作品的Maker们准备的，目的就是让大家趁着这天游客相对较少时有足够的时间来相互&ldquo;串门&rdquo;交流取经。不然到了后面几天游客增多，大家就忙于接待了。<br />
<img alt="" src="http://www.csksoft.net/data/pic/makerfaire2015ba/003.jpg" /></p>
<p align="center">图：展览期间密集的人流</p>
<p align="center"><img alt="" src="http://www.csksoft.net/data/pic/makerfaire2015ba/004.jpg" /></p>
<p align="center">图：整个展出区地图</p>
<p>作为一年一度Maker Faire的全球主场，并且恰逢10周年，这届Maker Faire Bay Area的规模自然是不能小的。主办方设置了多个室内展示区、多个室外大型互动作品展区还有专门供销售DIY套件、Maker作品的Maker Shed馆。<br />
就室内展厅，就包括： </p>
<ol>
    <li>我们RoboPeak所在的主展区EXPO HALL </li>
    <li>以3D打印机、加工设备和实验装备为主的Maker Lab </li>
    <li>以专门展示灯光互动艺术的暗室展区 </li>
    <li>以展出智能硬件初创公司产品的Startup Pavilion </li>
    <li>很有趣的展示自制食物的Homegrown Village </li>
</ol>
<p>....</p>
<p>这次我们一行4人，展出的作品为： </p>
<p align="center"><img alt="" src="http://www.csksoft.net/data/pic/makerfaire2015ba/063.jpg" /></p>]]></description><category>动态</category><comments>http://www.csksoft.net/blog/post/makerfaire.bayarea.2015.html#comment</comments><wfw:comment>http://www.csksoft.net/blog/</wfw:comment><wfw:commentRss>http://www.csksoft.net/blog/sydication.asp?cmt=307</wfw:commentRss><trackback:ping>http://www.csksoft.net/blog/cmd.asp?act=tb&amp;id=307&amp;key=23bf363d</trackback:ping></item><item><title>Intel Galileo Gen 2开发板的性能评估、使用技巧和实现分析</title><author>csk@live.com (csk)</author><link>http://www.csksoft.net/blog/post/306.html</link><pubDate>Mon, 23 Feb 2015 20:39:55 +0800</pubDate><guid>http://www.csksoft.net/blog/post/306.html</guid><description><![CDATA[<div class="quote">本文最早刊登于2014.12和2015.1月的《无线电》杂志上，对Galileo Gen2的内部实现做了分析。</div>
<div class="quote">转载请注明原文出处：CSK.Blog : <a href="http://www.csksoft.net/blog/">http://www.csksoft.net/blog/</a></div>
<p><strong>请点击文章标题进入阅读全文</strong></p>
<p>&nbsp;在Intel发布首款兼容Arduino开发接口风格的x86开发板Galileo的不到一年内，推出了它的升级版本Intel Galileo Gen2。顾名思义，Gen2即英文Generation 2(第二代)的缩写。从一个简单的照片对比中，我们就可以感受到两者的不同：</p>
<p align="center"><img alt="" src="http://www.csksoft.net/data/pic/intel_galileo_gen2/001.jpg" /></p>
<p align="center">图：Intel Galileo一代（左）与二代（右）的对比图</p>
<p>从开发板实物的直接对比上，我们可以看到Galileo Gen2的左侧布置了不少小芯片，似乎比前一代复杂了不少。那么它到底与前一代的主要区别在哪里？到底哪些地方得到了提升呢？</p>
<p>当然，这些问题的答案一部分Intel已经为我们解答了：在Intel的官方网站中给出了Galileo Gen2相比前一代的硬件配置的变化。但仅仅硬件配置的不同却远不足以解答以上的这些问题。这些硬件配置具体带来了那些实际的性能和特性改变？在底层设计上，Galileo Gen2具体是怎么做的？</p>
<p>为了将这些问题弄清楚，在没有更多现成资料的情况下，最直接的手段就是亲自去实践了。</p>
<p>同时，我们知道，Intel Galileo虽然是一块兼容Arduino规范的开发板，但其背后基于x86的平台特性又不断地在提醒我们：这又不仅仅只是一块Arduino兼容系统而已。那么，隐藏在兼容Arduino接口规范外表下的Galileo的真实实力又该如何充分展现出来呢？在本文的上一篇《Intel Galileo 开发板的体验、分析和应用》[1]当中，我已向大家简单的介绍了Intel Galileo的底层实现、基于yocto环境的Linux系统开发等话题。在这篇文章中，我将继续深入这些话题。向大家分享Intel Galileo不仅仅作为一个简单的Arduino板的那些功能。</p>
<p align="center"><img alt="" src="http://www.csksoft.net/data/pic/intel_galileo_gen2/002.jpg" /></p>
<p align="center">图：在Intel Galileo中安装Debian Linux发行版，运行图形桌面</p>
<p>&emsp;<br />
</p>
<p align="center"><img alt="" src="http://www.csksoft.net/data/pic/intel_galileo_gen2/003.jpg" /></p>
<p align="center">图：Galileo Gen2与上一代的对比</p>
<p align="center">&nbsp;</p>
<p align="center"><img alt="" src="http://www.csksoft.net/data/pic/intel_galileo_gen2/010.jpg" /></p>
<p style="text-align: center">图：相比前一代Galileo对IO的实现（A），Galileo Gen2的实现（B）令软硬件的设计复杂了不少</p>
<p align="center"><img alt="" src="http://www.csksoft.net/data/pic/intel_galileo_gen2/014.jpg" /></p>
<p style="text-align: center">图：示波器中观测到的IO口产生的信号波形</p>
<p align="center"><img alt="" src="http://www.csksoft.net/data/pic/intel_galileo_gen2/023.jpg" /></p>
<p align="center"><img alt="" src="http://www.csksoft.net/data/pic/intel_galileo_gen2/032.jpg" /></p>
<p style="text-align: center">图：Galileo Gen2原理图中进行IO信号电平转换的部分<br />
<p align="center"><img alt="" src="http://www.csksoft.net/data/pic/intel_galileo_gen2/037.jpg" /></p>
<p style="text-align: center">图：Quark SoC数据手册[8]中描绘的硬件框图，可发现有2种GPIO设备<p align="center"><img alt="" src="http://www.csksoft.net/data/pic/intel_galileo_gen2/050.jpg" /></p>
<p style="text-align: center">图：通过串口调试器看到的本例子输出</p>
<p align="center"><img alt="" src="http://www.csksoft.net/data/pic/intel_galileo_gen2/056.jpg" /></p>
<p style="text-align: center">图：使用Hob简化Yocto的使用过程</p>
]]></description><category>电子电路</category><comments>http://www.csksoft.net/blog/post/306.html#comment</comments><wfw:comment>http://www.csksoft.net/blog/</wfw:comment><wfw:commentRss>http://www.csksoft.net/blog/sydication.asp?cmt=306</wfw:commentRss><trackback:ping>http://www.csksoft.net/blog/cmd.asp?act=tb&amp;id=306&amp;key=1522672f</trackback:ping></item><item><title>Smartisan T1简要评测和感受</title><author>csk@live.com (csk)</author><link>http://www.csksoft.net/blog/post/305.html</link><pubDate>Tue, 26 Aug 2014 07:11:40 +0800</pubDate><guid>http://www.csksoft.net/blog/post/305.html</guid><description><![CDATA[<div class="quote">没想到好久不更新自己Blog数个月后迎来的是这样一篇文章...不过既然很多朋友想听听我的感受，就写了
<div><strong>首先申明的是，我不是什么锤子粉，也不可能是枪手。写这篇文章只是想告诉其他朋友我买Smartisan T1的感受而已，你要觉得好就去买，不好也没事，都和我无关。</strong></div>
<div><strong>我不想为这篇文章展开非常无聊的讨论或者谩骂。就一手机，好就是好，不好就是不好，没那么复杂。可怕的就是有些人什么都不去研究，不去自己思考，人云亦云，那才是真的无知。</strong></div>
<div>&nbsp;</div>
</div>
<div><br />
</div>
<div>
<h2 class="std_h2">1.我为何会去买Smartisan T1</h2>
</div>
<div>最近正巧用了快一年的HTC one m7因为内部MMC Flash芯片故障，导致系统数据丢失，启动过程锁死在CPU内部的bootloader阶段。了解情况的朋友知道，这样的情况下，刷机是不可能的，返修是唯一的手段。但因为我手贱，自己拆机维修时把所有的屏幕排线弄断了...</div>
<div>之前我算是HTC的忠实用户，从多普达的机器一直用到现在。认为除了Apple外，HTC在UI和工业设计上的处理非常符合我的审美。但现在这个时间点恰逢ip6将要发布，但我个人又不喜欢用iOS的系统，HTC one m8个人认为id设计不合格，三星又一直入不了眼。在这样的背景下，就打算尝试新的机器。</div>
<div>那么看了又看，Smartisan T1的外观虽然不是很吸引我，但看了一些评测，尤其是Zealer的那篇把Smartisan批得一无是处的文章后，反而坚定我打算买这部手机的信念。这不是我脑残了，就以Zealer的那个视频而言，虽然每次都以负面的评价收场，但手机内部拆解的照片，UI的细节视频，这些客观的东西是没法做修饰的，也不会因为评测者主观认知变化。就做工来说，我认为Smartisan T1的细节把控绝对是到位的。我拆过HTC one, HTC desire S, iphone 4S, 三星 S3，从内部结构布局看，Smartisan T1得设计是可以和apple比较。这不是光靠老罗的那些什么情怀能解决的事情，是要有实际的功底的。从UI上来说，有些细节对之前用习惯HTC sense的我来说也是不太习惯，但好歹也算是经过精密设计的，感官上也符合审美。</div>
<div style="text-align: left;">至于外界批评的一些瑕疵，比如发热耗电，我只能说之前用的htc one绝对是有过之而无不及，很正常。至于良品率，那是在发货之前的事情，良率再低，只要QC过关，到我手里的还是合格品。</div>
<div>此外，目前我也正好在创业初期，深知做出一款产品的不易。从非理性的角度上，我想这也算是我会支持老罗买Smartisan T1的很重要因素。</div>
<div>综合考虑，选择Smartisan T1是目前对我比较好的选择，至少也算是做一次Kickstarter的pledge罢了。不过目前老罗那边产能有限，我等不及排队，就多加了几百元从黄牛那边拿了机器。</div>
<div><br />
</div>
<div>
<h2 class="std_h2">2. 开箱的初步感受</h2>
</div>
<div>简单说，目前感觉还是很不错的。硬件做工暂无可挑剔的，软件上有一些吐槽点，但不是致命的。并且就算那些大厂牌一样都有。</div>
<div>文章结尾会贴一些照片象征一下，但网上肯定以及有铺天盖地的同类照片了，所以也不想过多重复。就说说自己的感受</div>
<div>第一映像是从打开包装开始的，这点上Smartisan T1的处理非常到位，盒子用料的材质、内部物件的布局，都非常讲究。的确是有一种&ldquo;不像是国货&rdquo;的感觉。这点上只能说只有亲自感受才知道了。</div>
<div style="text-align: center; "><img src="/data/pic/t1/01.png" alt="" /><br />
</div>
<div style="text-align: center; "><img src="/data/pic/t1/02.png" alt="" /><br />
</div>
<div style="text-align: center; "><img src="/data/pic/t1/03.png" alt="" /><br />
</div>
<div style="text-align: left;">说说我观察到的几个细节。首先这部手机不支持从侧面插入SIM卡，虽然外界有很多质疑，但我觉得无所谓。要装入SIM卡，就要打开后盖。可以注意出场时，固定后盖的螺丝是没上的。实际上在装入SIM卡后，即使不拧上螺丝，后盖的紧固也是很可靠的。</div>
<div style="text-align: center; "><img src="/data/pic/t1/04.png" alt="" /><br />
</div>
<div style="text-align: left;">下图是听筒位置的特写，虽然外界也是争议很多。但至少看起来很细致美观。做工上我认为也非常到位，的确没啥好挑剔了。</div>
<div style="text-align: center; "><img src="/data/pic/t1/05.png" alt="" /><br />
</div>
<div style="text-align: left;">拆开后盖内部的情况。要强调的是材质都是金属磨沙质感的，不是ABS。可以对比下其他手机厂家。</div>
<div style="text-align: center; "><img src="/data/pic/t1/06.png" alt="" /><br />
</div>
<div style="text-align: left;">为了方便用户紧固那个螺丝而配套的螺丝刀。</div>
<div style="text-align: center; "><img src="/data/pic/t1/07.png" alt="" /><br />
</div>
<div style="text-align: left;">图片就贴到这里为止。对于附带的螺丝刀。我个人也是觉得没有什么必要性，毕竟这提高了用户使用门槛。这个设计或许能用老罗的情怀来描述。不过，公道的说，对于一些Geek，这点还是挺能打动他们的。另外从螺丝刀的设计和做工上，用俗话说就是&ldquo;装逼&rdquo;，可以满足下个人某些方面的虚荣心，但话又说回来，很多人买iphone，也不就为了体验这种感受吗。</div>
<div style="text-align: left;"><br />
</div>
<div style="text-align: left;">
<h2 class="std_h2">3. 屏幕和按钮</h2>
</div>
<div style="text-align: left;">之前听说Smartisan T1的实体按钮是败笔，有的人遇到按下无法弹起。有的人按下去屏幕碎了..也有人说屏幕色彩不行、漏光严重、XXXX。我目前情况是，看来我非常幸运，这些问题我都没遇到。屏幕色彩鲜艳（不知道色彩准不准），漏光几乎没有，总体上看，比我之前的HTC one M7 1080p的OLED屏幕也没差到那里。</div>
<div style="text-align: left;">实体按钮也非常好使，手感一流。至于网上说前面板打孔放按钮导致容易让玻璃破碎，就我观察，目前的设计能按一下按钮使得屏幕碎了，除非那用户手是用榔头做的...</div>
<div style="text-align: left;">所以这点上，我觉得Smartisan T1做工完全合格，而且接近我认为的完美。</div>
<div style="text-align: left;"><br />
</div>
<div style="text-align: left;">
<h2 class="std_h2">4. 相机</h2>
</div>
<div style="text-align: left;">这点我认同其他的评测，相机没有老罗说的那么好。对焦速度的确偏慢，而且弱光表现不足。而且软件上很多功能不能设置，比如ISO、EV。拍照也不能选择16:9模式。但就手机相机比较，拍摄体验画质上在至少不输其他同价位手机。当时也用同事的iphone4S在完全相同环境拍着对比，画质上几乎一样。</div>
<div style="text-align: left;">而发布会上说的快速抢拍功能，实际使用效果不太好。但我个人没啥特别大的不适</div>
<div style="text-align: left;"><br />
</div>
<div style="text-align: left;">
<h2 class="std_h2">5. 发热</h2>
</div>
<div style="text-align: left;">跑了一些3D的游戏，以及一些消耗CPU的处理运算。发热的确不低，不过也就和HTC one m7一个等级，感觉htc的还烫一些。所以个人觉得很正常。毕竟都是高通的CPU，要热也怪高通。感觉热反而说明这手机内部散热处理的好</div>
<div style="text-align: left;"><br />
</div>
<div style="text-align: left;">
<h2 class="std_h2">6. 电池待机</h2>
</div>
<div style="text-align: left;">目前还没完成一次充放电循环，所以暂无评价。不过从放电消耗的趋势预测，和htc one m7应该差不多。估计一天下来还是要充电的。</div>
<div style="text-align: left;"><br />
</div>
<div style="text-align: left;"><strong>2014-8-27：关于耗电方面的更新：1.充电速度感觉不快，从20%充满大概2个小时。但我用的PC usb供电，最大也就500mA，所以应该不能反映自带充电器的情况 2.从昨天晚上10:40用到现在13:51，还剩下39% QQ一直挂着，期间集中使用累计大概有2个小时。比HTC one m7强多了。</strong></div>
<div style="text-align: left;">
<h2 class="std_h2">7. 音质</h2>
</div>
<div style="text-align: left;">因为老罗鼓吹了一下，所以特地用AKG &nbsp;k240配合耳放听了下，只能说不好也不差。毕竟那个运放芯片也就做普通HIFI的等级。内置的speaker效果不好，但我也没期待啥。手机大小的音源，不好是常态。之前htc one m7号称用的beats audio技术，实际上也是做了低频增益处理。严格说是对信号做了染色，属于大幅度失真了。</div>
<div style="text-align: left;"><br />
</div>
<div style="text-align: left;">
<h2 class="std_h2">8. UI</h2>
</div>
<div style="text-align: left;">这点之前的评价都已老罗的情怀来说事。我非常反感这点。从体验上说，系统UI设计的相当的不错。那种局部细微的设计渗透在整个使用环节中，有些不见得实用，但给初次使用者带来的喜悦感是相当微妙的。他能从心理上给用户传到一个信号：这货买的值了！我想，当年第一次接触iphone，给我的其实也无非就是如此。毕竟那时候iphone有的功能，winmobile手机一个都不缺，apple做的，也就是这些细节上的微妙感受吧。</div>
<div style="text-align: left;">至于是哪些细节，我就不罗嗦了，老罗已经有铺天盖地的视频。</div>
<div style="text-align: left;">对于老罗的情怀，的确有一些值得吐槽的点，例如内置铃声，充分体现了老罗个人（或者不是他，而是某个人）的偏好，对我来说，几乎没有一个可选的。但除了这点外，其他的设计都是很让我满意的，也是一个优秀UI该有的。</div>
<div style="text-align: left;">比如不能设置壁纸这点，我其实很认同老罗的看法。</div>
<div style="text-align: left;"><br />
</div>
<div style="text-align: left;">
<h2 class="std_h2">9. 稳定性和流畅性</h2>
</div>
<div style="text-align: left;">目前没发现任何crash，而处理器性能摆在那边，说真的，要做到不流畅，反而蛮困难。稳定性这点说真的，底层BSP都是厂家给的，老罗做UI深度定制，要把稳定性做差，同样也真不容易..</div>
<div style="text-align: left;"><br />
</div>
<div style="text-align: left;">目前想说的就那么多。最后多扯一下淡，可能是因为大家对国货一直以来比较失望，又因为老罗以前的背景，所以容易让人有怀疑。这点我也一样。但做出了东西，好和不好，其实是可以客观评价的，事情也没有什么情怀这种无聊话题那么复杂。关键就在你是人云亦云还是愿意自己去调查探索这个问题上了。而综合来看Smartisan T1，至少目前我觉得它很优秀，老罗在对待产品的问题上值得我和我所在公司学习。</div>]]></description><category>随感</category><comments>http://www.csksoft.net/blog/post/305.html#comment</comments><wfw:comment>http://www.csksoft.net/blog/</wfw:comment><wfw:commentRss>http://www.csksoft.net/blog/sydication.asp?cmt=305</wfw:commentRss><trackback:ping>http://www.csksoft.net/blog/cmd.asp?act=tb&amp;id=305&amp;key=a433f8c8</trackback:ping></item><item><title>Intel Galileo 开发板的体验、分析和应用</title><author>csk@live.com (csk)</author><link>http://www.csksoft.net/blog/post/304.html</link><pubDate>Fri, 25 Apr 2014 19:15:33 +0800</pubDate><guid>http://www.csksoft.net/blog/post/304.html</guid><description><![CDATA[<div class="quote"><strong>请点击文章标题阅读全文</strong><br />本文最早发表于ifanr：http://www.ifanr.com/388835
<div>转载请保留作者信息和原始出处：CSK.Blog</div>
</div>

<div>
<h1 class="std_h1">1. 前言</h1>
</div>
<div>在今年(2013)罗马举办的首届欧洲 Make Faire 上,Intel 向对外发布了采用 x86 构架的 Arduino 开发板:Intel Galileo。这无疑是一个开源硬件领域的重磅消息。作为 CPU 领域的巨头 Intel, 为开源硬件/Maker 领域这个从前相对小众的圈子推出专门的硬件,无疑说明对开源硬件领 域发展的重视程度。同时,Intel 也作为本届欧洲 Maker Faire 的主要赞助商。</div>
<div style="text-align: center; "><img src="/data/pic/intel_galileo_hacks/001.jpg" alt="" /><br />
</div>
<div style="text-align: center; ">图:Intel Galileo 开发板,图片来自 intel.com</div>
<div>在 PC 行业,Intel x86 构架的强大性能一直被行业称道,自然这次推出的 Arduino 开发板,也 给业界带来了无限的遐想。我相信很多人都会略带调侃问:这个开发板能不能运行 Windows 这样的问题。同时,相信也有不少人会关心 Intel Galileo 的功耗问题,以及开发使用上是否具有难度。</div>
<div>作为曾在 Intel 工作过的作者,对老东家能够推出针对开源硬件市场的产品感到欣慰。通过 朋友,我也有幸在较早时间拿到了一块 Intel Galileo。经过了一段时间的使用和体验,这里 我就将我们对 Intel Galileo 的一些使用体验向大家分享。并且作为开源硬件和机器人开发的 从业人员,聊聊 Intel Galileo 到底可以给我们带来哪些想象空间? 这里也先针对那个调侃问题做个回应:<strong>是的,通过软件的调整,Intel Galileo 的确可以运行 Windows:)</strong></div>
<div style="text-align: center; "><img src="/data/pic/intel_galileo_hacks/002.jpg" alt="" /><br />
</div>
<div style="text-align: center;">图:使用 RoboPeak 微型 USB 显示屏,给 Galileo 增加显示屏变成标准 PC</div>]]></description><category>Hacks</category><comments>http://www.csksoft.net/blog/post/304.html#comment</comments><wfw:comment>http://www.csksoft.net/blog/</wfw:comment><wfw:commentRss>http://www.csksoft.net/blog/sydication.asp?cmt=304</wfw:commentRss><trackback:ping>http://www.csksoft.net/blog/cmd.asp?act=tb&amp;id=304&amp;key=94bbe0eb</trackback:ping></item><item><title>聊聊几个特殊的显示屏：EL和单色等离子工业屏的浅析与使用</title><author>csk@live.com (csk)</author><link>http://www.csksoft.net/blog/post/el_and_plasma_disp.html</link><pubDate>Sun, 15 Dec 2013 07:09:54 +0800</pubDate><guid>http://www.csksoft.net/blog/post/el_and_plasma_disp.html</guid><description><![CDATA[<div class="quote">
<p>又是许久没有更新自己Blog了。虽然在微博上一直更新自己近况。不过好的内容还需要Blog写文章积淀。</p>
</div>
<p><strong>点击文章标题浏览全文</strong></p>
<p>作为一名电子爱好者，我一直喜欢收集各种类型的屏幕，尤其是那些具有特殊显示效果或者有一定历史且目前很难见到的。虽然不敢说真的收集的有多全有多高级，但也一度被大家戏称为&ldquo;屏幕控&rdquo;。<br />
近期因为各种机缘巧合得到了几块并不多见的EL和等离子工业显示屏。这些屏幕对于电子爱好者来说非常少见，主要应用在工业和航天、军工领域。但显示效果别具一格，因此写了本文向大家分享他们的特点以及使用方式。<br />
虽然这些屏幕并不是大家都会用到的，但相信其中的一些使用理念，尤其是在缺少厂家资料情况下，通过电路分析寻找驱动方法的思路，会对大家有所帮助。</p>
<p align="center"><br />
<img alt="" src="/data/pic/eldispimg/001.jpg" /></p>
<p align="center">图：单色等离子屏（左）与EL屏（右）的显示效果 </p>
<p align="center"><br />
<img alt="" src="/data/pic/eldispimg/020.jpg" /></p>
<p align="center">图：用EL显示屏展示RoboPeak机器人控制界面（PLANAR 640x400）</p>
<p align="center">&nbsp;</p>
<p align="center"><img alt="" src="/data/pic/eldispimg/021.jpg" /></p>
<p align="center">图：PLANAR 320x240 EL显示屏</p>
]]></description><category>电子电路</category><comments>http://www.csksoft.net/blog/post/el_and_plasma_disp.html#comment</comments><wfw:comment>http://www.csksoft.net/blog/</wfw:comment><wfw:commentRss>http://www.csksoft.net/blog/sydication.asp?cmt=303</wfw:commentRss><trackback:ping>http://www.csksoft.net/blog/cmd.asp?act=tb&amp;id=303&amp;key=937823a1</trackback:ping></item><item><title>Oculus Rift 虚拟现实眼镜的介绍、体验和应用畅想</title><author>csk@live.com (csk)</author><link>http://www.csksoft.net/blog/post/oculus.rift.eval_3155.html</link><pubDate>Sun, 30 Jun 2013 08:45:06 +0800</pubDate><guid>http://www.csksoft.net/blog/post/oculus.rift.eval_3155.html</guid><description><![CDATA[<div class="quote">本文最早发布于ifanr，当时地址为：<a href="http://www.ifanr.com/288886" >http://www.ifanr.com/288886</a>
<div>先转回我自己的Blog</div>
</div>
<div><strong>内容提要，请点击文章标题浏览全文</strong></div>
<div>
<h1 class="std_h1">1.<span class="Apple-tab-span" style="white-space:pre">	</span>简介</h1>
</div>
<div>去年8月的时候，我经好友介绍，了解到了当时正在Kickstarter网站上募资的Oculus Rift虚拟现实眼镜项目(后文简称Rift)。虽然那个时候Kickstarter上的项目页面中并没看到Oculus Rift眼镜的实物，不过看过五分钟不到的演示视频的后，我便迫不及待的想预定一台了。</div>
<div style="text-align: center; "><img src="http://www.csksoft.net/data/pic/oculusrift/001.png" ><br>
</div>
<div>
<div style="text-align: center;">图: Oculus Rift在Kickstarter上的募资页面</div>
<div><br>
</div>
<div>...</div></div><div>
</div>
<div style="text-align: center; "><img src="http://www.csksoft.net/data/pic/oculusrift/005.png" ><br>
</div>
<div>
<div style="text-align: center; ">图：Oculus Rift宣传视频中宣称的110度视角</div>
<div><br>
</div>
<div>经过了半年多的等待，Oculus团队不负众望陆续将Rift开发套件送到了全球各地的赞助者手上。我也在今年4月底收到了等候多时的Rift。</div>
<div><br>
</div>
<div>那么Rift到底用起来感觉如何？接下来我将向大家分享我的使用体验。并且由于我本身对电子制作和机器人有浓厚兴趣，因此本文也将花一定篇幅探讨Rift背后的技术实现以及针对他进行扩展应用。</div>
</div>
<div>
<div>
<h1 class="std_h1">2.<span class="Apple-tab-span" style="white-space:pre">	</span>开箱照</h1>
</div>
<div>我的Rift是从香港寄来的，快递使用的是EMS。打开纸箱后就会看到Rift定制的黑色箱子，感觉很专业：</div>
</div>
<div style="text-align: center; "><img src="http://www.csksoft.net/data/pic/oculusrift/006.png" ><br>
</div>
<div></div>
<div style="text-align: center; "><img src="http://www.csksoft.net/data/pic/oculusrift/010.png" ><br>
</div>
<div>
<div>做工上我认为只能算中上水平，不过要知道对于一个之前没有涉足硬件制造的团队来说，半年内生产出上万的批量合格产品绝非易事。</div>
<div>在早先的Oculus进度通报邮件中提及，目前所有的开发者套件均由深圳的工厂负责代工。</div>
<div>
<h1 class="std_h1">3.<span class="Apple-tab-span" style="white-space:pre">	</span>使用过程和体验</h1>
</div>
<div>
<h2 class="std_h2">...<br>
</h2>
</div>
</div>
<div>如果将Rift眼镜上的透镜拆掉，就可以看到藏在眼镜底部的LCD显示器。它只是简单的复制了电脑显示器的画面而已。</div>
<div style="text-align: center; "><img src="http://www.csksoft.net/data/pic/oculusrift/018.png" ><br></div>
<div>...</div><div>
</div>
<div style="text-align: center; "><img src="http://www.csksoft.net/data/pic/oculusrift/021.png" ><br></div>
<div>很容易猜到这两幅画面其实分别对应了Rift中左右眼应该看到的部分。而之所以扭曲，这便是Rift能实现110度视角的奥秘所在：采用凸透镜将画面放大。</div>
<div style="text-align: center; "><img src="http://www.csksoft.net/data/pic/oculusrift/022.png" ><br></div>
<div>
<div style="text-align: center; ">图：利用凸透镜将原先长度为x的画面放大至x’</div>
<div style="text-align: center; ">来源：Oculus SDK文档</div>
</div>
<div style="text-align: center; "><img src="http://www.csksoft.net/data/pic/oculusrift/023.png" ><br></div>
<div>
<div style="text-align: center; ">图: Rift在LCD屏幕前安装了凸透镜，用于扩大视角</div>
<div><br>
</div>
<div>由于凸透镜在放大画面的同时会产生扭曲，因此就需要先将PC的原始输出画面做扭曲的处理，就可以抵消扩大视角范围造成的画面扭曲。</div>
<div><br>
</div>
<div>为了给大家直观的感受，这里将Rift左右眼位置的凸透镜拆除，可以看到背后的LCD显示的对应画面：</div>
</div>
<div style="text-align: center; "><img src="http://www.csksoft.net/data/pic/oculusrift/024.png" ><br></div>
<div>
<div>虽然这样远距离看上去画面很清晰，但是如果不安装凸透镜，直接将rift带上，双眼就会看到模糊一片的景象，并且也会感觉画面很小。</div>
<div><br>
</div>
<div>那么带上Rift看到的画面是怎样的呢？这里我将相机仿造人肉眼那样直接贴紧Rift拍摄，此时的画面就和亲身的体验很接近。不过亲身的体验是全三维的，很有现场感。这种感觉靠本文难以带给读者。</div>
</div>
<div style="text-align: center; "><img src="http://www.csksoft.net/data/pic/oculusrift/025.png" ><br></div>
<div style="text-align: center; ">图：相机尚未完全紧贴Rift时的效果，此时基本可以看到画面。</div>
<div style="text-align: center; "><img src="http://www.csksoft.net/data/pic/oculusrift/026.png" ><br></div>
<div>
<div><strong>...</strong></div></div><div>
<div><br>
</div>
<div>
<h2 class="std_h2">视角切换体验</h2>
</div>
<div>作为虚拟现实眼镜另一个很重要的指标就是在人扭头，视角切换时候，所看到画面随着切换的响应速度了。如果传感器或者软件处理的较慢，则会感受到所看到的画面有所滞后。从而产生不真实感，更是会令人晕眩。</div>
<div><br>
</div>
<div>对此Oculus Rift在宣传中申明采用了1000hz刷新率的惯性导航定位算法，可以实现很低的滞后率。</div>
<div><br>
</div>
<div>从我的感受看，前文提到的官方演示程序的确表现很出色。读者不妨先看这段视频感受一下。</div>
</div>
<div>
<div style="text-align: center; "><embed src="http://www.tudou.com/v/jXqE-Fv7z1I/&rpid=70789997&resourceId=70789997_05_05_99&bid=05/v.swf" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" wmode="opaque" width="480" height="400"></embed>
</div>
<div>
<h2 class="std_h2">佩戴舒适度与晕眩感</h2>
</div>
<div>...</div></div><div>
<div><br>
</div>
<div>
<h2 class="std_h2">支持Rift的应用和游戏</h2>
</div>
<div>...</div></div><div>
<div><br>
</div>
<div>
<h1 class="std_h1">4.<span class="Apple-tab-span" style="white-space:pre">	</span>内部构造和简要分析</h1>
</div>
<div>...</div></div><div>
<div>
<h2 class="std_h2">实现移动感知的探讨</h2>
</div>
<div></div>
<div>下图为我团队所开发的0-6米全向<a href="http://www.robopeak.net/blog/?p=267" >激光测距雷达系统</a>。他可以实时的扫描环境四周（360度）的物体相对于自身的距离，并且可以提供毫米级别的定位精度。用它来结合Rift进行虚拟现实世界中人物移动的判断，当属不错的选择。</div>
</div>
<div style="text-align: center;"><img src="http://www.csksoft.net/data/pic/oculusrift/050_1.png" ><br></div>
<div>
<div style="text-align: center; ">图：使用激光雷达进行Rift使用者的跟踪</div>
<div><br>
</div>

<div>
<h2 class="std_h2">应用的展望</h2>
</div>
<div>
...
</div>
<div style="text-align: center;"><img src="http://www.csksoft.net/data/pic/oculusrift/051.png" ><br></div>
<div style="text-align: center; ">图：Rift代表的虚拟现实技术与机器人技术的融合</div>
</div>]]></description><category>Hacks</category><comments>http://www.csksoft.net/blog/post/oculus.rift.eval_3155.html#comment</comments><wfw:comment>http://www.csksoft.net/blog/</wfw:comment><wfw:commentRss>http://www.csksoft.net/blog/sydication.asp?cmt=301</wfw:commentRss><trackback:ping>http://www.csksoft.net/blog/cmd.asp?act=tb&amp;id=301&amp;key=18527570</trackback:ping></item><item><title>低成本激光投射虚拟键盘的设计制作-上(原理和硬件) </title><author>csk@live.com (csk)</author><link>http://www.csksoft.net/blog/post/lowcost.laserkbd_part1.html</link><pubDate>Sat, 22 Jun 2013 02:34:50 +0800</pubDate><guid>http://www.csksoft.net/blog/post/lowcost.laserkbd_part1.html</guid><description><![CDATA[<div class="quote">
<div style="text-align: left;">姗姗来迟的文章...先前在《无线电》杂志2012年9-10月刊登过，近期转到我blog上</div>
<div>转载注意：</div>
<div>请保留作者和出处。<a href="http://www.csksoft.net/blog/post/lowcost.laserkbd_part1.html">http://www.csksoft.net/blog/post/lowcost.laserkbd_part1.html</a></div>
<div>来源连接：</div>
</div>
<div>
<div>
<div class="quote">
<div>目前DFRobot正协助制作本设计的开源套件，感兴趣的朋友可以前去购买。详情见：</div>
<div><a href="http://www.robopeak.net/blog/?p=315">http://www.robopeak.net/blog/?p=315</a></div>
</div>
</div>
<div><a href="http://www.robopeak.net/blog/?p=315"></a></div>
<div>
<div>在制作3D激光扫描仪的过程中，我偶然在网络上发现有人销售可以投影出键盘画面的激光器组件，并且价格低廉。仔细想来其实激光投影键盘的原理和3D扫描仪一致，于是便产生了DIY一个低成本激光键盘的想法。最终，本作品在我完成3D扫描仪的3天内完成了，可见硬件部分的制作不复杂。虽然完成的时间短，但其中也涉及不少的设计细节需要考虑，于是便写了此文向大家分享我的制作过程。</div>
<div style="text-align: center; "><img src="http://www.robopeak.net/blog/wp-content/uploads/2013/05/prototype_vs_kit.jpg" width="80%" alt="" /><br />
</div>
<div>
<h1 class="std_h1">简介</h1>
</div>
<div>激光投射键盘相信大家之前也有所听说，他通过光学手段，将计算机键盘的画面通过激光投影到任意的平面上（如桌面）上，并且允许操作者像使用真实键盘那样进行输入操作。</div>
<div style="text-align: center; "><img src="/data/pic/laserkbd/002_celluon.gif" alt="" /><br />
</div>
<div style="text-align: center; ">图：Celluon公司出品的Magic Cube激光投影键盘</div>
<div style="text-align: center; "><br />
</div>
<div>目前市面上能买到的激光键盘产品是由韩国公司Celluon生产销售的。这类产品目前也可以在国内买到，不过因为价格高昂，目前仍旧在千元水平。我之前并没有购买过，具体使用效果也不得而知。有人评价说因为缺少物理反馈，这样的键盘使用上手感可能不好。</div>
<div><br />
</div>
<div>但无论如何，激光虚拟键盘还是非常能吸引眼球的，在投射出的键盘影像上输入非常有科技感并且足够科幻。如果能自己以较低成本DIY一台出来，那岂不是更好？</div>
<div><br />
</div>
<div>本文提出的DIY激光投影键盘方案可以保证使用较低的成本（百元左右），并提供较强的性能：30hz的输入频率、支持多键输入，并且还有额外的功能：把他当作多点输入设备来使用，比如可以作为绘图板，并能感应手指的压力大小。</div>
<div><br />
</div>
<div>在完成本制作后我拍摄了一段演示视频展现它的性能，可以访问如下地址观看：</div>
<div style="text-align: center; "><embed src="http://player.youku.com/player.php/sid/XMzIwMDc1Mjgw/v.swf" allowfullscreen="true" quality="high" width="480" height="400" align="middle" allowscriptaccess="always" type="application/x-shockwave-flash"></embed> </div>
<div><br />
</div>
<div>
<h1 class="std_h1">原理分析</h1>
</div>
<div><br />
</div>
<div>在具体介绍实现过程前，我们首先需要分析这类激光投影键盘的工作原理以及给出解决问题的思路，这样也可方便大家举一反三。首先需要解决的核心问题有这么两个：</div>
<div><br />
</div>
<div>
<ol>
    <li>如何产生键盘的画面？</li>
    <li>如何检测键盘输入事件？</li>
</ol>
</div>
<div><br />
</div>
<div>
<h2 class="std_h2">产生键盘画面</h2>
</div>
<div><br />
</div>
<div>对于产生键盘画面，可能很多人认为这种画面是通过激光+高速光学振镜来得到的。这种方式虽然在技术上是完全可行的，但由于需要采用精密的机械部件，成本非常高，并且也难以做成轻便的产品。</div>
<div style="text-align: center; ">&nbsp;<img src="/data/pic/laserkbd/003_laserprojection.jpg" alt="" /></div>
<div style="text-align: center; ">图：通过光学振镜扫描产生的激光投影画面。图片来自[1]</div>
<div><br />
</div>
<div>实际上在激光投影键盘产品中，这类画面往往是通过全息投影技术得到的。激光器通过照射先前保存有键盘画面的全息镜片的方式在目标平面上产生相应的画面。这种方式的成本非常低廉，市面销售的激光笔常配备的投影图案的镜头也是用这种原理产生的。</div>
<div><br />
</div>
<div style="text-align: center; ">&nbsp;<img src="/data/pic/laserkbd/004.jpg" alt="" /></div>
<div style="text-align: center; ">图：可以投射出图案的激光笔镜头</div>
<div><br />
</div>
<div>不过这类全息投影方式对于DIY来说仍旧不现实，幸好得益于目前网络的便利&mdash;&mdash;通过网购可以直接买到用于产生激光键盘画面的全息投影设备了，且成本在￥50以内。</div>
<div><br />
</div>
<div><br />
</div>
<div style="text-align: center; ">&nbsp;<img src="/data/pic/laserkbd/005.jpg" alt="" /></div>
<div style="text-align: center; ">图：可以购买到的投影键盘画面的激光器模组</div>
<div><br />
</div>
<div>
<h2 class="std_h2">识别键盘输入事件</h2>
</div>
<div><br />
</div>
<div>在解决了产生键盘画面的问题后，这里分析另一个看似简单的问题：如何判断键盘输入事件？</div>
<div><br />
</div>
<div>由于键盘画面可以投射在任意的表面上，因此传统的靠物理按钮的手段自然是不可能的（否则也称不上虚拟键盘）。需要非接触的手段来检测。这里给出了几种途径，他们在技术上都是可行的：</div>
<div><br />
</div>
<div><strong>1) 通过计算机视觉的方式，通过图像来识别</strong></div>
<div>通过摄像头捕捉键盘区域的画面并进行分析，判断出键盘输入事件。</div>
<div><strong>2) 通过检测按键发出的声音来判断</strong></div>
<div>这里假设使用者在按键时会碰触桌面，产生一定的敲击声。通过检测该声音传播时间，可以进行定位。该方案在国外的一些研究机构已经实现。</div>
<div><strong>3) 通过超声波雷达手段来判断</strong></div>
<div>通过发射超声波并检测反射波的传播时间查来检测目标物体（手指）的位置。</div>
<div><br />
</div>
<div>这3种方案国内外均有文献表明可以实现，不过相对来说计算机视觉的硬件较为简单，仅仅需要一个摄像头，因此这里我们采用这种方式。</div>
<div><br />
</div>
<div>下图给出了本制作早期阶段，摄像头所拍摄的使用过程的画面，基于这类画面进行计算机视觉的运算，可以得到我们需要的键盘事件：</div>
<div style="text-align: center; "><img src="/data/pic/laserkbd/006.png" alt="" /><br />
</div>
<div style="text-align: center; ">图：通过计算机视觉的方式识别并判断键盘输入事件</div>
<div><br />
</div>
<div>其实这里涉及到了2个子问题：</div>
<div>
<ol>
    <li>判断手指按下的是哪个键？</li>
    <li>如何判断手指已经&ldquo;按到&rdquo;了对应的&ldquo;按钮&rdquo;？</li>
</ol>
</div>
<div><br />
</div>
<div>由于我们人类就是通过视觉来理解外部世界的，因此很直观的可以想到，只要能够识别并定位画面中手指的位置，第一个问题就可以解决了。这里先不讨论定位本身该如何实现，假设我们的算法已经可以和人脑一样轻松在一副画面中找到手指的位置并用相对于图像的坐标来表示(x,y)。</div>
<div><br />
</div>
<div>接下来就要考虑第二个问题，如何判断手指已经&ldquo;按下按钮&rdquo;？这里一个办法是通过捕捉声音：即像前文提到的通过捕捉手指碰触桌面产生的敲击声来判断。但这样会带来额外的问题：</div>
<div><br />
</div>
<div>
<ol>
    <li>需要额外的硬件和电路，增加了复杂性</li>
    <li>如何将敲击声与画面中真正敲击的手指对应？就像上图中的5个手指都可能是在敲击状态，此时难以进行匹配</li>
    <li>其他的噪音也会被当作键盘敲击</li>
</ol>
</div>
<div><br />
</div>
<div>因此这里还是依靠视觉的手段来进行判断。在分析可行方案前，需要明确&ldquo;按下按钮&rdquo;的具体指标。我们可以定义当手指碰触桌面，或者距离桌面足够接近为&ldquo;按下&rdquo;。那么其实问题的实质就是我们需要检测出手指距离桌面的距离z。在求出该数值后，我们只需简单的判断它小于某一个值，就认为手指已经&ldquo;按下按键&rdquo;。</div>
<div><br />
</div>
<div>综合起来看，我们需要设计一种视觉处理算法：它可以在一副画面中找出每个手指相对画面的位置(x,y)，并且手指距离桌面的高度z。事实上我们就是在检测手指的三维空间坐标了(x,y,z)了。</div>
<div>&nbsp;</div>
<div style="text-align: center; "><img src="/data/pic/laserkbd/007.jpg" alt="" /><br />
</div>
<div style="text-align: center; ">图：需要设计的视觉检测算法和期望的检测结果</div>
<div><br />
</div>
<div>如果之前有阅读我的3D激光扫描仪制作的话，相信大家就能猜到具体的实现方式了，其实算法本身就是做三维的激光测距。不过这里我们先按照前文的思路继续分析下去：</div>
<div><br />
</div>
<div>做三维测量有很多种方式，比如现在可以购买微软的KINECT深度传感器。如果不考虑成本，这的确是一种非常有效的方法，可以非常好的解决本文提出的这些问题。另一种类似的办法是使用双摄像头来做双目视觉处理，提取目标画面物体的深度信息。不过目前这类处理比较消耗处理资源，且校正过程比较复杂，并不适合这里的应用。</div>
<div><br />
</div>
<div style="text-align: center; ">&nbsp;<img src="/data/pic/laserkbd/008_stereovision.png" alt="" /></div>
<div style="text-align: center; ">图：RoboPeak团队曾进行的双目视觉进行深度提取的实验</div>
<div><br />
</div>
<div>这里我们采用基于三角测距原理的激光测距仪[2]一致的办法，通过主动投射激光来做目标物体的三维坐标检测。在[2]中我使用一束线型激光照射目标物体，在目标物体的反射光被摄像头捕捉到，利用三角测距原理，可以求出目标物体中被线激光照亮部分的坐标信息。</div>
<div style="text-align: center; ">&nbsp;<img src="/data/pic/laserkbd/009_tri1.png" alt="" /></div>
<div style="text-align: center; ">在[2]中提到的利用线激光和单摄像头的3D测距原理</div>
<div><br />
</div>
<div>这里我们将线激光所产生的光线平面与桌面平行并紧贴在桌面之上，将摄像头放置于激光发射器上方并俯视桌面，如下图所示：</div>
<div><br />
</div>
<div style="text-align: center; ">&nbsp;<img src="/data/pic/laserkbd/010.gif" alt="" /></div>
<div style="text-align: center; ">图：利用激光三角测距原理用于手指空间坐标检测</div>
<div><br />
</div>
<div>此时若手指接近桌面，则会阻挡住激光的通路，产生反射，反射的光点画面会被图中摄像头拍摄到。这是一个标准的三角测距的结构设置。细心的读者可能已经发现在前文给出的本制作摄像头拍摄到的画面中手指尖部的白色光斑，这正是安装了线激光器后被手指遮挡产生的反射效果。</div>
<div><br />
</div>
<div style="text-align: center; ">&nbsp;<img src="/data/pic/laserkbd/011_irview.png" alt="" /></div>
<div style="text-align: center; ">图：本制作采用的线激光测距方案</div>
<div><br />
</div>
<div>对于这种基于线激光的测距的方式[2]，我们可以通过三角关系求出被激光照亮部分相对于激光发射口为原点、位于线激光组成平面内的坐标P(x,y)。而又因为线激光组成的平面与桌面平行，且在设计上这两个平面是紧贴着的，所以可以近似的认为坐标点P(x,y)是位于桌面平面的。</div>
<div><br />
</div>
<div>这样的设置具有几个优点：</div>
<div><br />
</div>
<div><strong>方便检测指尖</strong></div>
<div>当手指遮挡激光平面后产生了反射，因此会在摄像头画面中出现较为明亮的光斑，可以通过简单的视觉算法来提取指尖部分</div>
<div><br />
</div>
<div><strong>方便检测按键事件</strong></div>
<div>由于只有当手指靠近或者碰触到桌面才会遮挡住激光产生反光，而在距离桌面较高的位置则不会被检测算法察觉。因此这里检测按键事件可以做出简化，不需要通过检测手指距离桌面高度来判断。而只要当检测算法检测到手指反光，则可认为出现了按键事件，且可直接用当前检测到的坐标来进行后续的处理。</div>
<div><br />
</div>
<div>值得一提的是，事实上这样的方式对从事多点触摸领域朋友来说应该不陌生，有一种称为LLP(Laser Light Plane)的技术[4]和我们的方式很类似。</div>
<div style="text-align: center; "><img src="/data/pic/laserkbd/012_LLP.jpg" alt="" /><br />
</div>
<div style="text-align: center; ">图：LLP方式的多点触摸技术，图片来源自[5]</div>
<div><br />
</div>
<div>如上图所示，LLP技术也通过发射一束线型激光构造出一个光平面，并捕捉手指反光来做多点触摸定位。而摄像头的安装位置也并非一定位于上边示意图的底下，同样也可以安装在本制作一样的位置。事实上这里采用的激光测距方案的前期处理是和LLP一致的：提取手指指尖的兴趣点，并转换成相对于摄像头画面的坐标。不过对于多点触摸而言，不需要得到手指在桌面上的精确距离，就好比我们用的鼠标只需要知道一个相对位移的程度，而不需得到具体鼠标移动了多少毫米。但由于我们需要将手指的坐标转换成具体按键的信息，因此还有必要进行更进一步的处理。</div>
<div><br />
</div>
<div>不过相信有人会说这样的方法岂不是和之前通过求出指尖的三维坐标的方式的思路不同吗？的确目前的方式无法直接求得手指距离桌面的高度z。并且接触主动发射线激光的特性，通过求取z来判断是否存在按键事件也显得不必要了。但这并不表示我们无法求解手指距离桌面的高度，并且在后文我将指出，求出手指距离桌面的高度仍旧是有意义的。</div>
<div><br />
</div>
<div>
<h2 class="std_h2">判断并产生对应的按键事件</h2>
</div>
<div><br />
</div>
<div>前面我们已经解决了如何检测手指当碰触到桌面时指尖在桌面平面上的坐标P(x,y)。但这与我们最终要产生对应的按键事件还有一定距离。我们需要建立一个映射机制，通过桌面坐标P(x,y)找到对应按键键值，并最终通知操作系统触发一个对应键值的按键事件。</div>
<div><br />
</div>
<div>这里的做法与GUI系统进行UI元素碰撞判断的过程类似。在图形系统中，所有UI元素均保存有他们相对于屏幕的坐标值。GUI系统不停地判断当前鼠标指针位置是否落入了某一个按钮或者选择框的坐标范围内。</div>
<div style="text-align: center; "><img src="/data/pic/laserkbd/013.gif" alt="" /><br />
</div>
<div style="text-align: center; ">图：GUI系统通过对比鼠标坐标和按钮UI元素的坐标来判断鼠标是否存在于按钮元素上方</div>
<div><br />
</div>
<div>与GUI系统类似，我们首先需要建立投射键盘图案中每个按键的坐标信息。然后将指尖相对于桌面平面上的坐标P(x,y)映射到键盘图案的坐标系内进行按键的判断。</div>
<div style="text-align: center; ">&nbsp;<img src="/data/pic/laserkbd/014.gif" alt="" /></div>
<div style="text-align: center; ">图：将基于桌面平面以激光器为原点的指尖坐标P(x,y)映射到键盘坐标平面并进行按键判断</div>
<div><br />
</div>
<div>上述过程涉及到两个步骤：</div>
<div><br />
</div>
<div>1) 将以激光发射器为原点的指尖坐标P(x,y)映射到以键盘图案左上角为原点坐标的平面内，得到映射点P&rsquo;(x,y)</div>
<div>该过程用数学表达记作：</div>
<div>
<div class="quote">P' (x,y)=f<sub>projection</sub> (P(x,y))</div>
</div>
<div><br />
</div>
<div>2) 将映射点P&rsquo;(x,y)与事先记录的每个按键的坐标值比对，求得当前对应按下的按键值。</div>
<div>该过程记作：</div>
<div>
<div class="quote">Key[n]=f<sub>mapping</sub> (P' (x,y))</div>
</div>
<div><br />
</div>
<div>可能有人会问为何不直接按照以激光发射器原点的坐标来表示每个按键的坐标?这样第一步的映射f_projection就可以省略了。这的确也可以达到同样的效果。但是由于在组装上会存在误差，不能保证每次制作出来的成品激光发射器与键盘图案投射的位置都完全一致，并且单个成品在使用过程中也会因为热胀冷缩等原因，键盘图案会发生偏移。一旦键盘图案发生了移动，则先前以这种方式记录的所有按键坐标都需要重新测量。但如果一开始就以键盘左上角为原点的方式记录坐标，则每次组装完成品或者发生图案偏移后，则只需进行简单的矫正，求出一个新的f_projection函数即可。</div>
<div><br />
</div>
<div>对于步骤2)中的函数f_mapping，一种简单的实现是依次按照前文例图中的判断代码对每个按键轮流计算，判断是否被&ldquo;按下&rdquo;。这种方式实现简单直观，但是性能较差。对于这类问题，可以使用Kd-Tree的数据结构[3]进行快速的查找。</div>
<div><br />
</div>
<div>
<h2 class="std_h2">系统框图</h2>
</div>
<div><br />
</div>
<div>前面我们解决了制作激光投影键盘的两个关键问题，这里将我们最终采用方案的大致原理做出总结，方便大家理解。在实现过程部分，将具体就其中的实现细节做出介绍。</div>
<div><br />
</div>
<div style="text-align: center; ">&nbsp;<img src="/data/pic/laserkbd/015.gif" alt="" /></div>
<div><br />
</div>
<div>框图中还包含了本制作的另一个功能：多点触摸绘图板。该部分也将在具体制作过程中介绍。</div>
<div><br />
</div>
<div>
<h1 class="std_h1">实现过程</h1>
</div>
<div>
<h2 class="std_h2">器件选择</h2>
</div>
<div><br />
</div>
<div>有前面的原理分析可知，本激光键盘至少需要摄像头、投射键盘画面的激光器以及一字线激光。如下是我选用的器件和参数</div>
<div><br />
</div>
<div>
<div align="center">
<table class="MsoTableLightShadingAccent5" border="1" cellspacing="0" cellpadding="0" style="border-collapse:collapse;border:none;mso-border-top-alt:solid #4BACC6 1.0pt;    mso-border-top-themecolor:accent5;mso-border-bottom-alt:solid #4BACC6 1.0pt;    mso-border-bottom-themecolor:accent5;mso-yfti-tbllook:1184;mso-padding-alt:    0cm 5.4pt 0cm 5.4pt">
    <tbody>
        <tr>
            <td width="189" valign="top" style="width:142.0pt;border-top:solid #4BACC6 1.0pt;            mso-border-top-themecolor:accent5;border-left:none;border-bottom:solid #4BACC6 1.0pt;            mso-border-bottom-themecolor:accent5;border-right:none;padding:0cm 5.4pt 0cm 5.4pt">
            <p class="MsoNormal"><strong><span style="font-family:宋体;            mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:            宋体;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;            mso-hansi-theme-font:minor-latin;color:#31849B;mso-themecolor:accent5;            mso-themeshade:191">元件</span><span lang="EN-US" style="color:#31849B;            mso-themecolor:accent5;mso-themeshade:191"><o:p></o:p></span></strong></p>
            </td>
            <td width="189" valign="top" style="width:142.05pt;border-top:solid #4BACC6 1.0pt;            mso-border-top-themecolor:accent5;border-left:none;border-bottom:solid #4BACC6 1.0pt;            mso-border-bottom-themecolor:accent5;border-right:none;padding:0cm 5.4pt 0cm 5.4pt">
            <p class="MsoNormal"><strong><span style="font-family:宋体;            mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:            宋体;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;            mso-hansi-theme-font:minor-latin;color:#31849B;mso-themecolor:accent5;            mso-themeshade:191">核心参数</span><span lang="EN-US" style="color:#31849B;            mso-themecolor:accent5;mso-themeshade:191"><o:p></o:p></span></strong></p>
            </td>
        </tr>
        <tr>
            <td width="189" valign="top" style="width:142.0pt;border:none;background:#D2EAF1;            mso-background-themecolor:accent5;mso-background-themetint:63;padding:0cm 5.4pt 0cm 5.4pt">
            <p class="MsoNormal"><strong><span style="font-family:宋体;            mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:            宋体;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;            mso-hansi-theme-font:minor-latin;color:#31849B;mso-themecolor:accent5;            mso-themeshade:191">摄像头</span><span lang="EN-US" style="color:#31849B;            mso-themecolor:accent5;mso-themeshade:191"><o:p></o:p></span></strong></p>
            </td>
            <td width="189" valign="top" style="width:142.05pt;border:none;background:#D2EAF1;            mso-background-themecolor:accent5;mso-background-themetint:63;padding:0cm 5.4pt 0cm 5.4pt">
            <p class="MsoNormal"><span style="font-family:宋体;            mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:            宋体;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;            mso-hansi-theme-font:minor-latin;color:#31849B;mso-themecolor:accent5;            mso-themeshade:191">广角镜头，视角</span><span lang="EN-US" style="color:#31849B;            mso-themecolor:accent5;mso-themeshade:191">&gt;120</span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:            minor-latin;mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;            mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;color:#31849B;            mso-themecolor:accent5;mso-themeshade:191">度</span><span lang="EN-US" style="color:#31849B;mso-themecolor:accent5;mso-themeshade:191"><o:p></o:p></span></p>
            </td>
        </tr>
        <tr>
            <td width="189" valign="top" style="width:142.0pt;border:none;padding:0cm 5.4pt 0cm 5.4pt">
            <p class="MsoNormal"><strong><span style="font-family:宋体;            mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:            宋体;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;            mso-hansi-theme-font:minor-latin;color:#31849B;mso-themecolor:accent5;            mso-themeshade:191">投射键盘画面的激光器</span><span lang="EN-US" style="color:#31849B;            mso-themecolor:accent5;mso-themeshade:191"><o:p></o:p></span></strong></p>
            </td>
            <td width="189" valign="top" style="width:142.05pt;border:none;padding:0cm 5.4pt 0cm 5.4pt">
            <p class="MsoNormal"><span style="font-family:宋体;mso-ascii-font-family:Calibri;            mso-ascii-theme-font:minor-latin;mso-fareast-font-family:宋体;mso-fareast-theme-font:            minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;            color:#31849B;mso-themecolor:accent5;mso-themeshade:191">无特殊要求</span><span lang="EN-US" style="color:#31849B;mso-themecolor:accent5;mso-themeshade:191"><o:p></o:p></span></p>
            </td>
        </tr>
        <tr>
            <td width="189" valign="top" style="width:142.0pt;border:none;background:#D2EAF1;            mso-background-themecolor:accent5;mso-background-themetint:63;padding:0cm 5.4pt 0cm 5.4pt">
            <p class="MsoNormal"><strong><span style="font-family:宋体;            mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:            宋体;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;            mso-hansi-theme-font:minor-latin;color:#31849B;mso-themecolor:accent5;            mso-themeshade:191">一字线激光</span><span lang="EN-US" style="color:#31849B;            mso-themecolor:accent5;mso-themeshade:191"><o:p></o:p></span></strong></p>
            </td>
            <td width="189" valign="top" style="width:142.05pt;border:none;background:#D2EAF1;            mso-background-themecolor:accent5;mso-background-themetint:63;padding:0cm 5.4pt 0cm 5.4pt">
            <p class="MsoNormal"><span style="font-family:宋体;            mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:            宋体;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;            mso-hansi-theme-font:minor-latin;color:#31849B;mso-themecolor:accent5;            mso-themeshade:191">红外激光器，</span><span lang="EN-US" style="color:#31849B;            mso-themecolor:accent5;mso-themeshade:191">&gt;50mW<o:p></o:p></span></p>
            </td>
        </tr>
        <tr>
            <td width="189" valign="top" style="width:142.0pt;border:none;border-bottom:solid #4BACC6 1.0pt;            mso-border-bottom-themecolor:accent5;padding:0cm 5.4pt 0cm 5.4pt">
            <p class="MsoNormal"><strong><span style="font-family:宋体;            mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:            宋体;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;            mso-hansi-theme-font:minor-latin;color:#31849B;mso-themecolor:accent5;            mso-themeshade:191">红外带通滤光片</span><span lang="EN-US" style="color:#31849B;            mso-themecolor:accent5;mso-themeshade:191"><o:p></o:p></span></strong></p>
            </td>
            <td width="189" valign="top" style="width:142.05pt;border:none;border-bottom:            solid #4BACC6 1.0pt;mso-border-bottom-themecolor:accent5;padding:0cm 5.4pt 0cm 5.4pt">
            <p class="MsoNormal"><span lang="EN-US" style="color:#31849B;mso-themecolor:accent5;            mso-themeshade:191">800nm</span><span style="font-family:宋体;mso-ascii-font-family:            Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:宋体;            mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;            mso-hansi-theme-font:minor-latin;color:#31849B;mso-themecolor:accent5;            mso-themeshade:191">左右光谱带通</span><span lang="EN-US" style="color:#31849B;            mso-themecolor:accent5;mso-themeshade:191"><o:p></o:p></span></p>
            </td>
        </tr>
    </tbody>
</table>
</div>
</div>
<div><br />
</div>
<div>对于摄像头，这里一个比较关键的特性是需要采用广角镜头。目前的USB摄像头一般视角在90度左右，这样的摄像头需要在很高处俯视才能拍摄到完整的激光键盘图案，如果想把本投影键盘制作的小巧，则需要采用广角镜头，视角最好在120度以上。</div>
<div><br />
</div>
<div style="text-align: center; ">&nbsp;<img src="/data/pic/laserkbd/016.gif" alt="" /></div>
<div style="text-align: center; ">图：窄视角的摄像头需要安装在较高的位置</div>
<div><br />
</div>
<div>除了镜头外，摄像头本身没有特殊要求，一般市面VGA画质的普通USB摄像头即可满足要求。下图为我采用的镜头和摄像头照片：</div>
<div style="text-align: center; ">&nbsp;<img src="/data/pic/laserkbd/017.jpg" alt="" /></div>
<div style="text-align: center; ">图：两种不同视角的摄像头镜头，左边为窄视角镜头，右边为广角镜头</div>
<div><br />
</div>
<div style="text-align: center; ">&nbsp;&nbsp;<img src="/data/pic/laserkbd/018.jpg" alt="" /></div>
<div style="text-align: center; ">图：USB摄像头模组</div>
<div><br />
</div>
<div>对投射键盘图案的激光发射器模组前文已经提到，且没有特殊要求。</div>
<div><br />
</div>
<div style="text-align: center; ">&nbsp;<img src="/data/pic/laserkbd/019.jpg" alt="" /></div>
<div style="text-align: center; ">图：选用的激光键盘图案投射模组</div>
<div><br />
</div>
<div>对用于测距的激光发射器，只需要使用红外波段的一字线激光器，功率在50mW左右即可。为了安全考虑，不要使用过大功率的激光器。采用红外波段主要为了过滤可见光干扰，简化视觉处理中的兴趣点提取，同时也不会因为手指反射对投射的键盘图案产生干扰。</div>
<div style="text-align: center; ">&nbsp;<img src="/data/pic/laserkbd/020.jpg" alt="" /></div>
<div style="text-align: center; ">图：选用的红外线型激光器</div>
<div><br />
</div>
<div>
<h2 class="std_h2">摄像头改装</h2>
</div>
<div><br />
</div>
<div>在我之前的3D测距仪文章[2]中提到过使用红外激光器配合红外滤光片进行测距可有效避免可见光干扰的技巧，在这里也仍旧适用。对此我们需要对摄像头镜头做一些改造，首先拆除镜头上的红外光截至滤光片，并在镜头头部安装红外带通滤光片：</div>
<div><br />
</div>
<div style="text-align: center; ">&nbsp;<img src="/data/pic/laserkbd/021.jpg" alt="" /></div>
<div style="text-align: center; ">图：拆除镜头内的红外截止滤光片</div>
<div><br />
</div>
<div style="text-align: center; ">&nbsp;<img src="/data/pic/laserkbd/022.jpg" alt="" /></div>
<div style="text-align: center; ">图：在镜头表面安装红外带通滤光片</div>
<div><br />
</div>
<div>
<h2 class="std_h2">电子系统</h2>
</div>
<div><br />
</div>
<div>本制作的电子系统比较简单，仅仅涉及给两个激光发射器供电以及通过USB电缆连接摄像头至主机。并没有采用任何单片机，这样也意味着之前原理部分介绍的算法将完全在PC上实现。这样的优点是大幅降低了制作成本以及制作的难度。如果使用的是免驱动USB摄像头，在PC上使用本激光投影键盘只需要额外运行处理程序即可。不过缺点就是这样的设计无法给手机等不支持USB的设备使用。</div>
<div><br />
</div>
<div>由于摄像头已经使用了一条USB电缆，因此这里我们直接通过usb的5V供电来驱动另外2个激光器。电路很简单，如下图所示：</div>
<div><br />
</div>
<div style="text-align: center; ">&nbsp;<img src="/data/pic/laserkbd/023.png" alt="" /></div>
<div><br />
</div>
<div>可以看到电路的核心就是一个3.3V的LDO芯片而已，可以裁剪一个洞洞板制作：</div>
<div><br />
</div>
<div style="text-align: center; ">&nbsp;<img src="/data/pic/laserkbd/024.jpg" alt="" /></div>
<div style="text-align: center; ">图：使用小块洞洞板制作简易的驱动电路</div>
<div><br />
</div>
<div>
<h2 class="std_h2">总体安装</h2>
</div>
<div><br />
</div>
<div>由前面的分析可以得到如下的安装结构：</div>
<div style="text-align: center; ">&nbsp;<img src="/data/pic/laserkbd/025.jpg" alt="" /></div>
<div>其中线型激光器需要安装在设备的最底下并紧靠底部，这样可以保证产生的激光平面能够尽可能的靠近桌面平面。在激光器上方安装投射键盘图案的激光模组，他的高度以能够投射出与常规键盘尺寸大小类似的图案来决定。在最顶端安装摄像头，其高度取决于摄像头能够完整拍摄整个键盘图案画面为宜。</div>
<div><br />
</div>
<div>我使用一块轻质木材作为安装这3个部件的整体支架：</div>
<div><br />
</div>
<div style="text-align: center; ">&nbsp;<img src="/data/pic/laserkbd/026.jpg" alt="" /></div>
<div style="text-align: center; ">图：将激光器安装在木板最底部，使用热熔胶固定</div>
<div style="text-align: center; ">&nbsp;<img src="/data/pic/laserkbd/027.jpg" alt="" /></div>
<div style="text-align: center; ">图：安装图案投射模块和摄像头并点亮</div>
<div style="text-align: center; ">&nbsp;<img src="/data/pic/laserkbd/028.jpg" alt="" /></div>
<div style="text-align: center; ">图：在木板背面安装稳压电路板和所有供电连线</div>
<div style="text-align: center; ">&nbsp;<img src="/data/pic/laserkbd/029.jpg" alt="" /></div>
<div style="text-align: center; ">图：将木板装入一个牢固的纸盒</div>
<div><br />
</div>
<div style="text-align: center; ">&nbsp;<img src="/data/pic/laserkbd/030.jpg" alt="" /></div>
<div style="text-align: center; ">图：完成并通电</div>
<div style="text-align: center; ">&nbsp;<img src="/data/pic/laserkbd/031.jpg" alt="" /></div>
<div style="text-align: center; ">图：顶部加装一个&ldquo;保护罩&rdquo;</div>
<div><br />
</div>
<div>最终本制作的实体部分组装完毕，接下来将介绍本制作的重点：视觉算法部分。</div>
</div>
</div>
<div>后篇：<a href="http://www.csksoft.net/blog/post/lowcost.laserkbd_part2.html">http://www.csksoft.net/blog/post/lowcost.laserkbd_part2.html</a></div>]]></description><category>Design&amp;amp;Engineering</category><comments>http://www.csksoft.net/blog/post/lowcost.laserkbd_part1.html#comment</comments><wfw:comment>http://www.csksoft.net/blog/</wfw:comment><wfw:commentRss>http://www.csksoft.net/blog/sydication.asp?cmt=299</wfw:commentRss><trackback:ping>http://www.csksoft.net/blog/cmd.asp?act=tb&amp;id=299&amp;key=115ad154</trackback:ping></item><item><title>低成本激光投射虚拟键盘的设计制作-下(算法与实现)</title><author>csk@live.com (csk)</author><link>http://www.csksoft.net/blog/post/lowcost.laserkbd_part2.html</link><pubDate>Sat, 22 Jun 2013 00:20:24 +0800</pubDate><guid>http://www.csksoft.net/blog/post/lowcost.laserkbd_part2.html</guid><description><![CDATA[<div class="quote">
<div style="text-align: left;">姗姗来迟的文章...先前在《无线电》杂志2012年9-10月刊登过，近期转到我blog上</div>
<div>转载注意：</div>
<div>请保留作者和出处。</div>
<div>来源连接：<a href="http://www.csksoft.net/blog/post/lowcost.laserkbd_part1.html">http://www.csksoft.net/blog/post/lowcost.laserkbd_part2.html</a></div>
</div>
<div>
<div>
<div class="quote">
<div>目前DFRobot正协助制作本设计的开源套件，感兴趣的朋友可以前去购买。详情见：</div>
<div><a href="http://www.robopeak.net/blog/?p=315">http://www.robopeak.net/blog/?p=315</a></div>
</div>
</div>
<div><a href="http://www.robopeak.net/blog/?p=315"></a></div>
<div>接上一篇：-上(原理和硬件) &nbsp;<a href="http://www.csksoft.net/blog/post/lowcost.laserkbd_part1.html">http://www.csksoft.net/blog/post/lowcost.laserkbd_part1.html</a></div>
<div><br />
</div>
<div style="text-align: left;">
<div>
<h2 class="std_h2">3.5.<span class="Apple-tab-span" style="white-space:pre">	</span>前期视觉处理</h2>
</div>
<div><br />
</div>
<div>由于本制作的视觉处理部分都在PC上进行，因此我使用了OpenCV[6]库来加速视觉运算代码的开发。在进行原理部分提到的手指尖提取和坐标求解前，需要对摄像头捕获的原始画面做一些前期的处理，方便后续的计算。</div>
<div><br />
</div>
<div><strong>3.5.1.<span class="Apple-tab-span" style="white-space:pre">	</span>镜头扭曲矫正</strong></div>
<div><br />
</div>
<div>由于我们使用了广角镜头，因此摄像头拍摄到的画面会存在比较明显的扭曲，就如下图所示：</div>
<div style="text-align: center; "><img src="/data/pic/laserkbd/032.gif" alt="" /><br />
</div>
<div>
<div>这样扭曲的画面难以直接进行处理计算出后续需要的坐标信息，因为这种扭曲变换是非线性的。因此这里首先需要对摄像头镜头进行校正。在之前的文章[2]中有对摄像头矫正技术的介绍，这里我仍旧使用matlab的摄像头校正工具[7]进行校正。在OpenCV中也提供了相关函数和工具可以对摄像头校正，不过很多人反映相比matlab的算法，OpenCV函数校正得到的结果略差。</div>
<div><br />
</div>
<div>在使用Chessboard图案完整校正后，可使用OpenCV的cvInitUndistortRectifyMap/ cvRemap函数通过校正数据将扭曲的画面重新修正。</div>
</div>
<div style="text-align: center; "><img src="/data/pic/laserkbd/033.jpg" alt="" /><br />
</div>
<div>
<div style="text-align: center;">图：将左侧广角镜头的原始画面进行扭曲修正，得到右侧画面</div>
<div><br />
</div>
<div>这里有一点需要注意，在先前的安装阶段我们提到摄像头需要安装红外带通滤光片。但在安装滤光片后，由于可见光都被过滤，因此之后无法再进行上述的镜头校正。因此这部分的校正工作需要先于红外滤光片的安装进行。</div>
</div>
<div>
<div><strong>3.5.2.<span class="Apple-tab-span" style="white-space:pre">	</span>滤波</strong></div>
<div><br />
</div>
<div>由于摄像头镜头加装了红外带通滤光片，可见光可以有效地被阻挡，因此在摄像头捕获的画面上基本只含有手指对红外激光的反射。</div>
</div>
<div style="text-align: center; "><img src="/data/pic/laserkbd/034.jpg" alt="" /><br />
</div>
<div>
<div style="text-align: center;">图：红外带通滤光片有效地过滤了可见光干扰</div>
<div><br />
</div>
<div>对于这样的画面基本上是可以直接进行后续的视觉处理的，不过一般我们还需要额外进行几个步骤：灰度化、高斯滤波、阈值化、形态学滤波</div>
<div><br />
</div>
<div>灰度化即将原先RGB色彩的彩色图像转化成灰度图，因为后续的视觉算法并不关心色彩信息，但需要反射光亮度，使用灰度表示后可以大幅加速处理速度。高斯滤波(Gauss Filter)、阈值化（Threshold）、形态学滤波（Morphology Filter）用于过滤画面中的噪点并且使得反射光斑变得平滑和连贯。如果不熟悉这部分概念，可以参考Digital Image Processing一书[8]。这几步操作在OpenCV中均有对应函数可以实现。</div>
</div>
<div style="text-align: center; "><img src="/data/pic/laserkbd/035.jpg" alt="" /><br />
</div>
<div>
<div style="text-align: center;">图：对图像进行各类滤波处理后的效果</div>
<div><br />
</div>
<div>上图展现了经过上述滤波算法后，手指尖激光反光光斑处理后的效果。可以看到，原先光斑外围的反射光干扰以及两个比较靠近的指尖之间&ldquo;黏连&rdquo;的光斑已经有效地过滤掉了。通过一系列的滤波过程，使得我们可以很精确的求出指尖的坐标。</div>
</div>
<div>
<div>
<h2 class="std_h2">3.6.<span class="Apple-tab-span" style="white-space:pre">	</span>兴趣点提取</h2>
</div>
<div><br />
</div>
<div>可以使用OpenCV提供的cvFindContours对先前与处理得到的光斑画面进行轮廓提取，进而求解出每个光斑区域在图像中的位置。进一步的，我们通过质心法并以光斑亮度作为权重，可以大致求解出每个指尖中心的大致坐标。虽然这个中心坐标未必真的在指尖中心，但相比简单的以光斑区域中心作为指尖中心的方法要精确很多。</div>
<div style="text-align: center; "><img src="/data/pic/laserkbd/036.jpg" alt="" /><br />
</div>
</div>
<div style="text-align: center;">图：使用轮廓提取手段提取出来的手指区域坐标</div>
<div>
<div>
<h2 class="std_h2">3.7.<span class="Apple-tab-span" style="white-space: pre;">	</span>手指坐标计算和校正</h2>
</div>
<div><br />
</div>
<div>在得到了手指光斑中心点相对于画面坐标之后，可以通过三角测距的方法，把手指在桌面平面内的坐标P(x,y)求出来。</div>
<div>该过程可以类比在激光3D测距中的算法，如下图所示：</div>
</div>
<div style="text-align: center; "><img src="/data/pic/laserkbd/037.jpg" alt="" /><br />
</div>
<div>
<div style="text-align: center;">图：将指尖坐标求解问题转化成3D激光测距问题</div>
<div><br />
</div>
<div>我们可以把兴趣点画面顺时针旋转90度，即将图像的X/Y轴相互交换，并在兴趣点之间连接起直线，如上图(b)所示。就会发现这样的画面就和[2]中进行3D激光测距出现的激光扫描线类似，如上图(c)。因此，我们可以按照[2]中推导的公式，求出画面中每个兴趣点的真实坐标（即以激光器为原点，桌面所在平面的坐标系坐标）</div>
<div><br />
</div>
<div>这部分的具体原理和公式推导请参考文章[2]。为了能够进行精确的激光测距，我们也需要和[2]中描述的那样对本制作进行校正。校正方法与[2]一样，可以在投影键盘前方用直尺做测量并进行曲线拟合。</div>
</div>
<div style="text-align: center; "><img src="/data/pic/laserkbd/038.jpg" alt="" /><br />
</div>
<div>
<div style="text-align: center;">图：对激光测距部分进行校正</div>
<div><br />
</div>
<div>经过本轮的运算，我们可以得到先前监测到的兴趣点在桌面平面坐标下的表示，测试坐标值具有了物理意义，均以毫米为单位表示。</div>
</div>
<div style="text-align: center; "><img src="/data/pic/laserkbd/039.jpg" alt="" /><br />
</div>
<div>
<div>
<h2 class="std_h2">3.8.<span class="Apple-tab-span" style="white-space:pre">	</span>按键映射和校正</h2>
</div>
<div><br />
</div>
<div>在得到了以桌面坐标平面表示的指尖坐标P(x,y)后，我们需要再进行校正得到前文提到的映射函数</div>
</div>
<div>
<div class="quote">P' (x,y)=f<sub>projection</sub> (P(x,y))</div>
</div>
<div>
<div>该部分的校正比较容易，可以将手指放置在键盘图案的某几个&ldquo;按键&rdquo;上，然后将当前的坐标P(x,y)与所&ldquo;按&rdquo;&ldquo;按键&rdquo;在键盘图案的坐标P_key (x,y)做一下对比。</div>
<div><br />
</div>
<div>理想状态下，每个P(x,y)与对应的P_key (x,y)都偏差了一个固定的位移量D。不过由于校正中会带来误差，每次测量时的偏差量D&rsquo;与理想的位移量都存在一个误差偏移Derror。即</div>
</div>
<div>
<div class="quote">P<sub>key</sub> (x,y)=P(x,y)+D+ Derror</div>
</div>
<div>这里我们就可以采用多次测量，并进行最小二乘拟合的方式，把Derror给消除掉，得到近似于D的一个校正值。因此，这里的映射函数就是：</div>
<div>
<div class="quote">P' (x,y)=P(x,y)+D</div>
</div>
<div>另外这里也需要把键盘图案的坐标事先保存下来。我直接对投影在桌面上的键盘图案进行了测量，并按照如下格式保存在程序当中：</div>
<div style="text-align: center; "><img src="/data/pic/laserkbd/040.jpg" alt="" /><br />
</div>
<div>
<div style="text-align: center;">图：使用一维数组，保存每个按键中心点的坐标(x,y)，按键的尺寸，以及按键的键值</div>
<div><br />
</div>
<div>在有了上述数据后，一方面我们可以使用Kd-tree来快速查找到所按下的按键ID。及前文所说的函数</div>
</div>
<div>
<div class="quote">Key[n]=f<sub>mapping</sub> (P' (x,y))</div>
</div>
<div>
<div>这里的f_mapping在我的实现中，就是一个Kd-tree。相比循环查找的O(n)复杂度，Kd-tree可以在O(log(n))的时间复杂度下，找到距离点P&rsquo;(x,y)最接近的元素，因此非常高效率。</div>
<div><br />
</div>
<div>目前OpenCV中提供了Kd-tree的实现，不过我在使用过程中遇到了诸多问题，尤其它可能会导致程序crash，因此我使用了由Martin F. Krafft开发的基于C++模板的Kd-tree实现libkdtree++[9]。</div>
</div>
<div><br />
</div>
<div>得到键盘图案坐标后的另一个好处是可以在PC上重新绘制出一个软键盘，用于提示当前&ldquo;按下&rdquo;的按键，提高使用体验：</div>
<div style="text-align: center; "><img src="/data/pic/laserkbd/041.png" alt="" /><br />
</div>
<div style="text-align: center; ">图：将坐标映射到对应&ldquo;按下&rdquo;的按键，并提供视觉反馈</div>
<div>
<div>
<h2 class="std_h2">3.9.<span class="Apple-tab-span" style="white-space:pre">	</span>键盘事件摸拟注入</h2>
</div>
<div><br />
</div>
<div>在得到用户按下键盘按键的信息后，就要考虑将这些按键注入到当前的系统中，使得我们的投影键盘能够作为一个真正的键盘来使用。这里我没有采用最直接的编写系统驱动程序的办法，虽然那样性能最好最直接，但会额外增加制作时间。我采用Windows系统提供的SendInput API[10]向系统注入键盘事件。该API允许应用程序向整个系统注入任意的键盘事件，在实际效果上，已经和编写驱动程序的效果没有区别。像系统输入法等特性也可以很好的支持。另外，这样做也可以保证我们所有的处理程序都在用户态模式运行，可以很容易的把我们的代码移植到MacOS或者Linux下运行。</div>
</div>
<div style="text-align: center;"><img src="/data/pic/laserkbd/042.png" alt="" /><br />
</div>
<div>
<div style="text-align: center;">图：本制作可以很好的使用中文输入法</div>
<div>不过前面我们得到的按下按键信息还不能直接注入到系统，还需要额外处理如下两件逻辑：</div>
<div>1)<span class="Apple-tab-span" style="white-space:pre">	</span>模拟组合键</div>
<div>2)<span class="Apple-tab-span" style="white-space:pre">	</span>模拟连发事件</div>
<div><br />
</div>
<div>对于组合键的模拟其实比较容易，一方面我们的设计可以保证多按键同时输入，对于Ctrl+C这样的组合键，其实不需要做额外处理，只要将当前的实际按键传输给OS即可。而对于键盘的功能键，比如Fn+F1这种特殊用途的按键，就需要编写程序特殊实现。</div>
<div>对于连发事件OS就没有提供什么特殊帮助了，需要我们自己来模拟。</div>
</div>
<div>
<div>
<h2 class="std_h2">3.10.<span class="Apple-tab-span" style="white-space:pre">	</span>检测手指对桌面的压力与多点触摸版应用</h2>
</div>
<div><br />
</div>
<div>在本制作的介绍视频中，我演示了本制作可以检测出手指对桌面的&ldquo;压力&rdquo;，从而在绘图板应用中能够产生不同粗细画笔的应用。</div>
<div style="text-align: center;"><img src="/data/pic/laserkbd/043.png" alt="" /><br />
</div>
</div>
<div>
<div style="text-align: center;">图：本制作的另一应用，多点绘图板</div>
<div><br />
</div>
<div>上图中可以发现绘制的线条的粗细不是固定的，线条的粗细是正是通过估算手指对桌面的&ldquo;压力&rdquo;决定的。</div>
<div><br />
</div>
<div>在前文原理介绍中已经知道，我们是无法真正得到手指对桌面的压力的。一切的信息都是通过摄像头的画面捕捉得来。这里估算的压力，是通过先前兴趣点提取阶段计算出的光斑面积得出的：</div>
</div>
<div style="text-align: center;"><img src="/data/pic/laserkbd/044.jpg" alt="" /><br />
</div>
<div>
<div style="text-align: center;">图：通过兴趣点区域面积估算&ldquo;压力&rdquo;</div>
<div><br />
</div>
<div>如上图(b)所示，程序使用了不同直径的圆圈表示两个投影点对应手指的不同&ldquo;压力&rdquo;。而参考他们对应的兴趣点尺寸(a)可以发现，面积比较大的兴趣点区域往往也认为&ldquo;压力&rdquo;比较大（注意两个画面是上下颠倒关系）。</div>
<div><br />
</div>
<div>这样的估算其实也有一定的现实依据，因为当手指紧压桌面时候，指尖反射激光的面积会变大。不过直接使用面积大小作为压力大小的话就会出现问题。就如上图(c)所示，从兴趣点面积看，画面下侧的兴趣点面积显然比上边的大很多。不过这未必是因为对应的一个手指用力压着桌面而另一个没有用力造成的。大家都知道按照投影变换，距离镜头比较远的物体就算尺寸相同，与会显得比较小。在这里两个兴趣点也是同样的情况，所设计的算法需要考虑到这个问题，得到尽可能真实的&ldquo;压力&rdquo;估算，如上图(d)所示，本算法最终估算的两者&ldquo;压力&rdquo;几乎类似。</div>
<div><br />
</div>
<div>这里采用的手段很简单，因为我们可以通过三角测距原则计算出画面中任意点的真实物理坐标，因此可以摆脱投影变换的干扰。具体做法是除了每个兴趣点中心区域求解对应的物理坐标P(x,y)之外，我们对兴趣区域边框上的某一个点也求出他的真实坐标P2(x,y)。由于P(x,y)和P2(x,y)反应了真实世界的两点坐标，用他们之间的距离就可以比较真实的估算出手指的&ldquo;压力&rdquo;</div>
</div>
<div style="text-align: center;"><img src="/data/pic/laserkbd/045.jpg" alt="" /><br />
</div>
<div style="text-align: center;">图：将兴趣点和兴趣区域边缘一点分别进行测距求解坐标，并以物理坐标点之间的距离估算&ldquo;压力&rdquo;</div>
<div>
<div>
<h2 class="std_h2">3.11.<span class="Apple-tab-span" style="white-space:pre">	</span>程序总体界面和完成图</h2>
</div>
<div><br />
</div>
<div>完成了上述几个核心功能后，我在用OpenCV的绘图功能做了一个简易的程序界面，前面提到的每个处理状态都会实时的在界面中展现。就此大功告成！</div>
</div>
<div style="text-align: center;"><img src="/data/pic/laserkbd/046.png" alt="" /><br />
</div>
<div style="text-align: center;">图：程序界面</div>
<div style="text-align: center;"><img src="/data/pic/laserkbd/047.png" alt="" /><br />
</div>
<div>
<div style="text-align: center;">图：使用照片</div>
<div><br />
</div>
<div>
<h1 class="std_h1">4.<span class="Apple-tab-span" style="white-space:pre">	</span>讨论和下一步工作</h1>
</div>
<div><br />
</div>
<div>
<div>虽然制作成本低廉，但得益于在算法上的优势，本激光投影键盘的性能并不差。我并没有用过Celluon公司销售的激光投影键盘产品，因此无法与它们的产品做出比较，这里就单独按照我自己的使用感受以及性能做出评价。</div>
<div><br />
</div>
<div>得益于采用了[2]中描述的测距算法，该激光键盘可以识别出0.1mm的细微手指移动，并且通过校正可以达到2mm的最大误差水平。另外理论上通过视觉定位算法，本制作可以支持任意多个按键同时输入。而在输入响应速度上，由于采用的usb摄像头是30fps的，所以本键盘的最快响应频率就是30Hz，这虽然不敌传统键盘100hz以上的速度，但作为日常使用来说是足够了。</div>
</div>
</div>
<div>
<table class="MsoTableLightShadingAccent5" border="1" cellspacing="0" cellpadding="0" style="border-collapse:collapse;border:none;mso-border-top-alt:solid #4BACC6 1.0pt;    mso-border-top-themecolor:accent5;mso-border-bottom-alt:solid #4BACC6 1.0pt;    mso-border-bottom-themecolor:accent5;mso-yfti-tbllook:1184;mso-padding-alt:    0cm 5.4pt 0cm 5.4pt">
    <tbody>
        <tr>
            <td width="284" valign="top" style="width:213.05pt;border-top:solid #4BACC6 1.0pt;            mso-border-top-themecolor:accent5;border-left:none;border-bottom:solid #4BACC6 1.0pt;            mso-border-bottom-themecolor:accent5;border-right:none;padding:0cm 5.4pt 0cm 5.4pt">
            <p class="MsoNormal"><strong><span style="font-family: 宋体;">性能指标<span lang="EN-US"><o:p></o:p></span></span></strong></p>
            </td>
            <td width="284" valign="top" style="width:213.05pt;border-top:solid #4BACC6 1.0pt;            mso-border-top-themecolor:accent5;border-left:none;border-bottom:solid #4BACC6 1.0pt;            mso-border-bottom-themecolor:accent5;border-right:none;padding:0cm 5.4pt 0cm 5.4pt">
            <p class="MsoNormal"><strong><span style="font-family: 宋体;">描述<span lang="EN-US"><o:p></o:p></span></span></strong></p>
            </td>
        </tr>
        <tr>
            <td width="284" valign="top" style="width:213.05pt;border:none;background:#D2EAF1;            mso-background-themecolor:accent5;mso-background-themetint:63;padding:0cm 5.4pt 0cm 5.4pt">
            <p class="MsoNormal"><strong><span style="font-family:宋体;            mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:            宋体;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;            mso-hansi-theme-font:minor-latin;color:#31849B;mso-themecolor:accent5;            mso-themeshade:191">反应速度</span><span lang="EN-US" style="color:#31849B;            mso-themecolor:accent5;mso-themeshade:191"><o:p></o:p></span></strong></p>
            </td>
            <td width="284" valign="top" style="width:213.05pt;border:none;background:#D2EAF1;            mso-background-themecolor:accent5;mso-background-themetint:63;padding:0cm 5.4pt 0cm 5.4pt">
            <p class="MsoNormal"><span lang="EN-US" style="color:#31849B;mso-themecolor:accent5;mso-themeshade:191">30hz<o:p></o:p></span></p>
            </td>
        </tr>
        <tr>
            <td width="284" valign="top" style="width:213.05pt;border:none;padding:0cm 5.4pt 0cm 5.4pt">
            <p class="MsoNormal"><strong><span style="font-family:宋体;            mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:            宋体;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;            mso-hansi-theme-font:minor-latin;color:#31849B;mso-themecolor:accent5;            mso-themeshade:191">最多同时输入的按键（多点触摸点数）</span><span lang="EN-US" style="color:#31849B;mso-themecolor:accent5;mso-themeshade:191"><o:p></o:p></span></strong></p>
            </td>
            <td width="284" valign="top" style="width:213.05pt;border:none;padding:0cm 5.4pt 0cm 5.4pt">
            <p class="MsoNormal"><span style="font-family:宋体;mso-ascii-font-family:Calibri;            mso-ascii-theme-font:minor-latin;mso-fareast-font-family:宋体;mso-fareast-theme-font:            minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;            color:#31849B;mso-themecolor:accent5;mso-themeshade:191">无穷多（软件目前限制在</span><span lang="EN-US" style="color:#31849B;mso-themecolor:accent5;mso-themeshade:191">10</span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:            minor-latin;mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;            mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;color:#31849B;            mso-themecolor:accent5;mso-themeshade:191">点）</span><span lang="EN-US" style="color:#31849B;mso-themecolor:accent5;mso-themeshade:191"><o:p></o:p></span></p>
            </td>
        </tr>
        <tr>
            <td width="284" valign="top" style="width:213.05pt;border:none;background:#D2EAF1;            mso-background-themecolor:accent5;mso-background-themetint:63;padding:0cm 5.4pt 0cm 5.4pt">
            <p class="MsoNormal"><strong><span style="font-family:宋体;            mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:            宋体;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;            mso-hansi-theme-font:minor-latin;color:#31849B;mso-themecolor:accent5;            mso-themeshade:191">分辨率</span><span lang="EN-US" style="color:#31849B;            mso-themecolor:accent5;mso-themeshade:191"><o:p></o:p></span></strong></p>
            </td>
            <td width="284" valign="top" style="width:213.05pt;border:none;background:#D2EAF1;            mso-background-themecolor:accent5;mso-background-themetint:63;padding:0cm 5.4pt 0cm 5.4pt">
            <p class="MsoNormal"><span lang="EN-US" style="color:#31849B;mso-themecolor:accent5;mso-themeshade:191">0.1mm<o:p></o:p></span></p>
            </td>
        </tr>
        <tr>
            <td width="284" valign="top" style="width:213.05pt;border:none;padding:0cm 5.4pt 0cm 5.4pt">
            <p class="MsoNormal"><strong><span style="font-family:宋体;            mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:            宋体;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;            mso-hansi-theme-font:minor-latin;color:#31849B;mso-themecolor:accent5;            mso-themeshade:191">最大测距误差</span><span lang="EN-US" style="color:#31849B;            mso-themecolor:accent5;mso-themeshade:191"><o:p></o:p></span></strong></p>
            </td>
            <td width="284" valign="top" style="width:213.05pt;border:none;padding:0cm 5.4pt 0cm 5.4pt">
            <p class="MsoNormal"><span lang="EN-US" style="color:#31849B;mso-themecolor:accent5;            mso-themeshade:191">2mm<o:p></o:p></span></p>
            </td>
        </tr>
        <tr>
            <td width="284" valign="top" style="width:213.05pt;border:none;border-bottom:            solid #4BACC6 1.0pt;mso-border-bottom-themecolor:accent5;background:#D2EAF1;            mso-background-themecolor:accent5;mso-background-themetint:63;padding:0cm 5.4pt 0cm 5.4pt">
            <p class="MsoNormal"><strong><span style="font-family:宋体;            mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:            宋体;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;            mso-hansi-theme-font:minor-latin;color:#31849B;mso-themecolor:accent5;            mso-themeshade:191">传输协议</span><span lang="EN-US" style="color:#31849B;            mso-themecolor:accent5;mso-themeshade:191"><o:p></o:p></span></strong></p>
            </td>
            <td width="284" valign="top" style="width:213.05pt;border:none;border-bottom:            solid #4BACC6 1.0pt;mso-border-bottom-themecolor:accent5;background:#D2EAF1;            mso-background-themecolor:accent5;mso-background-themetint:63;padding:0cm 5.4pt 0cm 5.4pt">
            <p class="MsoNormal"><span lang="EN-US" style="color:#31849B;mso-themecolor:accent5;mso-themeshade:191">USB<o:p></o:p></span></p>
            </td>
        </tr>
    </tbody>
</table>
</div>
<div>不过由于不是实体键盘，无法提供物理反馈，因此无法进行盲打，输入速度也不够快。这点我相信Celluon公司的产品也有同样的问题。就我们这个DIY作品来说，相信它应该是一个成功的作品。</div>
<div>
<div>
<h2 class="std_h2">下一步工作</h2>
</div>
<div><br />
</div>
<div>虽然本制作已经完满达到当初的设计要求，不过还有不少可以改善的地方。这里我就当是抛砖引玉给大家一个借鉴，欢迎大家在此基础上做出更多的扩展。</div>
<div><br />
</div>
<div>就装置尺寸上就有很多可以改进的余地，比如大家会发现本制作的体积要比Celluon公司产品大很多，这主要是因为我们采用的摄像头镜头的视角仍旧不够大，需要安装在较高的高度上。</div>
<div><br />
</div>
<div>另外就定位算法而言，其实也有不少可以优化的地方，比如其实我们未必需要那么高精度的激光定位数据，如果只是简单的作为键盘输入的话，可以降低测距精度，或者完全使用其他算法来实现按键识别的过程。</div>
<div><br />
</div>
<div>另外目前的设计需要在PC上进行所有的视觉运算，这样的好处是大幅降低了制作成本和难度，但缺点也很明显：无法在手机等设备上使用。当然现在的智能手机一般带有USB OTG功能，可以外接usb设备，同时OpenCV也可以在Android、iOS等移动设备上运行，因此这里的实现仍旧可以通过移植运行在这些移动设备上。不过如果将这些算法移植到嵌入式芯片，比如DSP或者ARM内，则可以完全摆脱对PC的依赖。键盘自身就可处理所有视觉计算并直接输出按键事件，也可以加装WIFI或者蓝牙，做成无线传输。这其实也并不是个遥不可及的改进，不过那样的话，我们的制作就足以与Celluon的产品竞争了</div>
</div>
<div>
<div>
<h1 class="std_h1">5.<span class="Apple-tab-span" style="white-space:pre">	</span>参考文献</h1>
</div>
<div><br />
</div>
<div>[1] RGB laser projector &ndash; 0,5W</div>
<div>http://www.edaboard.com/thread230353.html</div>
<div><br />
</div>
<div>[2] 自制低成本3D激光扫描测距仪(3D激光雷达)，第一部分</div>
<div>http://www.csksoft.net/blog/post/lowcost_3d_laser_ranger_1.html</div>
<div><br />
</div>
<div>[3] short for k-dimensional tree</div>
<div>http://en.wikipedia.org/wiki/K-d_tree</div>
<div><br />
</div>
<div>[4] Multi-Touch Technologies, NUI Group Authors</div>
<div>http://nuicode.com/attachments/download/115/Multi-Touch_Technologies_v1.01.pdf</div>
<div><br />
</div>
<div>[5] Tacchi is SigMusic's 46&quot; fully multitouch table.</div>
<div>http://www.acm.uiuc.edu/sigmusic/tacchi.html</div>
<div><br />
</div>
<div>[6] OpenCV (Open Source Computer Vision) is a library of programming functions for real time computer vision.</div>
<div>http://opencv.org/</div>
<div><br />
</div>
<div>[7] Camera Calibration Toolbox for Matlab</div>
<div>http://www.vision.caltech.edu/bouguetj/calib_doc/</div>
<div><br />
</div>
<div>[8] Digital Image Processing, Second Edition, ISBN: 0-201-18075-8</div>
<div><br />
</div>
<div>[9] libkdtree++ is an STL-like C++ template container implementation of k-dimensional space sorting, using a kd-tree</div>
<div>http://libkdtree.alioth.debian.org/</div>
<div><br />
</div>
<div>[10] SendInput Win32 API</div>
<div>http://msdn.microsoft.com/en-us/library/windows/desktop/ms646310(v=vs.85).aspx</div>
</div>
<div><br />
</div>
</div>
</div>
<div>
<div>
<div>
<div> </div>
</div>
</div>
</div>]]></description><category>Design&amp;amp;amp;Engineering</category><comments>http://www.csksoft.net/blog/post/lowcost.laserkbd_part2.html#comment</comments><wfw:comment>http://www.csksoft.net/blog/</wfw:comment><wfw:commentRss>http://www.csksoft.net/blog/sydication.asp?cmt=298</wfw:commentRss><trackback:ping>http://www.csksoft.net/blog/cmd.asp?act=tb&amp;id=298&amp;key=2708461d</trackback:ping></item><item><title>基于MK802、Arduino和OpenCV库的互动开发</title><author>csk@live.com (csk)</author><link>http://www.csksoft.net/blog/post/mk802_dev_demos.html</link><pubDate>Mon, 26 Nov 2012 23:20:01 +0800</pubDate><guid>http://www.csksoft.net/blog/post/mk802_dev_demos.html</guid><description><![CDATA[<div class="quote">
<p align="left">这是一个文章系列的一部分，介绍基于MK802这类MiniPC的扩展开发，并展示他在计算机视觉、机器人控制方面的潜能</p>
<p>欢迎转载，但请保留原始作者信息(Shikai Chen, <a href="http://www.csksoft.net/">http://www.csksoft.net</a>)，以及指向本文原始出处的链接！</p>
<p>访问目录：基于MK802 MiniPC的扩展开发应用-简介篇(<a href="http://www.csksoft.net/blog/post/mk802_dev_intro.html">http://www.csksoft.net/blog/post/mk802_dev_intro.html</a>)</p>
<p>&nbsp;</p>
<p>revision: 0</p>
</div>
<p>这是本系列文章的最后一篇了。本文将以如下几个基于MK802的应用实例进行介绍，向大家展示MK802在机器人控制以及计算机视觉方面的应用潜力。<br />
1.&nbsp;基于MK802的摄像头自动光源跟踪<br />
2.&nbsp;基于MK802的人脸摄像机云台跟踪<br />
3.&nbsp;MK802将路由器网络通讯情况显示与VFD屏幕<br />
这些是例子基于了我前5篇文章[1][2][3][4][5]所介绍的各类技巧和环境所形成的，这里我就假设大家已经阅读过先前的文章了，这里将以介绍思路和原理的方式来介绍这些实例。如果想进一步了解他们的实现，可以在本系列文章在github开设的项目中查看他们的源代码，在前一篇文章[5]中我也介绍了如何编译他们的。<br />
</p>
<h2 class="std_h2">Demo applications run on MK802 MiniPC to show MK802 potential in OpenCV and arduino related areas<br />
</h2>
<div class="quote"><a href="https://github.com/cheaven/mk802_demo">https://github.com/cheaven/mk802_demo</a><a href="https://github.com/cheaven/mk802_demo"></a></div>
<p>另外之前也有一些朋友表示这些实例使用的算法并不高级，性能也不佳。这里我就做一个统一的回应，本系列文章介绍的这些实例的目的并不是去实现这些功能本身，这些实例目前的确存在更好地实现。我制作这些实例的目的是为了向大家介绍MK802用于机器人控制和计算机视觉算法处理方面的强大潜能，因此我都尽可能使用了被大家熟知或者存在于OpenCV例子当中的程序作为范本。至于如何将这些例子进行改进扩充，就是靠大家发扬光大了:-)。</p>
<p>另外还有很多人会问这些例子能不能在树梅派、MK802的后续升级版本、XXXXX上面实现？这里我再次重复前几篇文章的说明，这里介绍的一切方法和思路对所有基于Linux的系统有效。当然，如果只是简单的复制这里的步骤，那恐怕只能用于MK802了。</p>
<p align="center"><embed height="400" type="application/x-shockwave-flash" width="480" src="http://www.tudou.com/v/eMv3zLORfDw/&amp;rpid=70789997&amp;resourceId=70789997_05_05_99&amp;bid=05/v.swf" quality="1" menu="menu" loop="loop" scale="ShowAll" allowscriptaccess="always" allowfullscreen="true" wmode="opaque"></embed></p>
<p align="center"><img alt="" src="/data/pic/mk802dev/demos/001_sm.jpg" /></p>
<p align="center"><embed height="400" type="application/x-shockwave-flash" width="480" src="http://www.tudou.com/v/wvnv7vbJnGU/&amp;rpid=70789997&amp;resourceId=70789997_05_05_99&amp;bid=05/v.swf" wmode="opaque" allowfullscreen="true" allowscriptaccess="always" scale="ShowAll" loop="loop" menu="menu" quality="1"></embed></p>
<p align="center"><img alt="" src="/data/pic/mk802dev/demos/006_sm.jpg" /></p>
<p align="center"><embed height="400" type="application/x-shockwave-flash" width="480" src="http://www.tudou.com/v/oubxw-PhL7s/&amp;rpid=70789997&amp;resourceId=70789997_05_05_99&amp;bid=05/v.swf" wmode="opaque" allowfullscreen="true" allowscriptaccess="always" scale="ShowAll" loop="loop" menu="menu" quality="1"></embed></p>
<p align="center"><img alt="" src="/data/pic/mk802dev/demos/010_sm.jpg" /></p>
<p><strong>点击文章标题浏览正文</strong></p>]]></description><category>Hacks</category><comments>http://www.csksoft.net/blog/post/mk802_dev_demos.html#comment</comments><wfw:comment>http://www.csksoft.net/blog/</wfw:comment><wfw:commentRss>http://www.csksoft.net/blog/sydication.asp?cmt=297</wfw:commentRss><trackback:ping>http://www.csksoft.net/blog/cmd.asp?act=tb&amp;id=297&amp;key=cfc2fe5b</trackback:ping></item><item><title>在MK802上结合OpenCV库进行计算机视觉处理</title><author>csk@live.com (csk)</author><link>http://www.csksoft.net/blog/post/mk802_dev_opencv.html</link><pubDate>Mon, 26 Nov 2012 22:00:29 +0800</pubDate><guid>http://www.csksoft.net/blog/post/mk802_dev_opencv.html</guid><description><![CDATA[<div class="quote">
<p align="left">这是一个文章系列的一部分，介绍基于MK802这类MiniPC的扩展开发，并展示他在计算机视觉、机器人控制方面的潜能</p>
<p>欢迎转载，但请保留原始作者信息(Shikai Chen, <a href="http://www.csksoft.net/">http://www.csksoft.net</a>)，以及指向本文原始出处的链接！</p>
<p>访问目录：基于MK802 MiniPC的扩展开发应用-简介篇(<a href="http://www.csksoft.net/blog/post/mk802_dev_intro.html">http://www.csksoft.net/blog/post/mk802_dev_intro.html</a>)</p>
<p>&nbsp;</p>
<p>revision: 0</p>
</div>
<p>这里将介绍MK802这类基于Cortrex A8/A9相对于Arduino这类单片机开发版、树梅派、以及PC对于爱好者来说最具有吸引力的优势所在：性能足够强大，可以运行OpenCV这类库的视觉算法，同时体积足够小，也相对于PC足够的省电。<br />
这篇文章正是介绍如何在MK802上使用OpenCV库并利用它进行计算视觉相关应用的开发的。在我实际使用的体验来看，OpenCV在MK802上运行的性能虽然相比PC还有一些差距，一些复杂的算法运行的较慢，但是大部分的算法都可以满足需求。并且如果进一步的优化后，相信可以有更多的性能提升。<br />
需要注意的是本文并不是OpenCV以及计算机视觉方面的教程，对于涉及到的一些视觉算法的知识以及OpenCV本身的背景知识，还需要读者自行学习。本文将着重关注如何在MK802这类MiniPC上使用OpenCV这个问题。</p>
<p align="center"><img alt="" src="/data/pic/mk802dev/opencv/005_sm.png" /></p>
<p align="center"><img alt="" src="/data/pic/mk802dev/opencv/013_sm.jpg" /></p>
<p align="center"><img alt="" src="/data/pic/mk802dev/opencv/017_sm.jpg" /></p>
<p><strong>点击文章标题浏览正文</strong></p>]]></description><category>Hacks</category><comments>http://www.csksoft.net/blog/post/mk802_dev_opencv.html#comment</comments><wfw:comment>http://www.csksoft.net/blog/</wfw:comment><wfw:commentRss>http://www.csksoft.net/blog/sydication.asp?cmt=296</wfw:commentRss><trackback:ping>http://www.csksoft.net/blog/cmd.asp?act=tb&amp;id=296&amp;key=5bc8c98a</trackback:ping></item></channel></rss>
