Điều khiển máy tính từ xa bằng ... tay không. ST
Hầu hết ai mà chẳng điều khiển máy tính bằng tay, tay cầm chuột, tay gõ phím, nhưng trong bài viết này sẽ giới thiệu cách điều khiển máy tính bằng tay nhưng không động đến chuột hay bàn phím. Đối với nhiều người thì điều này có lẽ cũng còn khá xa vời, trong tưởng tượng hay trong các bộ phim, 1 viễn cảnh của công nghệ tương lai hay mới chỉ xuất hiện trong các phòng thí nghiệm hay trong 1 số ít sản phẩm công nghệ hiện đại chưa đại chúng. Trong bài này tôi sẽ cho các bạn thấy điều này không phải là cái gì đó trong tưởng tượng hay trong phim ảnh mà bất kỳ ai cũng có thể tự thực hiện được.
Các công cụ cần thiết :- Máy tính có Webcam.
- Microsoft Visual Studio (phiên bản 2008 chẳng hạn) : Code:
http://diendan.goonline.vn/showthread.php/528224-Visual-Studio-2008-Team-Suite-Full
- Thư viện về Computer Vision của Intel, ở đây dùng phiên bản OpenCV_1.1pre1a : Code:
http://www.mediafire.com/?bxw22fxzvy70q1m
- Bộ CSLD training do tôi đã chuẩn bị sẵn (nếu bạn nào quan tâm đến training và mở rộng khả năng học hỏi của máy tính có thể đặt câu hỏi tại đây) : Code:
http://www.mediafire.com/?skds3nbugbn3f
Chú ý : Để thuận tiện các bạn cài OpenCV vào ngay ổ C:
Tiến hành :
Mở Visual Studio và tạo 1 project Visual C++, Win32 Console Application mới. Đặt tên là diendan.go.vn_Control_Computer :
 This image has been resized. Click this bar to view the full image. The original image is sized 802x544. 
Chọn như các hình sau :
Sau khi tạo project, click chuột phải vào tên project và chọn Properties :
Chọn mục C/C++ và paste dòng sau vào khung Additional Include Directories : Code:
"C:\OpenCV\lib\cv.lib" "C:\OpenCV\lib\cxcore.lib" "C:\OpenCV\lib\highgui.lib"
 This image has been resized. Click this bar to view the full image. The original image is sized 760x533. 
Trong mục Linker --> Input --> Additional Dependencies chọn như sau :
 This image has been resized. Click this bar to view the full image. The original image is sized 762x535. 
Paste vào các dòng sau : Code:
"C:\OpenCV\lib\cv.lib" "C:\OpenCV\lib\cxcore.lib" "C:\OpenCV\lib\highgui.lib"
 This image has been resized. Click this bar to view the full image. The original image is sized 760x539. 
Nhấn OK :
 This image has been resized. Click this bar to view the full image. The original image is sized 765x536. 
Click chuột phải vào Source Files --> Add --> New Item... :
Chọn C++ File (.cpp), nhập vào tên main và nhấn Add :
 This image has been resized. Click this bar to view the full image. The original image is sized 806x518. 
Tiếp theo nháy đúp chuột vào main.cpp và paste toàn bộ đoạn code sau vào :
Trích:
#include "cv.h" #include "highgui.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #include <math.h> #include <float.h> #include <limits.h> #include <time.h> #include <ctype.h> #ifdef _EiC #define WIN32 #endif
static CvMemStorage* storage = 0; static CvHaarClassifierCascade* cascade1 = 0; static CvHaarClassifierCascade* cascade2 = 0; static CvHaarClassifierCascade* cascade3 = 0; static CvHaarClassifierCascade* cascade4 = 0; int use_nested_cascade = 0; void detect_and_draw( IplImage* image);
const char* cascade1_name ="Next.xml"; const char* cascade2_name ="Previous.xml"; const char* cascade3_name ="Stop.xml"; const char* cascade4_name ="Play.xml"; double scale = 1; int main( ) { CvCapture* capture = 0; IplImage *frame, *frame_copy = 0; IplImage *image = 0; const char* scale_opt = "--scale="; int scale_opt_len = (int)strlen(scale_opt); const char* cascade_opt = "--cascade="; int cascade_opt_len = (int)strlen(cascade_opt); const char* nested_cascade_opt = "--nested-cascade"; int nested_cascade_opt_len = (int)strlen(nested_cascade_opt);
cascade1 = (CvHaarClassifierCascade*)cvLoad( cascade1_name, 0, 0, 0 ); cascade2 = (CvHaarClassifierCascade*)cvLoad( cascade2_name, 0, 0, 0 ); cascade3 = (CvHaarClassifierCascade*)cvLoad( cascade3_name, 0, 0, 0 ); cascade4 = (CvHaarClassifierCascade*)cvLoad( cascade4_name, 0, 0, 0 ); storage = cvCreateMemStorage(0); capture = cvCaptureFromCAM(0); cvNamedWindow( "BACHKIM01", 1 ); if( capture ) { for(;;) { if( !cvGrabFrame( capture )) break;
frame = cvRetrieveFrame( capture ); if( !frame ) break; if( !frame_copy ) frame_copy = cvCreateImage( cvSize(frame->width,frame->height), IPL_DEPTH_8U, frame->nChannels ); if( frame->origin == IPL_ORIGIN_TL ) cvCopy( frame, frame_copy, 0 ); else cvFlip( frame, frame_copy, 0 ); cvShowImage( "BACHKIM01", frame_copy ); detect_and_draw( frame_copy ); if( cvWaitKey( 10 ) >= 0 ) goto _cleanup_; }
cvWaitKey(0); _cleanup_: cvReleaseImage( &frame_copy ); cvReleaseCapture( &capture ); } cvDestroyWindow("BACHKIM01"); return 0; } void detect_and_draw( IplImage* img ) { static CvScalar colors[] = { {{0,0,255}}, {{0,128,255}}, {{0,255,255}}, {{0,255,0}}, {{255,128,0}}, {{255,255,0}}, {{255,0,0}}, {{255,0,255}} }; IplImage *gray, *small_img; gray = cvCreateImage( cvSize(img->width,img->height), 8, 1 ); small_img = cvCreateImage( cvSize( cvRound (img->width/scale), cvRound (img->height/scale)), 8, 1 ); cvCvtColor( img, gray, CV_BGR2GRAY ); cvResize( gray, small_img, CV_INTER_LINEAR ); cvEqualizeHist( small_img, small_img ); c***earMemStorage( storage ); double t = (double)cvGetTickCount(); CvSeq* faces=0; int ind=0; if( cascade1 ) { faces = cvHaarDetectObjects( small_img, cascade1, storage, 1.2, 3, 0 //|CV_HAAR_FIND_BIGGEST_OBJECT //|CV_HAAR_DO_ROUGH_SEARCH |CV_HAAR_DO_CANNY_PRUNING //|CV_HAAR_SCALE_IMAGE , cvSize(90, 90) ); if(faces->total>0) { printf( "Next\n"); ind=1; } if(faces->total==0) { faces = cvHaarDetectObjects( small_img, cascade2, storage, 1.2, 3, 0 //|CV_HAAR_FIND_BIGGEST_OBJECT //|CV_HAAR_DO_ROUGH_SEARCH |CV_HAAR_DO_CANNY_PRUNING //|CV_HAAR_SCALE_IMAGE , cvSize(90, 90)); { printf( "Previous\n"); ind=2; } } if(faces->total==0) { faces = cvHaarDetectObjects( small_img, cascade3, storage, 1.2, 3, 0 //|CV_HAAR_FIND_BIGGEST_OBJECT //|CV_HAAR_DO_ROUGH_SEARCH |CV_HAAR_DO_CANNY_PRUNING //|CV_HAAR_SCALE_IMAGE , cvSize(90, 90) ); if(faces->total>0) { printf( "Stop\n"); ind=3; } } if(faces->total==0) { faces = cvHaarDetectObjects( small_img, cascade4, storage, 1.2, 3, 0 //|CV_HAAR_FIND_BIGGEST_OBJECT //|CV_HAAR_DO_ROUGH_SEARCH |CV_HAAR_DO_CANNY_PRUNING //|CV_HAAR_SCALE_IMAGE , cvSize(90, 90) ); if(faces->total>0) { printf( "Play\n"); ind=4; } } } t = (double)cvGetTickCount() - t; printf( "detection time = %gms\n", t/((double)cvGetTickFrequency()*1000.) ); for( int i = 0; i < (faces ? faces->total : 0); i++ ) { CvRect* r = (CvRect*)cvGetSeqElem( faces, i ); CvMat small_img_roi; CvSeq* nested_objects; CvPoint pt1,pt2; CvScalar color = colors[i%8]; int radius; pt1.x=cvRound(r->x * scale); pt1.y=cvRound(r->y * scale); pt2.x=cvRound((r->x + r->width) * scale); pt2.y=cvRound((r->y + r->height) * scale); cvRectangle(img, pt1,pt2,CV_RGB(255, 0, 0), 3, 8, 0); CvFont font; cvInitFont(&font,CV_FONT_HERSHEY_PLAIN, 2.0,2.0, 0,2, CV_AA); switch(ind) { case 1: {cvPutText(img, "Right!", cvPoint(pt1.x +40,pt1.y+40), &font, CV_RGB(255,0,0)); keybd_event(0x27, 0, 0, 0); //gửi thông điệp phím right arrow bar được nhấn đến hđh Sleep(1500); } break; case 2: {cvPutText(img, "Left!", cvPoint(pt1.x+40,pt1.y+40), &font, CV_RGB(255,0,0)); keybd_event (0x25, 0, 0, 0); //gửi thông điệp phím left arrow bar được nhấn đến hđh Sleep(1500); } break; case 3: {cvPutText(img, "Stop!", cvPoint(pt1.x+40,pt1.y+40), &font, CV_RGB(255,0,0)); //Thêm bất kỳ thông điệp bàn phím nào vào đây //Sleep(1500); } break; case 4: {cvPutText(img, "Up!", cvPoint(pt1.x+40,pt1.y+40), &font, CV_RGB(255,0,0)); //Thêm bất kỳ thông điệp bàn phím nào vào đây //Sleep(1500); } break; } printf("%d - %d\n",r->width,r->height); } cvShowImage( "BACHKIM01", img ); cvReleaseImage( &gray ); cvReleaseImage( &small_img ); }
|
|