激光投影虚拟键盘的设计与实现
生活随笔
收集整理的這篇文章主要介紹了
激光投影虚拟键盘的设计与实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
激光投影虛擬鍵盤的設計與實現
- 原理和實現流程
- 硬件系統
- 效果圖
- 部分代碼
對大學期間做的一些設計的匯總之一
原理和實現流程
激光投影虛擬鍵盤是基于OpenCV結合一字紅外激光、圖像攝像頭、紅外濾光片組成。
使用攝像頭獲取到原始圖像、對原始圖像進行二值化、查找圖像輪廓、獲取中心坐標,進而檢測出由于手指遮擋所引起的一字紅外激光反射生成的光點,通過對光點中心位置的檢測映射到鍵盤位置,從而實現了對應的按鍵行為。
使用OpenCV視覺庫可以很快捷查找由圖像攝像頭獲取到的手指頭輪廓和定位手指頭的位置以及校正由圖像攝像頭引起的圖像曲面失真。
硬件系統
硬件:一個攝像頭(視角盡可能大一點),一塊arduino板,一個一字紅外發射器,一個濾波片,一個鍵盤投影,一臺電腦
注意:用于裝在攝像頭前的濾波片要能正好過濾可見光并不能過濾紅外光,但盡管是這樣,在白天自然光的時候效果依然做不到很好,所以就在晚上關燈調試。
我這里的攝像頭因為視角太小就只能裝的比較高。自上而下的三個硬件分別為攝像頭、鍵盤投影器、一字紅外發射器。
效果圖
因為圖像讀取是有一定延遲的,多按鍵被識別為按下,輸出結果可能會出錯。
我這里的處理是二值圖的中心點所在按鍵位置,所以比如同時按A和L,可能處處結果為G。
部分代碼
#include <iostream> #include "opencv2/opencv.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #include <cv.h> #include <highgui.h> #include <stack> #include <opencv2/video.hpp> #include <stdio.h> #include <stdlib.h> #include <string> #include<ostream> #include<fstream> #include<Windows.h>using namespace cv; using namespace std;void refresh(String a) {//保存到txtofstream fout;fout.open("data.txt",std::ios::out|std::ios::app);fout << a;fout.close(); }int main() {VideoCapture capture(0);Mat frame;capture >> frame;if (!capture.isOpened()){printf("can not open ...\n");return -1;} //獲取視頻的第一幀,并框選目標 while (1){capture.read(frame);if (!frame.empty()){namedWindow("output", WINDOW_AUTOSIZE);imshow("output", frame);//setMouseCallback("output", draw_rectangle, 0);waitKey(250);}Mat img, imgGray, two;img = frame;cvtColor(img, imgGray, CV_BGR2GRAY);//先對彩色圖像進行灰度化threshold(imgGray, two, 10, 255, CV_THRESH_BINARY);//對灰度圖進行二值化// vector<vector<Point>> contours;// vector<Vec4i> hierarchy;// findContours(two, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE);// cvNamedWindow("二值化");// 創建一個名為窗口 // imshow("二值化", two);// 在窗口中顯示Mat ele = getStructuringElement(MORPH_RECT, Size(2, 2));//圖像侵蝕Mat des;erode(two, des, ele);vector<Point2f> point;int count = 0;int x = 0, y = 0;RNG& rng = theRNG();Mat image(600, 600, CV_8UC3);for (int j = 0; j < des.rows; j++) {//求二值圖的白點的點集for (int i = 0; i < des.cols; i++) {if (des.at<uchar>(j, i) == 255) {point.push_back(Point2f(i, j));count++;x += i;y += j;}}}if (count != 0) {//Sleep(200);Point2f center;//尋找最小面積的包圍圓float radius = 0;try {minEnclosingCircle(Mat(point), center, radius);}catch (Exception) {}//測位置代碼:/*int ox=0,oy=0;ox=center.x;oy=center.y;cout<<"ox:"<<ox<<" oy:"<<oy<<endl;Sleep(100);*/String o="";//根據鍵盤實際位置來調整if (center.y > 198 && center.y <= 234) {//數字顯示if (center.x > 90 && center.x <= 132) {o = "1";}else if (center.x <= 174) {o = "2";}...//以下類似}else if (center.y > 234 && center.y <= 270) {//字母第一行...}else if (center.y > 270 && center.y < 306) {//字母第二行...}else if (center.y > 306 && center.y < 342) {//字母第三行...}else if (center.y > 342 && center.y < 378) {//空格行if (center.x > 265 && center.x <= 445) {o = " ";}}else {cout << "wrong" << endl;}cout << o ;refresh(o);Sleep(200);//消抖}cvNamedWindow("輪廓圖");// 創建一個名為窗口 imshow("輪廓圖", des);// 在窗口中顯示}return 0; }總結
以上是生活随笔為你收集整理的激光投影虚拟键盘的设计与实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: arduino自制cnc绘图仪_如何制作
- 下一篇: 基于php的个人理财系统,基于PHP个人