Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 59 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
59
Dung lượng
2,8 MB
Nội dung
BỘ GIÁO DỤC VÀ ĐÀO TẠO TRƯỜNG ĐẠI HỌC NHA TRANG KHOA CÔNG NGHỆ THÔNG TIN ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC TÌMHIỂUCAMERA3D,ỨNGDỤNGLẬPTRÌNHGIAOTIẾPGIỮANGƯỜIVÀMÁYBẰNGCÁCCỬCHỈCỦATAY Giảng viên hướng dẫn: TS ĐINH ĐỒNG LƯỠNG Sinh viên thực hiện: LÊ NGỌC THÀNH Lớp: MSSV: 55CNTT2 55131653 Nha Trang - Tháng 6/2017 LỜI NÓI ĐẦU Công nghệ thông tin ngày trở nên quan trọng đời sống Việc tìm cách để giaotiếpngườimáy cho tự nhiên thân thiện mối quan tâm nghiên cứu nhà nghiên cứu phát triển ứngdụng Hiện sử dụng thiết bị để hỗ trợ giaotiếp chuột, bàn phím cách tiếp cận truyền thống không tự nhiên, thay vào phương pháp giaotiếp không cần tiếp xúc sử dụngcử phận thể người việc mà hướng đến tương lai Tháng 04 năm 2010, xuất camera 3D Kinect - thiết bị phát triển Microsoft thực cách mạng lĩnh vực giaotiếpngười – máy Đến tháng 01 năm 2014, Intel cho mắt thiết bị camera 3D intel realsense với khả cảm nhận vật không gian 3D có cự ly gần, thời gian thực có độ xác cao góp phần giúp nghiên cứu tương tác người – máy lên tầm cao mới, ngườigiaotiếp hoàn toàn với máy thông qua cử tay, cảm xúc giọng nói Tuy xuất năm thiết bị intel realsense tiện ích lạ lẫm Việt Nam Từ nghiên cứu ban đầu thiết bị realsense sinh viên K54, nhận thấy nhiều ứngdụng tiềm áp dụng phát triển từ thiết bị Từ đó, nhận đề tài liên quan đến thiết bị realsense để có hội tìmhiểutiếp tục nâng cấp, để sử dụngcửtay để ứngdụng điều khiển trình chiếu Powerpoint, sử dụngtrình duyệt Chrome kết hợp tìm kiếm thông tin giọng nói hay chơi game Em xin gửi đến thầy TS Đinh Đồng Lưỡng lời cảm ơn chân thành sâu sắc Nhờ hướng dẫn giúp đỡ tận tình thầy suốt 15 tuần, em thực hoàn thành đồ án tốt nghiệp Sự nhiệt tình hướng dẫn, bảo thầy trình thực đề tài giúp em có thêm nhiều động lực, định hướng để hoàn thành đề tài Em cảm ơn thầy! Đồng thời, em xin trân trọng cảm ơn thầy cô khoa công nghệ thông tin tận tình dạy dỗ em suốt thời gian em ngồi ghế giảng đường đại học Những kiến thức, kỹ mà thầy cô dạy cho em làm em ngày hoàn thiện học tập, làm việc sống Nha Trang, ngày 25 tháng năm 2017 Lê Ngọc Thành MỤC LỤC LỜI NÓI ĐẦU MỤC LỤC .3 DANH MỤC TỪ VIẾT TẮT DANH MỤC HÌNH ẢNH, BẢNG BIỂU CHƯƠNG I: TỔNG QUAN VỀ ĐỀ TÀI 1.1 Lý chọn đề tài 1.2 Yêu cầu đề tài 1.3 Phương pháp 1.4 Cấu trúc báo cáo CHƯƠNG II GIỚI THIỆU VỀ CAMEA 3D INTEL REALSENSE .11 2.1 Giới thiệu camera 3D Intel RealSense 11 2.2 Thư viện mã nguồn mở SDK 13 2.2.1 Kiến trúc SDK 14 2.2.2 Các Interface cốt lõi Intel RealSense SDK 15 2.3 CácứngdụngCamera 3D 15 CHƯƠNG III PHÂN TÍCH VÀ PHƯƠNG PHÁP GIẢI QUYẾT BÀI TOÁN .20 3.1 Intel Realsense Camera F200 21 3.2 Thu nhận xử lý ảnh 21 3.3 Định vị khớp nối 22 3.4 Nhận dạng cửtay 22 3.4.1 Nhận dạng hình dáng 23 3.4.2 Nhận diện cử điệu tay 23 CHƯƠNG IV CÀI ĐẶT CHƯƠNG TRÌNHVÀ KẾT QUẢ ĐẠT ĐƯỢC .26 4.1 Cài đặt chương trình 26 4.1.1 Cấu trúc liệu 26 4.1.2 Phương thức 29 4.1.3 Interface Handetail 31 4.2 Kết đạt 35 4.2.1 Ứngdụng điều khiển phần mềm trình chiếu MS PowerPoint 35 4.2.2 Ứngdụng sử dụngtrình duyệt web (Google Chrome) 37 4.2.3 Ứngdụng chơi game 37 CHƯƠNG V: KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN 38 5.1 Kết luận 38 5.2 Hướng phát triển 39 TÀI LIỆU THAM KHẢO .40 PHỤ LỤC: Tài liệu hướng dẫn sử dụng phát triển chương trình 41 Cài đặt driver DCM chạy ứngdụngCamera RealSense 41 Sau đó tải ứngdụngCamera 41 Khai báo thư viện cài đặt mô-đun HandDetail 43 DANH MỤC TỪ VIẾT TẮT 2D 2-Dimension 3D 3-Dimension CES Consumer Electronics Show DCM Dethp Camera Manager E3 Electronic Entertainment Expo GB Gigabyte IEC International Electrotechnical Commission ISO International Organization for Standardization JDK Java Development Kit OOP Oject Oriented Programming OpenCL Open Computing Language OpenCV Open Computer Vision PC Personal Computer SDK Software Development Kit TV TeleVision USB Universal Serial Bus DANH MỤC HÌNH ẢNH, BẢNG BIỂU Hình 1.1 – Minh họa bước xử lý chương trình Hình 2.1 – Camera 3D Realsense F200 13 Hình 2.2 – Kiến trúc Intel RealSense SDK 15 Hình 2.3 – Hệ thống Interface C++/C# .16 Hình 2.4 – Phần mềm chơi nhạc Kagura 18 Hình 2.5 – Phần mềm Posture Monitor .18 Hình 2.6 – Phần mềm Boom Ball .19 Hình 2.7 – Phần mềm Lego Portal Racers 19 Hình 2.8 – Các game điều khiển cử khuôn mặt 20 Hình 3.1 – Minh họa bước xử lý chương trình 21 Hình 3.2 – Camera Intel RealSense 3D FONT F200 22 Hình 3.3 – Hình ảnh thu từ Camera Intel RealSense 3D 22 Hình 3.4 – Hình ảnh thao tác bàn tay 23 Hình 3.5 – Minh họa cách xác định hình dáng 24 Hình 3.6 – Minh họa chuyển động điểm bàn tay .30 Hình 3.7 – Hình ảnh thao tác PowerPoint 37 Bảng 3.1 – Cử điệu bàn tay sử dụng đồ án 25 -26 Bảng 4.1 – Ma trận nhầm lẫn 36 CHƯƠNG I: TỔNG QUAN VỀ ĐỀ TÀI 1.1 Lý chọn đề tài Ngày nay, tất thiết bị điện tử điện thoại thông minh (smart phone), máy tính cá nhân (PC’s) tivi thông minh (smart TV) tích hợp nhiều camera 2D Hiện có số sản phẩm máy tính xách tay đời tích hợp camera3D, tương lai gần camera 3D thay toàn camera truyền thống 2D Với phát triển không ngừng thiết bị thu ảnh 3D, năm 2015 dự báo đời thiết bị camera 3D nhỏ gọn, thực thu nhận ảnh thời gian thực tích hợp máy tính xách tay điện thoại thông minh Việc nghiên cứu ứngdụng kỹ thuật giaotiếpngườimáy tính vấn đề nhà phát triển ứngdụng quan tâm phát triển Với ý nghĩa mục đích nêu trên, đề tài nghiên cứu phát triển ứngdụng điều khiển máy tính cửtay cần thiết hữu ích thời điểm Thế mạnh phương pháp so với phương pháp truyền thống có nhiều ưu điểm như: khả tương tác thân thiện tự nhiên, không cần tiếp xúc lên thiết bị điện tránh va chạm, nâng cao độ bền thiết bị, đặc biệt nơi công cộng, không cần tiếp xúc giúp thiết bị (trường hợp sử dụngmáy tính giảng dạy kết hợp viết phấn bảng cách tiếp cận hoàn toàn chiếm ưu so phương pháp truyền thống, việc giữ vệ sinh máy tính giáo viên vừa điều khiển máy tính vừa sử dụng phấn bảng) Từ mắt đến nay, công nghệ intel realsense dần tích hợp sẵn sản phẩm thương mại ứngdụng kèm mang đến trải nghiệm lạ cho ngườidùng Tuy nhiên, chúng lạ phần lới ngườidùng phổ thông đặc biệt nhận diện hành động cử qua không gian 3D Do đó, tô i chọn đề tài giaotiếpngườimáy cách thân thiện sử dụngcamera 3D intel realsense Trong đồ án muốn demo hệ thống vào việc điều khiển ứngdụng phổ biến thầy cô thường sử dụng giảng đường để tránh việc tiếp xúc trực tiếp với máytay sử dụng phấn trắng viết bảngứngdụngtrình chiếu Microsoft Office Power Point cử tay, mở ứngdụngcử tay, tìm kiếm google thông qua ứngdụng GoogleChrome Sự phát triển camera đời ứngdụng thực tế tất yếu Nên chọn đề tài intel realsense camera 3D làm đồ án tốt nghiệp 1.2 Yêu cầu đề tài Nội dung yêu cầu thực đề đề tài: - Tìmhiểucamera 3D thư viện mở SDK - Nhận dạng tư tay di chuyển tay thông qua điểm đặc trưng khớp nối (joints) hay điểm đầu ngón tay (fingertip) để nhận dạng di chuyển tay để ứngdụnggiaotiếpngườimáy - Thực cài đặt chức tương tác ngườimáy thông qua ứngdụng Powerpoint, duyệt web (Chrome) hay ứngdụng game thông qua cửtay 1.3 Phương pháp Hình 1.1 – Minh họa bước xử lý chương trình Chương trình gồm bước sau: - Bước 1: Thu thập liệu, liệu lấy từ camera dạng khung ảnh (frame) gồm ảnh 2D liệu 3D Bước đảm nhận intel realsense 3D camera - Bước 2: Phân vùng để lấy vùng bàn tay tiến hành định vị vị trí khớp nối bàn tay nhận diện hình dáng bàn tay Nhận diện thành phần tay, chương trình sử dụng mô-đun handtracking thư viện SDK hỗ trợ với việc xử lý để nhận diện thành phần bàn tay - Bước 3: Nhận diện cử điệu tayứngdụng điều khiển, chương trình thực xử lý liệu gọi phương thức điều khiển máy tính 1.4 Cấu trúc báo cáo Báo cáo chia thành chương phụ lục: Chương I: Tổng quan đề tài - Phần trình bày lý chọn đề tài, yêu cầu đề tài tổng quan giải toán, tổng quan cấu trúc báo cáo Chương II: Giới thiệu camera 3D intel realsense - Phần tập trung giới thiệu lý thuyết sử dụngtrìnhtìmhiểu thực đồ án gồm kiến thức như: + Giới thiệu tổng quan camera 3D nói chung realsense camera nói riêng + Ngôn ngữ lậptrình C++ phương pháp lậptrình hướng đối tượng + Thư viện OpenCV + Kiến trúc interface cốt lõi intel realsense SDK + Mô-đun handtracking intel realsense SDK /** * class HandDetail hold all Joint Coordinates of Hand and its current Shape, * Gesture at the last Frame */ class HandDetail { public: enum HandShape // define types of Hand Shape { NONES = -1, ZERO, ONE, TWO, THREE, FOUR, FIVE, MOUSE }; enum HandGesture // define types of Hand Gesture { NONEG = 0, PULL_ UP, PULL_ RIGHT, PULL_ DOW N, PULL_ LEFT, PULL_F5, PULL_ ESC }; // public Methods HandDetail(); void updateHandDetail(Node* ); void runOffStream(string ); // input fro m TXT file to get Coordinate of Joints, one line - one frame void updateHandShape(); void updateHandGesture(); void updateGesture(); void pushGesture(char ); void resetPreviousGesture(); // set values with void updateCursor(); // only isMouseOn == true void readfile(vector &); void read View(); bool getView(); bool getChangeShape(); bool frameGate(); bool gestureGate(); bool mouseGate(); string getHandShapeToString(); HandDetail::HandShape getHandShape(); string getHandGestureToString(); HandDetail::HandGesture getHandGesture(); // use delayGesture variable every time that get a Hand Gesture string getStraightFingers(); // input from File void inFullHand(); private: // Joints Data 44 JOINT wrist; JOINT thu mb0, thumb 1, thu mb2, thumbTip; JOINT index0, index1, index2, indexTip; JOINT mid 0, mid 1, mid2, midTip; JOINT ring0, ring1, ring2, ringTip; JOINT p inky0, pin ky1, pin ky2, pinkyTip; // Joints Data at previous Frame, use to compute the Move Distance JOINT preM id0, preIndexTip, preWrist; HandShape i_handShape; // Shape at the last Frame string straightFingers; Hand Gesture i_handGesture; // save the lastest Gesture char* previousGesture; INPUT mouseInput; ifstream fin; // counter, flag int frameCount; int gestureCount; int mouseCount; int isMouseScroll; vector tap_right; vector tap_left; vector big 5_to_fist; vector fist_to_big5; vector _return; vector Two_Finger_Pinch_Open; vector window_ m; bool openSlide; bool isDoubleClick; bool R_ Button_Mouse; bool view_3d; bool isMouseOn; bool changeShape; bool gestureDelay; bool mouseDelay Left; bool isMouseDoubleClick; }; //===========================================================================// /** * In-Out methods * Calculate methods */ // set values = void init ializePositionWorld(JOINT* ); // output positonImage of a Joint (x, y) void outCoor2D(PXCHandData::Jo intData* ); // output positionWorld of a Jo int (x, y, z) void outCoor3D(PXCHandData::Jo intData* ); 45 // output Spped if a Joint - include ENDL void outSpeed3D(PXCHandData::JointData* ); // output all Joints, one Frame - one Line void outFullHand3D(Node* ); // input a Joint void inJoint(JOINT& ); // get Distance of Po ints float distance (JOINT* , JOINT* ); //get Distance 2D of Points (xOy) float distance2D(JOINT*, JOINT*); // detect whether the Finger is traight or not bool isStraightFinger (JOINT* , JOINT* , JOINT* , JOINT* ); bool isStraightFingerH (JOINT* , JOINT* , JOINT*); // detect whether the Finger is curved or not bool isCurvedFinger (JOINT* , JOINT* , JOINT* ); int CheckProcess(); bool GetActiveProcessName(TCHAR *, DW ORD); /** * Window methods */ void GenerateKey(int, BOOL); void MouseSetup(INPUT* ); void MouseMove(INPUT *, int, int); void MouseClick(INPUT *); void DoubleClick(int x, int y); void MouseScroll(bool eve); /** * Co mbined and call microphone */ void Co mbinedKey(vector, BOOL); void OutputBrowser(string); #endif TTli b.cpp // 2017 05 30 #include "TTlib.h" //===========================================================================// void HandDetail::runOffStream(string fileName) { freopen(fileName.c_str(), "r", stdin); while (t rue) { Sleep(10); inFullHand(); 46 updateHandShape(); updateHandGesture(); // output if (getHand Gesture() == HandDetail::PULL_ LEFT) cout get ChildNodes()[0].getCh ildNodes()[0].getNodeValue(); thumb2 = rootDataNode->get ChildNodes()[0].getCh ildNodes()[0].getCh ild Nodes()[0].getNodeValue(); thumbTip = rootDataNode>getChildNodes()[0].get ChildNodes()[0].getCh ild Nodes()[0].getCh ild Nodes()[0].getNodeValue(); index0 = rootDataNode->getCh ild Nodes()[1].getNodeValue(); index1 = rootDataNode->getCh ild Nodes()[1].getChildNodes()[0].getNodeValue(); index2 = rootDataNode->getCh ild Nodes()[1].getChildNodes()[0].getChildNodes()[0].getNodeValue(); indexTip = rootDataNode>getChildNodes()[1].get ChildNodes()[0].getCh ild Nodes()[0].getCh ild Nodes()[0].getNodeValue(); mid0 = rootDataNode->getCh ild Nodes()[2].getNodeValue(); mid1 = rootDataNode->getCh ild Nodes()[2].getCh ild Nodes()[0].getNodeValue(); mid2 = rootDataNode->getCh ild Nodes()[2].getCh ild Nodes()[0].getChildNodes()[0].getNodeValue(); midTip = rootDataNode>getChildNodes()[2].get ChildNodes()[0].getCh ild Nodes()[0].getCh ild Nodes()[0].getNodeValue(); ring0 = rootDataNode->getChildNodes()[3].getNodeValue(); ring1 = rootDataNode->getChildNodes()[3].getChildNodes()[0].getNodeValue(); ring2 = rootDataNode->getChildNodes()[3].getChildNodes()[0].get ChildNodes()[0].getNodeValue(); ringTip = rootDataNode>getChildNodes()[3].get ChildNodes()[0].getCh ild Nodes()[0].getCh ild Nodes()[0].getNodeValue(); pinky0 = rootDataNode->getChildNodes()[4].getNodeValue(); pinky1 = rootDataNode->getChildNodes()[4].getChildNodes()[0].getNodeValue(); pinky2 = rootDataNode->getChildNodes()[4].getChildNodes()[0].get ChildNodes()[0].getNodeValue(); pinkyTip = rootDataNode>getChildNodes()[4].get ChildNodes()[0].getCh ild Nodes()[0].getCh ild Nodes()[0].getNodeValue(); updateHandShape(); // if Mouse Mode OFF -> continue detect new Gesture if (isMouseOn == false) updateHandGesture(); else { if (R_Button_Mouse) { cout process MouseMove updateCursor(); } preWrist = wrist; } //===========================================================================// void HandDetail::updateHandShape() { 50 int dem = 0; // count the number of straight Fingers straightFingers = ""; // which Finger is straight // straight Thumb if (isStraightFinger(&thumb0, &thumb1, &thu mb2, &thu mbTip)) { dem++; straightFingers += "thumb "; } // straight Index if (isStraightFinger(&index0, &index1, &index2, &indexTip) && isStraightFingerH(&wrist, &index0, &indexTip)) { dem++; straightFingers += "index "; } // straight Mid if (isStraightFinger(&mid0, &mid 1, &mid2, &midTip) && isStraightFingerH(&wrist, &mid 0, &midTip )) { dem++; straightFingers += " mid "; } // straight Ring if (isStraightFinger(&ring0, &ring1, &ring2, &ringTip) && isStraightFingerH(&wrist, &ring 0, &ringTip)) { dem++; straightFingers += "ring "; } // straight Pinky if (isStraightFinger(&pinky 0, &p inky1, &p inky2, &p inkyTip ) && isStraightFingerH(&wrist, &pinky 0, &pinkyTip)) { dem++; straightFingers += "pinky "; } HandDetail::HandShape handShape; switch (dem) { case 0: handShape = HandDetail::ZERO; break; case 1: handShape = HandDetail::ONE; break; case 2: handShape = HandDetail::TWO; break; case 3: handShape = HandDetail::THREE; break; case 4: handShape = HandDetail::FOUR; 51 break; case 5: handShape = HandDetail::FIVE; break; default: handShape = HandDetail::NONES; break; } // Special Shape -> Mouse Mode On if (straightFingers == "index " || straightFingers == "thumb index ") { handShape = HandDetail::MOUSE; Co mbinedKey(b ig5_to_fist, FA LSE); isMouseOn = true; if ((straightFingers == "thumb " || handShape == HandDetail::ZERO) && isMouseScroll == && isMouseDoubleClick) { isMouseScroll = 0; } // 0.068 if (distance2D(&thu mbTip, &index0) >= distance(&index0, &indexTip)*0.8 && thumbTip.positionImage.x > index0.positionImage.x) R_Button_Mouse = true; else R_Button_Mouse = false; } else { if (i_handGesture == HandDetail::NONEG) { R_Button_Mouse = false; isMouseOn = false; if (handShape == HandDetail::FIVE && isMouseScroll == 0) { openSlide = true; isMouseScroll = 1; } else if ((straightFingers == "thumb " || handShape == HandDetail::ZERO) && isMouseScroll == 0) { isMouseScroll = 2; } else if (handShape == HandDetail::FIVE && isMouseScroll == && isMouseDoubleClick) { if (abs(wrist.positionImage.x preWrist.positionImage.x) = int(NUM_OF_HAND_PRE_MOVEM ENT * RATE_OF_HAND_ GESTURE_ DETECTOR)) i_handGesture = HandDetail::PULL_ DOWN; else if (left >= int(NUM_OF_HAND_PRE_MOVEM ENT * RATE_OF_HAND_ GESTURE_DETECTOR)) i_handGesture = HandDetail::PULL_ LEFT; else i_handGesture = HandDetail::NONEG; // Reset Queue if (i_handGesture != HandDetail::NONEG) { resetPreviousGesture(); } } //===========================================================================// void HandDetail::updateGesture() // need to be improved { float deltaX = mid0.positionWorld.x - p reMid0.positionWorld.x; float deltaY = mid0.positionWorld.y - p reMid0.positionWorld.y; if (abs(deltaX) >= abs(deltaY)) { if (deltaX >= LEA ST_MOVE_ DISTANCE) // left - increase X pushGesture('L'); else if (deltaX = LEA ST_MOVE_ DISTANCE) // up - increase Y pushGesture('U'); else if (deltaY = 1; i ) { previousGesture[i] = prev iousGesture[i-1]; } previousGesture[0] = gestureHeading; } //===========================================================================// void HandDetail::resetPreviousGesture() { for (int i = 0; i < NUM_OF_HA ND_PRE_M OVEM ENT; i++) previousGesture[i] = 'N'; } //===========================================================================// void HandDetail::updateCursor() { // get distance of Hand Move float deltaX = mid0.positionWorld.x - p reMid0.positionWorld.x; float deltaY = mid0.positionWorld.y - p reMid0.positionWorld.y; // Mouse Click Event is Delayed if (mouseDelay Left) { if (mouseGate()) mouseDelay Left = false; } else // mouseDelayLeft == false { // detect MouseClick float deltaIndexTip = abs(indexTip.positionWorld.x - preIndexTip.positionWorld.x) + abs(indexTip.positionWorld.y preIndexTip.positionWorld.y) abs(indexTip.positionWorld.z - preIndexTip.positionWorld.z); + float deltaZ = abs(indexTip.positionWorld.z - preIndexTip.positionWorld.z); //if (deltaIndexTip >= abs(deltaX) * M OUSE_ CLICK_RATE && // deltaIndexTip >= abs(deltaY) * MOUSE_ CLICK_ RATE LEAST_M OVE_ DISTANCE*3) if (deltaZ >= LEAST_MOVE_DISTA NCE) { // process Mouse Click Event //MouseClick(&mouseInput); mouseDelay Left = true; 55 && deltaIndexTip >= } } // compute the distance that Mouse will move (p ixel) int x = (int) (-deltaX / M OVE_ DISTANCE_PER_ PIXCEL); int y = (int) (-deltaY / M OVE_ DISTANCE_PER_ PIXCEL); // Thie out //cout