分享

DIY激光虚拟键盘低成本自制

  2015-08-08
CLK.blog在制作3D激光扫描仪的过程中,我偶然在网络上发现有人销售可以投影出键盘画面的激光器组件,并且价格低廉。仔细想来其实激光投影键盘的原理和3D扫描仪一致,于是便产生了DIY一个低成本激光键盘的想法。最终,本作品在我完成3D扫描仪的3天内完成了,可见硬件部分的制作不复杂。虽然完成的时间短,但其中也涉及不少的设计细节需要考虑,于是便写了此文向大家分享我的制作过程。1.jpg
简介
激光投射键盘相信大家之前也有所听说,他通过光学手段,将计算机键盘的画面通过激光投影到任意的平面上(如桌面)上,并且允许操作者像使用真实键盘那样进行输入操作。
2.jpg 
图:Celluon公司出品的Magic Cube激光投影键盘
目前市面上能买到的激光键盘产品是由韩国公司Celluon生产销售的。这类产品目前也可以在国内买到,不过因为价格高昂,目前仍旧在千元水平。我之前并没有购买过,具体使用效果也不得而知。有人评价说因为缺少物理反馈,这样的键盘使用上手感可能不好。
但无论如何,激光虚拟键盘还是非常能吸引眼球的,在投射出的键盘影像上输入非常有科技感并且足够科幻。如果能自己以较低成本DIY一台出来,那岂不是更好?
本文提出的DIY激光投影键盘方案可以保证使用较低的成本(百元左右),并提供较强的性能:30hz的输入频率、支持多键输入,并且还有额外的功能:把他当作多点输入设备来使用,比如可以作为绘图板,并能感应手指的压力大小。
在完成本制作后我拍摄了一段演示视频展现它的性能,可以访问如下地址观看:
原理分析
在具体介绍实现过程前,我们首先需要分析这类激光投影键盘的工作原理以及给出解决问题的思路,这样也可方便大家举一反三。首先需要解决的核心问题有这么两个:
  • 如何产生键盘的画面?
  • 如何检测键盘输入事件?
产生键盘画面
对于产生键盘画面,可能很多人认为这种画面是通过激光+高速光学振镜来得到的。这种方式虽然在技术上是完全可行的,但由于需要采用精密的机械部件,成本非常高,并且也难以做成轻便的产品。
   3.jpg
图:通过光学振镜扫描产生的激光投影画面。图片来自[1]
不过这类全息投影方式对于DIY来说仍旧不现实,幸好得益于目前网络的便利——通过网购可以直接买到用于产生激光键盘画面的全息投影设备了,且成本在¥50以内。
   5.jpg
图:可以购买到的投影键盘画面的激光器模组
识别键盘输入事件
在解决了产生键盘画面的问题后,这里分析另一个看似简单的问题:如何判断键盘输入事件?
由于键盘画面可以投射在任意的表面上,因此传统的靠物理按钮的手段自然是不可能的(否则也称不上虚拟键盘)。需要非接触的手段来检测。这里给出了几种途径,他们在技术上都是可行的:
1) 通过计算机视觉的方式,通过图像来识别
通过摄像头捕捉键盘区域的画面并进行分析,判断出键盘输入事件。
2) 通过检测按键发出的声音来判断
这里假设使用者在按键时会碰触桌面,产生一定的敲击声。通过检测该声音传播时间,可以进行定位。该方案在国外的一些研究机构已经实现。
3) 通过超声波雷达手段来判断
通过发射超声波并检测反射波的传播时间查来检测目标物体(手指)的位置。
这3种方案国内外均有文献表明可以实现,不过相对来说计算机视觉的硬件较为简单,仅仅需要一个摄像头,因此这里我们采用这种方式。
下图给出了本制作早期阶段,摄像头所拍摄的使用过程的画面,基于这类画面进行计算机视觉的运算,可以得到我们需要的键盘事件:
6.jpg 
图:通过计算机视觉的方式识别并判断键盘输入事件
其实这里涉及到了2个子问题:
  • 判断手指按下的是哪个键?
  • 如何判断手指已经“按到”了对应的“按钮”?

由于我们人类就是通过视觉来理解外部世界的,因此很直观的可以想到,只要能够识别并定位画面中手指的位置,第一个问题就可以解决了。这里先不讨论定位本身该如何实现,假设我们的算法已经可以和人脑一样轻松在一副画面中找到手指的位置并用相对于图像的坐标来表示(x,y)。
接下来就要考虑第二个问题,如何判断手指已经“按下按钮”?这里一个办法是通过捕捉声音:即像前文提到的通过捕捉手指碰触桌面产生的敲击声来判断。但这样会带来额外的问题:
  • 需要额外的硬件和电路,增加了复杂性
  • 如何将敲击声与画面中真正敲击的手指对应?就像上图中的5个手指都可能是在敲击状态,此时难以进行匹配
  • 其他的噪音也会被当作键盘敲击

因此这里还是依靠视觉的手段来进行判断。在分析可行方案前,需要明确“按下按钮”的具体指标。我们可以定义当手指碰触桌面,或者距离桌面足够接近为“按下”。那么其实问题的实质就是我们需要检测出手指距离桌面的距离z。在求出该数值后,我们只需简单的判断它小于某一个值,就认为手指已经“按下按键”。
综合起来看,我们需要设计一种视觉处理算法:它可以在一副画面中找出每个手指相对画面的位置(x,y),并且手指距离桌面的高度z。事实上我们就是在检测手指的三维空间坐标了(x,y,z)了。
7.jpg 
图:需要设计的视觉检测算法和期望的检测结果
如果之前有阅读我的3D激光扫描仪制作的话,相信大家就能猜到具体的实现方式了,其实算法本身就是做三维的激光测距。不过这里我们先按照前文的思路继续分析下去:
做三维测量有很多种方式,比如现在可以购买微软的KINECT深度传感器。如果不考虑成本,这的确是一种非常有效的方法,可以非常好的解决本文提出的这些问题。另一种类似的办法是使用双摄像头来做双目视觉处理,提取目标画面物体的深度信息。不过目前这类处理比较消耗处理资源,且校正过程比较复杂,并不适合这里的应用。
   8.jpg
图:RoboPeak团队曾进行的双目视觉进行深度提取的实验
这里我们采用基于三角测距原理的激光测距仪[2]一致的办法,通过主动投射激光来做目标物体的三维坐标检测。在[2]中我使用一束线型激光照射目标物体,在目标物体的反射光被摄像头捕捉到,利用三角测距原理,可以求出目标物体中被线激光照亮部分的坐标信息。
   9.jpg
在[2]中提到的利用线激光和单摄像头的3D测距原理
这里我们将线激光所产生的光线平面与桌面平行并紧贴在桌面之上,将摄像头放置于激光发射器上方并俯视桌面,如下图所示:
   10.jpg
图:利用激光三角测距原理用于手指空间坐标检测
此时若手指接近桌面,则会阻挡住激光的通路,产生反射,反射的光点画面会被图中摄像头拍摄到。这是一个标准的三角测距的结构设置。细心的读者可能已经发现在前文给出的本制作摄像头拍摄到的画面中手指尖部的白色光斑,这正是安装了线激光器后被手指遮挡产生的反射效果。
   11.jpg
图:本制作采用的线激光测距方案
对于这种基于线激光的测距的方式[2],我们可以通过三角关系求出被激光照亮部分相对于激光发射口为原点、位于线激光组成平面内的坐标P(x,y)。而又因为线激光组成的平面与桌面平行,且在设计上这两个平面是紧贴着的,所以可以近似的认为坐标点P(x,y)是位于桌面平面的。
这样的设置具有几个优点:
方便检测指尖
当手指遮挡激光平面后产生了反射,因此会在摄像头画面中出现较为明亮的光斑,可以通过简单的视觉算法来提取指尖部分
方便检测按键事件
由于只有当手指靠近或者碰触到桌面才会遮挡住激光产生反光,而在距离桌面较高的位置则不会被检测算法察觉。因此这里检测按键事件可以做出简化,不需要通过检测手指距离桌面高度来判断。而只要当检测算法检测到手指反光,则可认为出现了按键事件,且可直接用当前检测到的坐标来进行后续的处理。
值得一提的是,事实上这样的方式对从事多点触摸领域朋友来说应该不陌生,有一种称为LLP(Laser Light Plane)的技术[4]和我们的方式很类似。
12.jpg 
图:LLP方式的多点触摸技术,图片来源自[5]
如上图所示,LLP技术也通过发射一束线型激光构造出一个光平面,并捕捉手指反光来做多点触摸定位。而摄像头的安装位置也并非一定位于上边示意图的底下,同样也可以安装在本制作一样的位置。事实上这里采用的激光测距方案的前期处理是和LLP一致的:提取手指指尖的兴趣点,并转换成相对于摄像头画面的坐标。不过对于多点触摸而言,不需要得到手指在桌面上的精确距离,就好比我们用的鼠标只需要知道一个相对位移的程度,而不需得到具体鼠标移动了多少毫米。但由于我们需要将手指的坐标转换成具体按键的信息,因此还有必要进行更进一步的处理。
判断并产生对应的按键事件
前面我们已经解决了如何检测手指当碰触到桌面时指尖在桌面平面上的坐标P(x,y)。但这与我们最终要产生对应的按键事件还有一定距离。我们需要建立一个映射机制,通过桌面坐标P(x,y)找到对应按键键值,并最终通知操作系统触发一个对应键值的按键事件。
这里的做法与GUI系统进行UI元素碰撞判断的过程类似。在图形系统中,所有UI元素均保存有他们相对于屏幕的坐标值。GUI系统不停地判断当前鼠标指针位置是否落入了某一个按钮或者选择框的坐标范围内。

13.jpg 
图:GUI系统通过对比鼠标坐标和按钮UI元素的坐标来判断鼠标是否存在于按钮元素上方
与GUI系统类似,我们首先需要建立投射键盘图案中每个按键的坐标信息。然后将指尖相对于桌面平面上的坐标P(x,y)映射到键盘图案的坐标系内进行按键的判断。
14.jpg
图:将基于桌面平面以激光器为原点的指尖坐标P(x,y)映射到键盘坐标平面并进行按键判断
上述过程涉及到两个步骤:
1) 将以激光发射器为原点的指尖坐标P(x,y)映射到以键盘图案左上角为原点坐标的平面内,得到映射点P’(x,y)
该过程用数学表达记作:
P' (x,y)=fprojection (P(x,y))
2) 将映射点P’(x,y)与事先记录的每个按键的坐标值比对,求得当前对应按下的按键值。
该过程记作:
Key[n]=fmapping (P' (x,y))
可能有人会问为何不直接按照以激光发射器原点的坐标来表示每个按键的坐标?这样第一步的映射f_projection就可以省略了。这的确也可以达到同样的效果。但是由于在组装上会存在误差,不能保证每次制作出来的成品激光发射器与键盘图案投射的位置都完全一致,并且单个成品在使用过程中也会因为热胀冷缩等原因,键盘图案会发生偏移。一旦键盘图案发生了移动,则先前以这种方式记录的所有按键坐标都需要重新测量。但如果一开始就以键盘左上角为原点的方式记录坐标,则每次组装完成品或者发生图案偏移后,则只需进行简单的矫正,求出一个新的f_projection函数即可。
系统框图
前面我们解决了制作激光投影键盘的两个关键问题,这里将我们最终采用方案的大致原理做出总结,方便大家理解。在实现过程部分,将具体就其中的实现细节做出介绍。
15.jpg   
框图中还包含了本制作的另一个功能:多点触摸绘图板。

7.jpg (35.66 KB, 下载次数: 113)

7.jpg

6.jpg (20.7 KB, 下载次数: 102)

6.jpg

5.jpg (10.3 KB, 下载次数: 95)

5.jpg

4.jpg (19.57 KB, 下载次数: 80)

4.jpg

3.jpg (23.46 KB, 下载次数: 83)

3.jpg

2.jpg (36.2 KB, 下载次数: 78)

2.jpg

1.jpg (10.47 KB, 下载次数: 72)

1.jpg

7.jpg (30.86 KB, 下载次数: 73)

7.jpg

6.jpg (25.2 KB, 下载次数: 77)

6.jpg

5.jpg (24.08 KB, 下载次数: 81)

5.jpg

4.jpg (20.68 KB, 下载次数: 74)

4.jpg

3.jpg (18.83 KB, 下载次数: 72)

3.jpg

2.jpg (14.32 KB, 下载次数: 115)

2.jpg

1.jpg (13.31 KB, 下载次数: 88)

1.jpg

33.jpg (25.53 KB, 下载次数: 85)

33.jpg

32.jpg (11.89 KB, 下载次数: 96)

32.jpg

31.jpg (27.28 KB, 下载次数: 82)

31.jpg

30.jpg (21.06 KB, 下载次数: 106)

30.jpg

29.jpg (20.3 KB, 下载次数: 88)

29.jpg

28.jpg (25.83 KB, 下载次数: 72)

28.jpg

27.jpg (21.64 KB, 下载次数: 78)

27.jpg

26.jpg (27.25 KB, 下载次数: 74)

26.jpg

25.jpg (22.33 KB, 下载次数: 77)

25.jpg

24.jpg (18.7 KB, 下载次数: 107)

24.jpg

23.jpg (17.23 KB, 下载次数: 83)

23.jpg

22.jpg (6.41 KB, 下载次数: 72)

22.jpg

21.jpg (6.45 KB, 下载次数: 86)

21.jpg

20.jpg (40.51 KB, 下载次数: 109)

20.jpg

19.jpg (27.11 KB, 下载次数: 68)

19.jpg

18.jpg (17.29 KB, 下载次数: 75)

18.jpg

17.jpg (21.81 KB, 下载次数: 76)

17.jpg

16.jpg (16.52 KB, 下载次数: 91)

16.jpg

4.jpg (14.77 KB, 下载次数: 75)

4.jpg

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多