matlab 软键盘,(转载)DIY激光虚拟键盘低成本自制【全面讲解二】
本帖最后由 gazelle 于 2013-8-15 10:58 编辑
转载请注明出处:CLK.blog实现过程
器件选择
有前面的原理分析可知,本激光键盘至少需要摄像头、投射键盘画面的激光器以及一字线激光。如下是我选用的器件和参数
元件核心参数
摄像头广角镜头,视角>120度
投射键盘画面的激光器无特殊要求
一字线激光红外激光器,>50mW
红外带通滤光片800nm左右光谱带通
对于摄像头,这里一个比较关键的特性是需要采用广角镜头。目前的USB摄像头一般视角在90度左右,这样的摄像头需要在很高处俯视才能拍摄到完整的激光键盘图案,如果想把本投影键盘制作的小巧,则需要采用广角镜头,视角最好在120度以上。
图:窄视角的摄像头需要安装在较高的位置
除了镜头外,摄像头本身没有特殊要求,一般市面VGA画质的普通USB摄像头即可满足要求。下图为我采用的镜头和摄像头照片:
图:两种不同视角的摄像头镜头,左边为窄视角镜头,右边为广角镜头
图:USB摄像头模组
对投射键盘图案的激光发射器模组前文已经提到,且没有特殊要求。
图:选用的激光键盘图案投射模组
对用于测距的激光发射器,只需要使用红外波段的一字线激光器,功率在50mW左右即可。为了安全考虑,不要使用过大功率的激光器。采用红外波段主要为了过滤可见光干扰,简化视觉处理中的兴趣点提取,同时也不会因为手指反射对投射的键盘图案产生干扰。
图:选用的红外线型激光器
摄像头改装
在我之前的3D测距仪文章[2]中提到过使用红外激光器配合红外滤光片进行测距可有效避免可见光干扰的技巧,在这里也仍旧适用。对此我们需要对摄像头镜头做一些改造,首先拆除镜头上的红外光截至滤光片,并在镜头头部安装红外带通滤光片:
图:拆除镜头内的红外截止滤光片
图:在镜头表面安装红外带通滤光片
电子系统
本制作的电子系统比较简单,仅仅涉及给两个激光发射器供电以及通过USB电缆连接摄像头至主机。并没有采用任何单片机,这样也意味着之前原理部分介绍的算法将完全在PC上实现。这样的优点是大幅降低了制作成本以及制作的难度。如果使用的是免驱动USB摄像头,在PC上使用本激光投影键盘只需要额外运行处理程序即可。不过缺点就是这样的设计无法给手机等不支持USB的设备使用。
由于摄像头已经使用了一条USB电缆,因此这里我们直接通过usb的5V供电来驱动另外2个激光器。电路很简单,如下图所示:
可以看到电路的核心就是一个3.3V的LDO芯片而已,可以裁剪一个洞洞板制作:
图:使用小块洞洞板制作简易的驱动电路
总体安装
由前面的分析可以得到如下的安装结构:
其中线型激光器需要安装在设备的最底下并紧靠底部,这样可以保证产生的激光平面能够尽可能的靠近桌面平面。在激光器上方安装投射键盘图案的激光模组,他的高度以能够投射出与常规键盘尺寸大小类似的图案来决定。在最顶端安装摄像头,其高度取决于摄像头能够完整拍摄整个键盘图案画面为宜。
我使用一块轻质木材作为安装这3个部件的整体支架:
图:将激光器安装在木板最底部,使用热熔胶固定
图:安装图案投射模块和摄像头并点亮
图:在木板背面安装稳压电路板和所有供电连线
图:将木板装入一个牢固的纸盒
图:完成并通电
图:顶部加装一个“保护罩”
最终本制作的实体部分组装完毕,接下来将介绍本制作的重点:视觉算法部分。
3.5.前期视觉处理
由于本制作的视觉处理部分都在PC上进行,因此我使用了OpenCV[6]库来加速视觉运算代码的开发。在进行原理部分提到的手指尖提取和坐标求解前,需要对摄像头捕获的原始画面做一些前期的处理,方便后续的计算。
3.5.1.镜头扭曲矫正
由于我们使用了广角镜头,因此摄像头拍摄到的画面会存在比较明显的扭曲,就如下图所示:
这样扭曲的画面难以直接进行处理计算出后续需要的坐标信息,因为这种扭曲变换是非线性的。因此这里首先需要对摄像头镜头进行校正。在之前的文章[2]中有对摄像头矫正技术的介绍,这里我仍旧使用matlab的摄像头校正工具[7]进行校正。在OpenCV中也提供了相关函数和工具可以对摄像头校正,不过很多人反映相比matlab的算法,OpenCV函数校正得到的结果略差。
在使用Chessboard图案完整校正后,可使用OpenCV的cvInitUndistortRectifyMap/ cvRemap函数通过校正数据将扭曲的画面重新修正。
图:将左侧广角镜头的原始画面进行扭曲修正,得到右侧画面
这里有一点需要注意,在先前的安装阶段我们提到摄像头需要安装红外带通滤光片。但在安装滤光片后,由于可见光都被过滤,因此之后无法再进行上述的镜头校正。因此这部分的校正工作需要先于红外滤光片的安装进行。
3.5.2.滤波
由于摄像头镜头加装了红外带通滤光片,可见光可以有效地被阻挡,因此在摄像头捕获的画面上基本只含有手指对红外激光的反射。
图:红外带通滤光片有效地过滤了可见光干扰
对于这样的画面基本上是可以直接进行后续的视觉处理的,不过一般我们还需要额外进行几个步骤:灰度化、高斯滤波、阈值化、形态学滤波
灰度化即将原先RGB色彩的彩色图像转化成灰度图,因为后续的视觉算法并不关心色彩信息,但需要反射光亮度,使用灰度表示后可以大幅加速处理速度。高斯滤波(Gauss Filter)、阈值化(Threshold)、形态学滤波(Morphology Filter)用于过滤画面中的噪点并且使得反射光斑变得平滑和连贯。如果不熟悉这部分概念,可以参考Digital Image Processing一书[8]。这几步操作在OpenCV中均有对应函数可以实现。
图:对图像进行各类滤波处理后的效果
上图展现了经过上述滤波算法后,手指尖激光反光光斑处理后的效果。可以看到,原先光斑外围的反射光干扰以及两个比较靠近的指尖之间“黏连”的光斑已经有效地过滤掉了。通过一系列的滤波过程,使得我们可以很精确的求出指尖的坐标。
3.6.兴趣点提取
可以使用OpenCV提供的cvFindContours对先前与处理得到的光斑画面进行轮廓提取,进而求解出每个光斑区域在图像中的位置。进一步的,我们通过质心法并以光斑亮度作为权重,可以大致求解出每个指尖中心的大致坐标。虽然这个中心坐标未必真的在指尖中心,但相比简单的以光斑区域中心作为指尖中心的方法要精确很多。
图:使用轮廓提取手段提取出来的手指区域坐标
3.7.手指坐标计算和校正
在得到了手指光斑中心点相对于画面坐标之后,可以通过三角测距的方法,把手指在桌面平面内的坐标P(x,y)求出来。
该过程可以类比在激光3D测距中的算法,如下图所示:
图:将指尖坐标求解问题转化成3D激光测距问题
我们可以把兴趣点画面顺时针旋转90度,即将图像的X/Y轴相互交换,并在兴趣点之间连接起直线,如上图(b)所示。就会发现这样的画面就和[2]中进行3D激光测距出现的激光扫描线类似,如上图(c)。因此,我们可以按照[2]中推导的公式,求出画面中每个兴趣点的真实坐标(即以激光器为原点,桌面所在平面的坐标系坐标)
这部分的具体原理和公式推导请参考文章[2]。为了能够进行精确的激光测距,我们也需要和[2]中描述的那样对本制作进行校正。校正方法与[2]一样,可以在投影键盘前方用直尺做测量并进行曲线拟合。
图:对激光测距部分进行校正
经过本轮的运算,我们可以得到先前监测到的兴趣点在桌面平面坐标下的表示,测试坐标值具有了物理意义,均以毫米为单位表示。
3.8.按键映射和校正
在得到了以桌面坐标平面表示的指尖坐标P(x,y)后,我们需要再进行校正得到前文提到的映射函数
P' (x,y)=fprojection (P(x,y))
该部分的校正比较容易,可以将手指放置在键盘图案的某几个“按键”上,然后将当前的坐标P(x,y)与所“按”“按键”在键盘图案的坐标P_key (x,y)做一下对比。
理想状态下,每个P(x,y)与对应的P_key (x,y)都偏差了一个固定的位移量D。不过由于校正中会带来误差,每次测量时的偏差量D’与理想的位移量都存在一个误差偏移Derror。即
Pkey (x,y)=P(x,y)+D+ Derror
这里我们就可以采用多次测量,并进行最小二乘拟合的方式,把Derror给消除掉,得到近似于D的一个校正值。因此,这里的映射函数就是:
P' (x,y)=P(x,y)+D
另外这里也需要把键盘图案的坐标事先保存下来。我直接对投影在桌面上的键盘图案进行了测量,并按照如下格式保存在程序当中:
图:使用一维数组,保存每个按键中心点的坐标(x,y),按键的尺寸,以及按键的键值
在有了上述数据后,一方面我们可以使用Kd-tree来快速查找到所按下的按键ID。及前文所说的函数
Key[n]=fmapping (P' (x,y))
这里的f_mapping在我的实现中,就是一个Kd-tree。相比循环查找的O(n)复杂度,Kd-tree可以在O(log(n))的时间复杂度下,找到距离点P’(x,y)最接近的元素,因此非常高效率。
目前OpenCV中提供了Kd-tree的实现,不过我在使用过程中遇到了诸多问题,尤其它可能会导致程序crash,因此我使用了由Martin F. Krafft开发的基于C++模板的Kd-tree实现libkdtree++[9]。
得到键盘图案坐标后的另一个好处是可以在PC上重新绘制出一个软键盘,用于提示当前“按下”的按键,提高使用体验:
图:将坐标映射到对应“按下”的按键,并提供视觉反馈
matlab 软键盘,(转载)DIY激光虚拟键盘低成本自制【全面讲解二】相关推荐
- matlab edittext 回车,安卓中的虚拟键盘实现,KeyEvent的事件分发、处理机制。EditText是如何将KeyEvent事件转为字符输入的?...
目录 一.实现一个可以模拟输入的软键盘 一开始,我们的需求是在用户经常使用的部分界面中,增加虚拟软键盘,减少用户对于外接键盘的依赖 如图,在整单改价界面右侧增加了方便用户快捷输入的软键盘,用户不需要使 ...
- 计算机怎样打开鼠标点的键盘,如何打开计算机虚拟键盘?五种打开计算机虚拟键盘的方法简介...
随着社会的发展和时代的进步,人们的生活越来越丰富多彩.越来越多的电子产品的出现给人们的生活增添了无限的兴奋.如今,计算机已成为人们生活中必不可少的电子产品之一.我们总能在生活中看到计算机.当然,键盘经 ...
- html win10虚拟键盘,五种打开win10虚拟键盘的方法 win10虚拟键盘快捷键
电脑在使用的过程中,有时会遇到只有鼠标或实体键盘部分按键失灵,或为了体验系统自带的虚拟键盘等情况.此时就需要开启系统的屏幕键盘.屏幕键盘是一个模拟键盘的系统软件,必要的时候可以代替物理键盘Win10做 ...
- html win10虚拟键盘,Win10怎么调出虚拟键盘
Win10怎么调出虚拟键盘,想必大家都遇到过键盘失灵的麻烦,一时之间没有备用键盘,陷入无法打字的困境,这时候win10纯净版系统自带的虚拟键盘就能起到救场或者应急的作用,但win10虚拟键盘如何调出来 ...
- java弹出虚拟键盘_JS实现电脑虚拟键盘的操作
本文实例为大家分享了JS实现电脑虚拟键盘的具体代码,供大家参考,具体内容如下 需求: 1.当输入框光标聚焦时,电脑虚拟键盘弹出 2.在输入框输入内容时,键盘跟着变化 具体实现代码如下: Html部分: ...
- 开机直接进入键盘布局_屏幕虚拟键盘的使用
在购物和开机时都需要输入密码,为了防止密码被窃就需要虚拟键盘. 『1』屏幕虚拟键盘所在: 点左下角的开始, 点程序栏, 点开附件, 往下拉, 在轻松访问里的屏幕键盘就是虚拟键盘,这时可以右键发送为桌面 ...
- python调用系统软键盘_python库 pywinio虚拟键盘使用
NOTICE: You must have a ps/2 keyboard connected to your PC if you test on win10 or later, otherwise ...
- usb 键盘码表_ASCII码表,键盘按键码表,虚拟键盘按键码表
ASCII码表 ASCII值 控制字符 ASCII值 控制字符 ASCII值 控制字符 ASCII值 控制字符 0 NUT 32 (space) 64 @ 96 . 1 SOH 33 ! 65 A 9 ...
- ubuntu下qt模拟键盘按键按下_基于QT的跨平台虚拟键盘设计与实现
摘 要: 针对QT在Windows.Linux.以及嵌入式Linux-arm等不同平台下没有开源.高效的虚拟键盘(包含中文输入法),以及QT版本升级造成代码不兼容等问题,设计并实现了一个跨平台的虚拟 ...
最新文章
- JS中常遇到的浏览器兼容问题和解决方法
- 动手动脑之接口与继承
- Petya and Exam
- java 避免重定向_java重定向与转发的问题
- 逐月对比的交叉表处理
- 快切-开源中文css框架之纯css透明
- GhostXP SP3 中关村系统装机版 2013
- 配音软件文字转语音有哪些?
- CFAR检测MATLAB仿真
- pandas最快入门(一)-读取与数据结构
- w ndows热键,Window 10 优雅的快捷键
- 物联网模块跨阵M1控制LED
- 鸡兔同笼。已知鸡兔总头数为h,总脚数为f,求鸡兔各有多少只?
- mysql5.5版本 64位+界面工具中文破解版版(有教程)
- Unable to open underlying table
- C语言结构体中的位段
- PDF文件页码拆分方法
- 二分答案——路标设置(洛谷 P3853)
- 代号X8,小度智能屏的破壁行动
- access give to翻译_法律英语中access to的巧妙译法