利用Kinect實現用指尖隔空控制鼠標(源碼放出)


# 簡介 此程序為利用Kinect實現用手指隔空控制鼠標,是我另一個項目的一部分,因為在另外那個項目中鼠標的click是通過一種特殊的方式實現的,因此這個程序**只實現了用手控制鼠標的移動,並沒有點擊的功能**。相比Leapmotion,利用Kinect來控制鼠標可以大幅增加操控范圍,使用者可以隨意走動,而不是被固定在桌面前。

好像很多人需要這個,但是網上為數不多的代碼都是Kinect V1的,所以放出我的代碼來供大家討論。

源碼

https://github.com/Beginner258/Kinect_Cursor_Control

運行環境

  • Kinect for Windows V2
  • Kinect SDK 2.0
  • OpenCV 3.0

使用方法

首先需要讓Kinect識別出你,建議距離0.5m以上4m以內並且正對攝像頭,如果位置合適的話瞬間就能識別出,如果幾秒鍾都沒有識別出來就請調節位置。然后將手放入操作窗口就可以控制鼠標了,綠色的點代表指尖。

效果

原理介紹

指尖識別基礎

程序的核心在於指尖識別,我發現網上關於指尖識別的資料不多,所以自己想了個很簡單的辦法,不過效果還不錯。首先應該知道三點:

1.  Kinect可以分辨出畫面中哪一部分是人體
2.  Kinect帶有深度攝像頭,可以獲取物體到攝像頭的距離
3.  Kinect可以獲取到人體的最多25個關節點的位置

減小搜索空間

為了尋找指尖,沒有必要在整副畫面中去搜索,那樣會導致效率非常低。指尖肯定是在手部關節點(Hand)附近的,因此只需要獲取到手部關節點的位置然后再拓展出一片區域,在這片區域里進行搜索就行了。之所以取Hand而不是取HandTip,是因為后者的穩定性非常差,即使在一個合適的距離正對Kinect也不一定能識別出來。

指尖識別

這時候就可以根據指尖的特征來進行指尖識別了。不過實際上我識別出的不是指尖,而是指尖上方的一點。此點的特征如下:

  1. 不屬於人體
  2. 或者屬於人體,但是和手部關節點不在同一個平面上(允許有誤差)
  3. 到手部關節點的位置在某個合適的范圍內
  4. 下面連續N(這里我取N為5)個像素都屬於人體

首先,對於第一點很好理解,因為上面說了識別的不是指尖,而是指尖上方的一點。

第二點是用來處理手移動到身邊正前方的時候的情況,比如手在胸前,這時候指尖上方的點都是屬於人體的,不滿足第一點。這里的誤差指的是手和小臂成90度時的深度差,一般15cm左右。

第三點是為了消除兩根手指根部之間的那個位置形成的誤判,同時也進一步減小了搜索空間,正常情況下手指到手腕的距離都在10~25cm范圍內,這里把拇指篩掉了,一般也不會用拇指去操作。如果要恢復拇指的話調整下參數就可以。

第四個條件篩選出了離手指尖最近的那個點。

確定操作窗口

為了便於操作和觀察,我設置了一個操作窗口,位於肩部的左上方和右上方,根據操作手的左右而調整。這個窗口就代表着電腦的屏幕,手指在窗口里的位置就是鼠標在電腦屏幕上的位置。這里窗口的大小是根據關節點HeadNeck的距離作為單位長度算出來的,也就是說能根據人體到Kinect的距離來調整操作窗口的大小。同時這個窗口是實時更新的,會根據人體的位置而進行調整。

這里要說一下,如果操作的位置相對固定,那么建議識別出窗口后就不要再更新,將操作窗口固定,因為這樣能夠大幅度提高鼠標的穩定性,同時上傳了一份以這種方式來做的代碼,不過這份代碼只實現了單手控制。

抖動消除

這是個不太好處理的問題,因為容易影響到正常操作。這里我設置了一個移動的閾值,如果和上一個位置相比,鼠標的位置改變很微小,那么就保持上次的位置不變。還可以再加入一個判斷位置突變的閾值,如果當前位置和上一次位置相距太遠,就可以判斷為非法而篩去。

指尖位置與鼠標位置的轉換

黑色框為程序里確定的操作窗口,大寫的X和Y代表的是屏幕的寬和高,紅色框為電腦屏幕,假設人的手指在的位置,如果想將鼠標也映射到同樣的位置,那么就有 的等比關系成立。電腦屏幕的寬和高,實際上是不需要考慮分辨率的,因為在鼠標的坐標系下,電腦的寬和高都被分成了65535個單位,所以寬和高可以視為65535。根據這些,就可以算出的值來。






免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM