鄒 龍 華 ,朱 永 強(qiáng) ,張 平 霞
(青島理工大學(xué)機(jī)械與汽車工程學(xué)院,青島 266520)
手勢(shì)識(shí)別是指通過計(jì)算機(jī)攝像頭等光學(xué)傳感器識(shí)別人手(或手和臂的組合)姿態(tài)或動(dòng)作并判斷其意義后進(jìn)行人機(jī)交互的技術(shù)。為使人機(jī)交互變得更加順暢,一些研究人員采用OpenCV(一個(gè)基于Apache 2.0 許可(開源)發(fā)行的跨平臺(tái)計(jì)算機(jī)視覺和機(jī)器學(xué)習(xí)軟件庫(kù))對(duì)手勢(shì)動(dòng)作進(jìn)行識(shí)別及跟蹤,通過MediaPipe 技術(shù)實(shí)時(shí)生成手掌檢測(cè)模型及手部坐標(biāo)模型,將手勢(shì)實(shí)時(shí)跟蹤結(jié)果計(jì)算出來(lái)并傳遞給計(jì)算機(jī),以實(shí)現(xiàn)基于手勢(shì)識(shí)別的人機(jī)交互。[1-2]文獻(xiàn)[2]設(shè)計(jì)了一種基于WiFi 的手勢(shì)控制識(shí)別系統(tǒng),根據(jù)WiFi 定位算法計(jì)算手勢(shì)設(shè)備佩戴者與多種智能設(shè)備之間的距離,選定接收設(shè)備;由手勢(shì)設(shè)備的加速度感應(yīng)器收集手勢(shì)數(shù)據(jù),并通過滑動(dòng)均值濾波算法進(jìn)行數(shù)據(jù)預(yù)處理,對(duì)所截取出的數(shù)據(jù)采用DTW(Dynamic Time Warping,動(dòng)態(tài)時(shí)間歸整,簡(jiǎn)稱DTW)算法,將手勢(shì)信息和手勢(shì)庫(kù)的數(shù)據(jù)進(jìn)行匹配,從而獲得特征手勢(shì)信息;將特征手勢(shì)信息轉(zhuǎn)換成指令,通過WiFi 模塊發(fā)送信號(hào)給被控制設(shè)備,最終實(shí)現(xiàn)了8 種手勢(shì)的判別并控制多種設(shè)備的運(yùn)行,手勢(shì)識(shí)別率達(dá)到98%。文獻(xiàn)[3]以MSP430 單片機(jī)為主控器,以FDC2214 傳感器為檢測(cè)核心,實(shí)現(xiàn)了學(xué)習(xí)和判決兩種工作模式。文獻(xiàn)[4]根據(jù)MediaPipe 技術(shù)研究了一種通過構(gòu)建目標(biāo)手部模型、關(guān)鍵點(diǎn)定位和數(shù)字手勢(shì)識(shí)別模塊實(shí)現(xiàn)數(shù)字手勢(shì)識(shí)別的方法。文獻(xiàn)[5]提出一種結(jié)合手勢(shì)的整體移動(dòng)與部分手指移動(dòng)的識(shí)別模式,根據(jù)此模式對(duì)DHG-14/28 動(dòng)態(tài)手勢(shì)數(shù)據(jù)集中14 類手勢(shì)和28 類手勢(shì)進(jìn)行實(shí)驗(yàn),分類識(shí)別準(zhǔn)確率分別為98.57%和88.29%。上述手勢(shì)識(shí)別方法在實(shí)際應(yīng)用中對(duì)硬件和軟件的要求高,操作不夠簡(jiǎn)便?;诖?,本文提出一種硬件配置成本低且操作簡(jiǎn)便的基于手勢(shì)識(shí)別的小車控制方法。
二軸輪式智能小車主要由Arduino Nano 單片機(jī)、攝像頭、電源、4 個(gè)電機(jī)、車架板、控制模塊和4 個(gè)橡膠車輪組成。Arduino Nano 是具有USB 接口的Arduino 小型版本,采用無(wú)電源插座和Mini-B 型的USB 接口,板型小巧,核心處理器是ATmega168(Nano 2.x)和ATmega328(Nano 3.0),供電方式主要有mini-B USB 接口供電和pin27 +5 V 接外部直流5 V 電源兩種。在此實(shí)驗(yàn)中采用外接+5 V 電源的方式給Arduino Nano 供電。[6]如圖1 所示,兩組車輪分別安裝在兩組電機(jī)轉(zhuǎn)軸上,使電機(jī)能夠帶動(dòng)車輪旋轉(zhuǎn),圖1 中兩組電機(jī)安裝在車架板的兩側(cè),對(duì)稱分布,攝像頭安裝在車架板的前部正中央,便于識(shí)別手勢(shì),Arduino Nano 單片機(jī)、控制模塊和電源均被固定在車架板的上面。
圖1 二軸輪式智能小車
整個(gè)軟件控制系統(tǒng)可分為兩部分:①基于攝像頭的手勢(shì)攝取模塊,主要通過小車攝像頭攝取外部手勢(shì)并將圖像信息傳遞給Arduino Nano 單片機(jī)。②二軸輪式小車的下位機(jī)軟件控制系統(tǒng),主要是通過在Arduino Nano 單片機(jī)中運(yùn)行的Python 代碼對(duì)手勢(shì)攝取模塊傳遞過來(lái)的手勢(shì)圖像進(jìn)行手部坐標(biāo)標(biāo)記,并對(duì)坐標(biāo)點(diǎn)之間的距離和實(shí)時(shí)跟蹤結(jié)果進(jìn)行計(jì)算處理,再將計(jì)算結(jié)果傳遞給計(jì)算機(jī)控制模塊,隨后控制模塊根據(jù)計(jì)算結(jié)果來(lái)控制小車進(jìn)行前進(jìn)、后退、左轉(zhuǎn)、右轉(zhuǎn)和停止。在運(yùn)行程序進(jìn)行手勢(shì)識(shí)別的過程中,做出前進(jìn)、后退、左轉(zhuǎn)和右轉(zhuǎn)的手勢(shì)時(shí),食指、中指、無(wú)名指和小拇指的斜率是相同的,攝像頭檢測(cè)到手部關(guān)鍵點(diǎn)后,將會(huì)進(jìn)入循環(huán)開始處理每個(gè)檢測(cè)到的手部關(guān)鍵點(diǎn),并獲取每個(gè)關(guān)鍵點(diǎn)的坐標(biāo),將坐標(biāo)存儲(chǔ)在xs 和ys數(shù)組中。然后,在圖像上繪制關(guān)鍵點(diǎn)的圓圈和標(biāo)注;再調(diào)用g_count 函數(shù)來(lái)計(jì)算手部特征值,并根據(jù)特征值輸出不同命令。
以前進(jìn)手勢(shì)程序代碼為例,含義為4 個(gè)絕對(duì)值差值的和小于4.5、0 點(diǎn)到12 點(diǎn)之間的距離大于100 mm且中指斜率大于2,部分程序代碼為:
if(bs0+bs1+bs2+bs3)<4.5 and dis>100 and bs[1]>2:print("前進(jìn)")#前進(jìn)左手掌心向前
elif(bs0+bs1+bs2+bs3)<4.5 and dis>100 and -1<bs[1]<0:print("左轉(zhuǎn)")#左轉(zhuǎn)右手五指并攏指向左邊
elif(bs0+bs1+bs2+bs3)<4.5 and dis>100 and0<bs[1]<1:print("右轉(zhuǎn)")#左手五指并攏指向右邊
elif(bs0+bs1+bs2+bs3)>4.5 and dis>100 and bs[1]<-2:print("后退")#后退右手掌心向前
elif dis<100 and bs[1]<-1:
print("停止")#停止握拳
本次實(shí)驗(yàn)采用Python 3.9 軟件,所需的庫(kù)包括OpenCV、Mediapipe、Time、Math、Cmath。其中OpenCV是視覺庫(kù),用于處理圖像和視頻;Mediapipe 是一個(gè)集成的機(jī)器學(xué)習(xí)視覺算法工具庫(kù),在此實(shí)驗(yàn)中通過Mediapipe 對(duì)手部進(jìn)行識(shí)別追蹤,再利用手部21 個(gè)坐標(biāo)點(diǎn)的位置計(jì)算,實(shí)現(xiàn)手勢(shì)識(shí)別功能;Time 用于計(jì)算幀率;Math 和Cmath 用于進(jìn)行數(shù)值計(jì)算。實(shí)驗(yàn)創(chuàng)建了3 個(gè)空列表xs、ys、bs,分別用于存儲(chǔ)手部關(guān)鍵點(diǎn)的x坐標(biāo)、y坐標(biāo)和手部關(guān)鍵點(diǎn)的相關(guān)計(jì)算值的數(shù)組,然后使用for 循環(huán)初始化這些列表,具體函數(shù)實(shí)現(xiàn)如下:
xs =[]
ys =[]
bs =[]
#大小為21 的數(shù)組初始化
for i in range(0,21):
xs.append(0)
ys.append(0)
for i in range(0,4):
bs.append(0)
定義了名為two_point_distance 的函數(shù),用于計(jì)算兩點(diǎn)之間的距離;定義了g_count 的函數(shù)用于計(jì)算手部的特征值;并使用sqrt 函數(shù)來(lái)計(jì)算歐幾里得距離和返回距離值,具體函數(shù)實(shí)現(xiàn)如下:
def two_point_distance(x1,y1,x2,y2 ):
dis =abs(math.sqrt((x2 -x1)*(x2 -x1)+(y2 -y1)*(y2 -y1)))
return dis
def g_count();
a=5
i=0
最后,在主循環(huán)中,使用while True 持續(xù)從攝像頭讀取視頻幀,具體函數(shù)實(shí)現(xiàn)如下:
while True:count=()
success,img =cap.read()
imgRGB=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)results =hands.process(imgRGB)
小車的手勢(shì)識(shí)別程序運(yùn)行邏輯圖如圖2 所示。
圖2 小車手勢(shì)識(shí)別程序運(yùn)行邏輯圖
將小車前端的攝像頭正對(duì)著操作者,手在攝像頭的正前方,做出“掌心向前且五指并攏向上”(見圖3a)、“掌心向后且五指并攏向下”(見圖3b)、“握拳”(見圖3c)、“右手五指并攏向左”(見圖3d)和“左手五指并攏向右”(見圖3e)的手勢(shì),分別可以得出“后退”“前進(jìn)”“停止”“右轉(zhuǎn)”和“左轉(zhuǎn)”的識(shí)別結(jié)果,通過測(cè)試,手勢(shì)識(shí)別率達(dá)到97.6%。Arduino Nano 單片機(jī)根據(jù)Python 程序計(jì)算出的手勢(shì)識(shí)別結(jié)果,執(zhí)行相應(yīng)手勢(shì)對(duì)應(yīng)的控制命令,且將控制命令直接傳輸給小車的控制模塊,達(dá)到控制圖1 所示二軸輪式小車的對(duì)應(yīng)行駛功能的目的,經(jīng)過實(shí)驗(yàn),小車根據(jù)指令運(yùn)動(dòng)的準(zhǔn)確率達(dá)到了97%,且小車能夠根據(jù)指令完成后退、前進(jìn)、停止、右轉(zhuǎn)和左轉(zhuǎn)動(dòng)作。
圖3 小車控制手勢(shì)示意圖
本文利用Python 軟件設(shè)計(jì)了一種基于手勢(shì)識(shí)別的小車控制方法,實(shí)現(xiàn)了5 種手勢(shì)的小車穩(wěn)定行駛控制,操作簡(jiǎn)單方便。經(jīng)過測(cè)試,此手勢(shì)識(shí)別方法的識(shí)別準(zhǔn)確率達(dá)到97.6%,基本能實(shí)現(xiàn)讓小車根據(jù)指令進(jìn)行運(yùn)動(dòng)。后續(xù)研究需進(jìn)一步提高手勢(shì)識(shí)別的準(zhǔn)確率。