红外激光键盘的原理总结.doc_第1页
红外激光键盘的原理总结.doc_第2页
红外激光键盘的原理总结.doc_第3页
红外激光键盘的原理总结.doc_第4页
红外激光键盘的原理总结.doc_第5页
已阅读5页,还剩10页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

. . . .而且现在有了强大的opencv图像处理库,实现这样的虚拟激光投射键盘变得易如反掌。投影键盘的基本原理。键盘由三个主要部件组成:摄像头、键盘图案投射器、一字线性感应激光头。见下图:图上从上到下分别是键盘图案投射器、摄像头、一字线性感应激光头。当然,摄像头放在键盘图案投射器上面也是可以的,比如。1. 键盘图案投射器在平坦的桌面投出清晰键盘图案2. 最底下的一字线性激光(一般采用红外线的,这样眼睛不可见)发出一字型激光,平行于桌面射出,这样如果手指有按键活动,会在手指上形成激光光斑3. 摄像头捕获激光光斑,对应于键盘图案映射的位置,就可以知道哪些键被按下OK,原理很简单,剩下的关键就是摄像头的图像处理算法了,而且现在有了opencv,实现也不是难事。这里说一下实现方法。由于人眼对激光的反应不一样,780nm-808nm的激光人眼不敏感,可看到微弱的一丝红光。850nm至1064nm波长人眼不可见,通过红外感光仪器等专业设备可以看到,其中808-850nm通过摄像头可以看到。980-1064nm通过倍频片可以看到。所以我在网上买了一个808nm-810nm 红外一字线激光器。这样配上滤光片,可以滤去绝大多数其他波长的杂光,只剩下红外激光的光斑。这样做的好处是减少干扰,增加键盘的可靠性,而且使算法处理更加简单有效。加上前面的650nm虚拟键盘激光组件,总共也就花了100块钱左右。25mw 808nm-810nm 红外一字线激光器 激光头直径18mm可见光截止400-750nm滤光片,800-1000nm高透在摄像头上看到的红外激光光斑投射到手指的图像如下图:对于光斑的跟踪我找了个现成的opencv扩展库cvblob,具体可以参考它的文档和例子,google code上有这个项目的托管。待会儿会奉上代码。cvblob可以跟踪多个光斑,所以很容易就可以实现ctrl+alt+delete之类的组合键。再来两张键盘图:顺便说一句,本文中的摄像头放的位置只能捕捉到部分键盘图像,所以demo只是演示了部分键盘的按键。不过丝毫不影响原理介绍。如果要获得全部键盘图像,或者去买一个广角的摄像头,或者把这个摄像头位置提高,不是什么难事。时间有限,不想折腾了。代码:#include #include #include opencv/cv.h#include opencv/highgui.h#include cvblob.husing namespace cvb;typedef struct keychar c;int x0;int y0;int x1;int y1;key g_keymap =4,525,350,588,419,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,315,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,139,530,191,V,392,135,457,190,B,316,128,377,181,N,242,124,299,176,M,171,118,225,172,26, 108,73, 159,_,182,62, 531,127,;int g_key_num = sizeof(g_keymap)/sizeof(key);int main()CvTracks tracks;cvNamedWindow(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 = cvCreateStructuringElementEx(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);/ Detecting red pixels:/ (This is very slow, use direct access better.)for (unsigned int j=0; jimgSize.height; j+)for (unsigned int i=0; i0.2+g)&(r0.2+b);/ cvSet2D(segmentated, j, i, CV_RGB(f, f, f);if(b0.4 | g0.4 | r0.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);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_BOUNDING_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-centroid.x;int yy = (int)it-second-centroid.y;/std:cout xx , yy std:endl;for(int i=0; i g_keymap.x0 &xx g_keymapi.y0 &yy g_keymapi.y1)std:cout g_keymapi.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 second);blobNumber+;std:cout filename.str() saved! std:endl;break;cvReleaseBlobs(blobs);/frameNumber+;cvReleaseStructuringElement(&morphKernel);cvReleaseImage(&frame);cvDestroyWindow(red_object_tracking);return 0;1. 若不给自己设限,则人生中就没有限制你发挥的藩篱。2. 若不是心宽似海,哪有人生风平浪静。在纷杂的尘世里,为自己留下一片纯静的心灵空间,不管是潮起潮落,也不管是阴晴圆缺,你都可以免去浮躁,义无反顾,勇往直前,轻松自如地走好人生路上的每一步3. 花一些

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论