紅外激光鍵盤的原理總結(jié)_第1頁
紅外激光鍵盤的原理總結(jié)_第2頁
紅外激光鍵盤的原理總結(jié)_第3頁
紅外激光鍵盤的原理總結(jié)_第4頁
紅外激光鍵盤的原理總結(jié)_第5頁
已閱讀5頁,還剩9頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、而且現(xiàn)在有了強(qiáng)大的opencv圖像處理庫,實(shí)現(xiàn)這樣的虛擬激光投射鍵盤變得易如反掌。投影鍵盤的基本原理。鍵盤由三個(gè)主要部件組成:攝像頭、鍵盤圖案投射器、一字線性感應(yīng)激光頭。見下圖:圖上從上到下分別是鍵盤圖案投射器、攝像頭、一字線性感應(yīng)激光頭。當(dāng)然,攝像頭放在鍵盤圖案投射器上面也是可以的,比如。1. 鍵盤圖案投射器在平坦的桌面投出清晰鍵盤圖案2. 最底下的一字線性激光(一般采用紅外線的,這樣眼睛不可見)發(fā)出一字型激光,平行于桌面射出,這樣如果手指有按鍵活動(dòng),會(huì)在手指上形成激光光斑3. 攝像頭捕獲激光光斑,對(duì)應(yīng)于鍵盤圖案映射的位置,就可以知道哪些鍵被按下OK,原理很簡單,剩下的關(guān)鍵就是攝像頭的圖像處

2、理算法了,而且現(xiàn)在有了opencv,實(shí)現(xiàn)也不是難事。這里說一下實(shí)現(xiàn)方法。由于人眼對(duì)激光的反應(yīng)不一樣,780nm-808nm的激光人眼不敏感,可看到微弱的一絲紅光。850nm至1064nm波長人眼不可見,通過紅外感光儀器等專業(yè)設(shè)備可以看到,其中808-850nm通過攝像頭可以看到。980-1064nm通過倍頻片可以看到。所以我在網(wǎng)上買了一個(gè)808nm-810nm 紅外一字線激光器。這樣配上濾光片,可以濾去絕大多數(shù)其他波長的雜光,只剩下紅外激光的光斑。這樣做的好處是減少干擾,增加鍵盤的可靠性,而且使算法處理更加簡單有效。加上前面的650nm虛擬鍵盤激光組件,總共也就花了100塊錢左右。25mw 8

3、08nm-810nm 紅外一字線激光器 激光頭直徑18mm可見光截止400-750nm濾光片,800-1000nm高透在攝像頭上看到的紅外激光光斑投射到手指的圖像如下圖:對(duì)于光斑的跟蹤我找了個(gè)現(xiàn)成的opencv擴(kuò)展庫cvblob,具體可以參考它的文檔和例子,google code上有這個(gè)項(xiàng)目的托管。待會(huì)兒會(huì)奉上代碼。cvblob可以跟蹤多個(gè)光斑,所以很容易就可以實(shí)現(xiàn)ctrl+alt+delete之類的組合鍵。再來兩張鍵盤圖:順便說一句,本文中的攝像頭放的位置只能捕捉到部分鍵盤圖像,所以demo只是演示了部分鍵盤的按鍵。不過絲毫不影響原理介紹。如果要獲得全部鍵盤圖像,或者去買一個(gè)廣角的攝像頭,或

4、者把這個(gè)攝像頭位置提高,不是什么難事。時(shí)間有限,不想折騰了。代碼:#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等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論