版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、而且现在有了强大的opencv图像处理库,实现这样的虚拟激光投射键盘变得易如反掌。投影键盘的基本原理。键盘由三个主要部件组成:摄像头、键盘图案投射器、一字线性感应激光头。见下图:图上从上到下分别是键盘图案投射器、摄像头、一字线性感应激光头。当然,摄像头放在键盘图案投射器上面也是可以的,比如。1. 键盘图案投射器在平坦的桌面投出清晰键盘图案2. 最底下的一字线性激光(一般采用红外线的,这样眼睛不可见)发出一字型激光,平行于桌面射出,这样如果手指有按键活动,会在手指上形成激光光斑3. 摄像头捕获激光光斑,对应于键盘图案映射的位置,就可以知道哪些键被按下OK,原理很简单,剩下的关键就是摄像头的图像处
2、理算法了,而且现在有了opencv,实现也不是难事。这里说一下实现方法。由于人眼对激光的反应不一样,780nm-808nm的激光人眼不敏感,可看到微弱的一丝红光。850nm至1064nm波长人眼不可见,通过红外感光仪器等专业设备可以看到,其中808-850nm通过摄像头可以看到。980-1064nm通过倍频片可以看到。所以我在网上买了一个808nm-810nm 红外一字线激光器。这样配上滤光片,可以滤去绝大多数其他波长的杂光,只剩下红外激光的光斑。这样做的好处是减少干扰,增加键盘的可靠性,而且使算法处理更加简单有效。加上前面的650nm虚拟键盘激光组件,总共也就花了100块钱左右。25mw 8
3、08nm-810nm 红外一字线激光器 激光头直径18mm可见光截止400-750nm滤光片,800-1000nm高透在摄像头上看到的红外激光光斑投射到手指的图像如下图:对于光斑的跟踪我找了个现成的opencv扩展库cvblob,具体可以参考它的文档和例子,google code上有这个项目的托管。待会儿会奉上代码。cvblob可以跟踪多个光斑,所以很容易就可以实现ctrl+alt+delete之类的组合键。再来两张键盘图:顺便说一句,本文中的摄像头放的位置只能捕捉到部分键盘图像,所以demo只是演示了部分键盘的按键。不过丝毫不影响原理介绍。如果要获得全部键盘图像,或者去买一个广角的摄像头,或
4、者把这个摄像头位置提高,不是什么难事。时间有限,不想折腾了。代码:#include <iostream>#include <iomanip>#include "opencv/cv.h"#include "opencv/highgui.h"#include "cvblob.h"using namespace cvb;typedef struct keychar c;int x0;int y0;int x1;int y1;key g_keymap ='4',525,350,588,419,'
5、5',442,345,504,414,'6',360,339,422,408,'7',277,332,342,404,'8',198,327,259,399,'9',121,320,174,389,'0',41, 318,94, 383,'E',528,274,590,337,'R',443,267,507,332,'T',359,263,428,327,'Y',280,259,344,321,'U',199,251,261,3
6、15,'I',119,246,179,307,'O',41, 240,96, 301,'D',504,203,567,259,'F',424,199,489,257,'G',348,194,410,251,'H',266,187,329,245,'J',192,183,251,241,'K',117,178,171,236,'L',42 ,174,92, 229,'X',543,144,605,197,'C',467,1
7、39,530,191,'V',392,135,457,190,'B',316,128,377,181,'N',242,124,299,176,'M',171,118,225,172,'<',98, 114,149,166,'>',26, 108,73, 159,'_',182,62, 531,127,;int g_key_num = sizeof(g_keymap)/sizeof(key);int main()CvTracks tracks;cvNamedWindow(&
8、quot;red_object_tracking", CV_WINDOW_AUTOSIZE);CvCapture *capture = cvCaptureFromCAM(0);cvGrabFrame(capture);IplImage *img = cvRetrieveFrame(capture);CvSize imgSize = cvGetSize(img);IplImage *frame = cvCreateImage(imgSize, img->depth, img->nChannels);IplConvKernel* morphKernel = cvCreateS
9、tructuringElementEx(5, 5, 1, 1, CV_SHAPE_RECT, NULL);/unsigned int frameNumber = 0;unsigned int blobNumber = 0;bool quit = false;while (!quit&&cvGrabFrame(capture)IplImage *img = cvRetrieveFrame(capture);cvConvertScale(img, frame, 1, 0);IplImage *segmentated = cvCreateImage(imgSize, 8, 1);/
10、Detecting red pixels:/ (This is very slow, use direct access better.)for (unsigned int j=0; j<imgSize.height; j+)for (unsigned int i=0; i<imgSize.width; i+)CvScalar c = cvGet2D(frame, j, i);double b = (double)c.val0)/255.;double g = (double)c.val1)/255.;double r = (double)c.val2)/255.;/ unsign
11、ed char f = 255*(r>0.2+g)&&(r>0.2+b);/ cvSet2D(segmentated, j, i, CV_RGB(f, f, f);if(b>0.4 | g>0.4 | r>0.4)cvSet2D(segmentated, j, i, CV_RGB(255, 255, 255);elsecvSet2D(segmentated, j, i, CV_RGB(0, 0, 0);cvMorphologyEx(segmentated, segmentated, NULL, morphKernel, CV_MOP_OPEN, 1
12、);cvShowImage("segmentated", segmentated);IplImage *labelImg = cvCreateImage(cvGetSize(frame), IPL_DEPTH_LABEL, 1);CvBlobs blobs;unsigned int result = cvLabel(segmentated, labelImg, blobs);cvFilterByArea(blobs, 500, 1000000);cvRenderBlobs(labelImg, blobs, frame, frame, CV_BLOB_RENDER_BOUND
13、ING_BOX);cvUpdateTracks(blobs, tracks, 200., 5);cvRenderTracks(tracks, frame, frame, CV_TRACK_RENDER_ID|CV_TRACK_RENDER_BOUNDING_BOX);cvShowImage("red_object_tracking", frame);/ print keyfor (CvTracks:const_iterator it=tracks.begin(); it!=tracks.end(); +it)int xx = (int)it->second->c
14、entroid.x;int yy = (int)it->second->centroid.y;/std:cout << xx << ',' << yy << std:endl;for(int i=0; i<g_key_num; i+)if(xx > g_keymap.x0 &&xx < g_keymapi.x1 &&yy > g_keymapi.y0 &&yy < g_keymapi.y1)std:cout << g_keymap
15、i.c << std:endl;break;cvReleaseImage(&labelImg);cvReleaseImage(&segmentated);char k = cvWaitKey(10)&0xff;switch (k)case 27:case 'q':case 'Q':quit = true;break;case 's':case 'S':for (CvBlobs:const_iterator it=blobs.begin(); it!=blobs.end(); +it)std:stringstream filename;filename << "redobject_blob_" << std:setw(5) << std:setfill('0') << blobNumber << ".png"cvSaveImageBlob(filename.str().c_str(), img, it->second);blobNumber+;std:
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年区块链技术研究与应用服务承包合同
- 2024工业设备购销合同模板
- 2024年企业购置绿色环保厂房合同
- 2024年度网络安全防护及监控合同
- 2024房地产合同模板房屋拆迁协议
- 2024年度9A文矿产资源开发利用合作合同
- 2024年工程建筑承包合同范本
- 2024年度XX企业人力资源服务合同
- 全区抗旱救灾倡议书(5篇)
- 2024双方关于提供在线教育服务的合同
- 海康威视视频车位诱导与反向寻车系统解决方案
- 小学生日常卫生小常识(课堂PPT)
- 幼儿园大班《风筝飞上天》教案
- 企业所属非法人分支机构情况表(共1页)
- 寄宿生防火、防盗、人身防护安全知识
- 弯管力矩计算公式
- 《Excel数据分析》教案
- 汽车低压电线束技术条件
- 水稻常见病虫害ppt
- 学生会考核表(共3页)
- 六年级家长会家长代表演讲稿-PPT
评论
0/150
提交评论