【机器视觉案例】(9) AI视觉,手势控制电脑键盘,附python完整代码
各位同學(xué)好,今天和大家分享一下如何使用 opencv+mediapipe 完成遠(yuǎn)程手勢(shì)控制電腦鍵盤。感興趣的可以看一下我前面一篇手勢(shì)控制電腦鼠標(biāo):https://blog.csdn.net/dgvv4/article/details/122268203?spm=1001.2014.3001.5501, 把這兩個(gè)結(jié)合起來(lái)去打游戲會(huì)不會(huì)很有意思呢。先放張圖看效果。
這里用百度搜索欄做測(cè)試,搜索框中的內(nèi)容和opencv顯示窗口上的內(nèi)容是同步打印出來(lái)的。
工作原理:如果檢測(cè)到食指指尖關(guān)鍵點(diǎn)坐標(biāo)在某個(gè)按鍵框的范圍內(nèi)部,那么該按鍵顯示綠色;如果食指指尖和中指指尖之間的距離小于規(guī)定距離,就認(rèn)為是點(diǎn)擊食指指尖所在的按鍵,按鍵變?yōu)榧t色;設(shè)置1秒內(nèi)同一個(gè)按鍵只能點(diǎn)擊一次,避免重復(fù)出現(xiàn)多個(gè)相同按鍵值。
1. 安裝工具包
# 安裝工具包
pip install opencv-contrib-python # 安裝opencv
pip install mediapipe # 安裝mediapipe
# pip install mediapipe --user #有user報(bào)錯(cuò)的話試試這個(gè)
pip install cvzone # 安裝cvzone
pip install pynput # 鍵盤控制單元# 導(dǎo)入工具包
import numpy as np
import cv2
from cvzone.HandTrackingModule import HandDetector # 手部追蹤方法
import mediapipe as mp
import time
from pynput.keyboard import Controller # 鍵盤控制模塊
21個(gè)手部關(guān)鍵點(diǎn)信息如下,本節(jié)我們主要研究食指指尖"8"和中指指尖"12"的坐標(biāo)信息。
2. 手部關(guān)鍵點(diǎn)檢測(cè),制作虛擬鍵盤
2.1 手部關(guān)鍵點(diǎn)檢測(cè)
(1) cvzone.HandTrackingModule.HandDetector() ? 手部關(guān)鍵點(diǎn)檢測(cè)方法
參數(shù):
mode: 默認(rèn)為 False,將輸入圖像視為視頻流。它將嘗試在第一個(gè)輸入圖像中檢測(cè)手,并在成功檢測(cè)后進(jìn)一步定位手的坐標(biāo)。在隨后的圖像中,一旦檢測(cè)到所有 maxHands 手并定位了相應(yīng)的手的坐標(biāo),它就會(huì)跟蹤這些坐標(biāo),而不會(huì)調(diào)用另一個(gè)檢測(cè),直到它失去對(duì)任何一只手的跟蹤。這減少了延遲,非常適合處理視頻幀。如果設(shè)置為 True,則在每個(gè)輸入圖像上運(yùn)行手部檢測(cè),用于處理一批靜態(tài)的、可能不相關(guān)的圖像。
maxHands: 最多檢測(cè)幾只手,默認(rèn)為 2
detectionCon: 手部檢測(cè)模型的最小置信值(0-1之間),超過(guò)閾值則檢測(cè)成功。默認(rèn)為 0.5
minTrackingCon: 坐標(biāo)跟蹤模型的最小置信值 (0-1之間),用于將手部坐標(biāo)視為成功跟蹤,不成功則在下一個(gè)輸入圖像上自動(dòng)調(diào)用手部檢測(cè)。將其設(shè)置為更高的值可以提高解決方案的穩(wěn)健性,但代價(jià)是更高的延遲。如果 mode 為 True,則忽略這個(gè)參數(shù),手部檢測(cè)將在每個(gè)圖像上運(yùn)行。默認(rèn)為 0.5
它的參數(shù)和返回值類似于官方函數(shù) mediapipe.solutions.hands.Hands()
(2)cvzone.HandTrackingModule.HandDetector.findHands() ? ?找到手部關(guān)鍵點(diǎn)并繪圖
參數(shù):
img: 需要檢測(cè)關(guān)鍵點(diǎn)的幀圖像,格式為BGR
draw: 是否需要在原圖像上繪制關(guān)鍵點(diǎn)及識(shí)別框
flipType: 圖像是否需要翻轉(zhuǎn),當(dāng)視頻圖像和我們自己不是鏡像關(guān)系時(shí),設(shè)為True就可以了
返回值:
hands: 檢測(cè)到的手部信息,包含:21個(gè)關(guān)鍵點(diǎn)坐標(biāo),檢測(cè)框坐標(biāo)及寬高,檢測(cè)框中心坐標(biāo),檢測(cè)出是哪一只手。
img: 返回繪制了關(guān)鍵點(diǎn)及連線后的圖像
2.2 繪制虛擬鍵盤
本節(jié)只創(chuàng)建鍵盤上的部分按鍵用于演示,定義類Button不需要一個(gè)一個(gè)單獨(dú)繪制矩形按鍵。使用一個(gè)循環(huán),分別對(duì)每個(gè)按鍵實(shí)例化,將實(shí)例化結(jié)果保存在 buttonList 列表中。在第(6)步繪制鍵盤時(shí),逐個(gè)取出實(shí)例化對(duì)象,在窗口上繪制30個(gè)按鍵。
代碼如下:
import cv2
from cvzone.HandTrackingModule import HandDetector # 導(dǎo)入手部檢測(cè)模塊#(1)捕捉電腦攝像頭
cap = cv2.VideoCapture(0) # 0代表自己的電腦攝像頭,1代表外接攝像頭
cap.set(3, 1280) # 設(shè)置顯示框的寬1280
cap.set(4, 720) # 設(shè)置顯示框的高720#(2)接收手部檢測(cè)方法
detector = HandDetector(mode=False, # 視頻流圖像 maxHands=1, # 最多檢測(cè)一只手detectionCon=0.5, # 最小檢測(cè)置信度minTrackCon=0.5) # 最小跟蹤置信度#(3)創(chuàng)建一個(gè)類用于構(gòu)造鍵盤按鍵
class Button:# 初始化,按鍵的左上坐標(biāo)pos(列表類型),文本信息text(字符串類型),按鍵的寬高sizedef __init__(self, pos:list, text:str, size=[90,90]):# 分配屬性self.pos = posself.text = textself.size = size# 在類的內(nèi)部定義方法def draw(self, img):x1, y1 = self.pos # 矩形框的左上角坐標(biāo)w, h = self.size # 矩形框的寬高# img畫板,矩形框左上角坐標(biāo),矩形框右下角坐標(biāo),顏色,-1代表顏色填充cv2.rectangle(img, (x1, y1), (x1+w, y1+h), (255,0,0), -1)# 美化一下矩形框cv2.rectangle(img, (x1, y1), (x1+w, y1+h), (255,255,0), 4)# 在矩形框上顯示字符串信息cv2.putText(img, self.text, (x1+25, y1+65), cv2.FONT_HERSHEY_COMPLEX, 1.8, (255,255,255), 3)# 創(chuàng)建一個(gè)列表存放鍵盤上每個(gè)按鍵的文本信息
keys = [['Q','W','E','R','T','Y','U','I','O','P'],['A','S','D','F','G','H','J','K','L',';'],['Z','X','C','V','B','N','M',',','.','/']]# 存放每一個(gè)按鍵的信息
buttonList = []# 通過(guò)循環(huán)來(lái)實(shí)例化所有按鍵
for i in range(3): # 鍵盤文本列表有三行# 分別實(shí)例化每一行的按鈕信息 for x, key in enumerate(keys[i]): #返回每個(gè)元素的索引和值# 確定每個(gè)按鍵的左上角坐標(biāo)位置px = 115*x + 30 + 40*i #水平方向每?jī)蓚€(gè)按鍵之間間隔115,每次換行縮進(jìn)40,初始位置x=30py = 115*i + 50 # 豎直方向每?jī)蓚€(gè)按鍵之間間隔115,初始位置y=50# 將實(shí)例化后的對(duì)象存放在列表中buttonList.append(Button([px, py], key))# 每次換行后px坐標(biāo)重置x = 0#(4)處理每一幀圖像
while True:# 返回是否讀取成功,和讀取的幀圖像success, img = cap.read()# 翻轉(zhuǎn)圖像,讓自己和攝像頭呈鏡像關(guān)系img = cv2.flip(img, 1) # 1代表水平翻轉(zhuǎn),0代表上下翻轉(zhuǎn)#(5)檢測(cè)手部關(guān)鍵點(diǎn)# 檢測(cè)手部關(guān)鍵點(diǎn)信息,返回手部信息hands,繪制關(guān)鍵點(diǎn)后的圖像imghands, img = detector.findHands(img, flipType=False)#(6)繪制鍵盤for i in range(3*len(keys[0])): # 一共有3行10列個(gè)按鍵# 調(diào)用類中的繪圖方法,顯示每個(gè)鍵盤按鍵buttonList[i].draw(img)#(7)顯示圖像cv2.imshow('video', img)# 每幀圖像滯留時(shí)間,ESC鍵退出if cv2.waitKey(1) & 0xFF==27:break# 釋放視頻資源
cap.release()
cv2.destroyAllWindows()
手部檢測(cè)結(jié)果及虛擬鍵盤如下圖所示。
3. 鎖定按鍵位置
從下面代碼的第(6)步開(kāi)始是鎖定鍵盤按鍵的位置。通過(guò) detector.findHands() 返回手部檢測(cè)信息hands列表,由0或1或2個(gè)字典組成,如果檢測(cè)到一只手就返回一個(gè)字典。字典中包含:lmList?代表21個(gè)手部關(guān)鍵點(diǎn)的像素坐標(biāo);bbox?代表檢測(cè)框的左上角坐標(biāo)和框的寬高;center?代表檢測(cè)框的中心點(diǎn)的像素坐標(biāo);type?代表檢測(cè)出的是左手還是右手。
只需要知道食指指尖坐標(biāo) lmList[8] 在哪個(gè)按鍵的范圍內(nèi),并計(jì)算食指指尖和中指指尖之間的距離,距離小于某個(gè)值認(rèn)為是點(diǎn)擊按鍵。距離計(jì)算方法,detector.findDistance(pt1, pt2, img) 傳入兩個(gè)關(guān)鍵點(diǎn)坐標(biāo)。返回值為 distance 代表兩個(gè)關(guān)鍵點(diǎn)之間的距離, info 代表指尖連線的起點(diǎn)、中點(diǎn)、終點(diǎn), img 代表繪制指尖連線后的圖像。
在上述代碼中補(bǔ)充:
import cv2
from cvzone.HandTrackingModule import HandDetector # 導(dǎo)入手部檢測(cè)模塊#(1)捕捉電腦攝像頭
cap = cv2.VideoCapture(0) # 0代表自己的電腦攝像頭,1代表外接攝像頭
cap.set(3, 1280) # 設(shè)置顯示框的寬1280
cap.set(4, 720) # 設(shè)置顯示框的高720#(2)接收手部檢測(cè)方法
detector = HandDetector(mode=False, # 視頻流圖像 maxHands=1, # 最多檢測(cè)一只手detectionCon=0.5, # 最小檢測(cè)置信度minTrackCon=0.5) # 最小跟蹤置信度#(3)創(chuàng)建一個(gè)類用于構(gòu)造鍵盤按鍵
class Button:# 初始化,按鍵的左上坐標(biāo)pos(列表類型),文本信息text(字符串類型),按鍵的寬高sizedef __init__(self, pos:list, text:str, size=[90,90]):# 分配屬性self.pos = posself.text = textself.size = size# 在類的內(nèi)部定義方法,默認(rèn)內(nèi)部深藍(lán)色填充,邊框?yàn)闇\藍(lán)色def draw(self, img, colorIn, colorBd):x1, y1 = self.pos # 矩形框的左上角坐標(biāo)w, h = self.size # 矩形框的寬高# img畫板,矩形框左上角坐標(biāo),矩形框右下角坐標(biāo),顏色,-1代表顏色填充cv2.rectangle(img, (x1, y1), (x1+w, y1+h), colorIn, -1)# 美化一下矩形框cv2.rectangle(img, (x1, y1), (x1+w, y1+h), colorBd, 4)# 在矩形框上顯示字符串信息cv2.putText(img, self.text, (x1+25, y1+65), cv2.FONT_HERSHEY_COMPLEX, 1.8, (255,255,255), 3)# 創(chuàng)建一個(gè)列表存放鍵盤上每個(gè)按鍵的文本信息
keys = [['Q','W','E','R','T','Y','U','I','O','P'],['A','S','D','F','G','H','J','K','L',';'],['Z','X','C','V','B','N','M',',','.','/']]# 存放每一個(gè)按鍵的信息
buttonList = []# 矩形按鍵的顏色
colorIn = (255,0,0) # 按鍵內(nèi)部填充的顏色
colorBd = (255,255,0) # 按鍵的邊框顏色 # 通過(guò)循環(huán)來(lái)實(shí)例化所有按鍵
for i in range(3): # 鍵盤文本列表有三行# 分別實(shí)例化每一行的按鈕信息 for x, key in enumerate(keys[i]): #返回每個(gè)元素的索引和值# 確定每個(gè)按鍵的左上角坐標(biāo)位置px = 115*x + 30 + 40*i #水平方向每?jī)蓚€(gè)按鍵之間間隔115,每次換行縮進(jìn)40,初始位置x=30py = 115*i + 50 # 豎直方向每?jī)蓚€(gè)按鍵指尖間隔115,初始位置y=50# 將實(shí)例化后的對(duì)象存放在列表中buttonList.append(Button([px, py], key))# 每次換行后px坐標(biāo)重置x = 0#(4)處理每一幀圖像
while True:# 返回是否讀取成功,和讀取的幀圖像success, img = cap.read()# 翻轉(zhuǎn)圖像,讓自己和攝像頭呈鏡像關(guān)系img = cv2.flip(img, 1) # 1代表水平翻轉(zhuǎn),0代表上下翻轉(zhuǎn)#(5)繪制鍵盤for i in range(3*len(keys[0])): # 一共有3行10列個(gè)按鍵# 調(diào)用類中的繪圖方法,顯示每個(gè)鍵盤按鍵buttonList[i].draw(img, colorIn, colorBd)#(6)檢測(cè)手部關(guān)鍵點(diǎn)# 檢測(cè)手部關(guān)鍵點(diǎn)信息,返回手部信息hands,繪制關(guān)鍵點(diǎn)后的圖像imghands, img = detector.findHands(img, flipType=False)# 如果檢測(cè)到手了,才執(zhí)行下一步if hands:# 獲取21個(gè)手部關(guān)鍵點(diǎn)信息lmList = hands[0]['lmList']# 獲取食指指尖關(guān)鍵點(diǎn)坐標(biāo)x1, y1 = lmList[8]# 獲取中指指尖關(guān)鍵點(diǎn)坐標(biāo)x2, y2 = lmList[12]#(7)遍歷所有的按鍵,檢查食指指尖在哪個(gè)按鍵的范圍內(nèi)for index, button in enumerate(buttonList): # botton存放的是類實(shí)例化后的對(duì)象# 所在矩形的左上坐標(biāo)和寬高x0, y0 = button.posw, h = button.size# 如果食指指尖在某個(gè)矩形框中,改變鍵盤按鍵顏色if x0<=x1<=x0+w and y0<=y1<=y0+h:# 按鍵內(nèi)部填充顏色cv2.rectangle(img, (x0, y0), (x0+w, y0+h), (0,255,0), -1)# 按鍵邊框顏色cv2.rectangle(img, (x0, y0), (x0+w, y0+h), (0,0,255), 4)# 按鍵上的字符串cv2.putText(img, button.text, (x0+25, y0+65), cv2.FONT_HERSHEY_COMPLEX, 1.8, (255,255,255), 3)#(8)計(jì)算食指和中指指尖之間的距離distance, _, img = detector.findDistance((x1,y1), (x2,y2), img)# 如果指尖距離小于80,認(rèn)為是點(diǎn)擊按鍵if distance<50:# 點(diǎn)擊按鍵改變按鍵顏色cv2.rectangle(img, (x0, y0), (x0+w, y0+h), (0,0,255), -1)# 按鍵上的字符串cv2.putText(img, button.text, (x0+25, y0+65), cv2.FONT_HERSHEY_COMPLEX, 1.8, (255,255,255), 3)#(9)顯示圖像cv2.imshow('video', img)# 每幀圖像滯留時(shí)間,ESC鍵退出if cv2.waitKey(1) & 0xFF==27:break# 釋放視頻資源
cap.release()
cv2.destroyAllWindows()
顯示結(jié)果如下,如果食指在某個(gè)按鍵矩形中,并且食指和中指之間的距離大于規(guī)定值,那么這個(gè)按鍵填充綠色,邊界框變紅色。食指在某個(gè)按鍵矩形中,并且食指和中指之間的距離小于規(guī)定值,那么這個(gè)按鍵和邊界框都填充紅色。
4. 激活鍵盤按鍵
下面的第(9)步,為了驗(yàn)證點(diǎn)擊按鍵時(shí)?opencv 畫面上的點(diǎn)擊內(nèi)容和百度搜索框的輸入內(nèi)容是否同步,在opencv畫面上創(chuàng)建一個(gè)矩形框用來(lái)顯示字符。
通過(guò) keyboard.press() 獲得鍵盤響應(yīng),輸入值是鍵盤上的某個(gè)字符,表示點(diǎn)擊鍵盤上的該字符。
由于每一幀播放的非常快,可能只點(diǎn)擊了一次按鍵,卻打印出來(lái)很多相同的字符。使用休眠函數(shù)?time.sleep(t)?,每點(diǎn)擊一次按鍵就暫停程序的執(zhí)行,暫停 t 秒時(shí)間。??
import cv2
from cvzone.HandTrackingModule import HandDetector # 導(dǎo)入手部檢測(cè)模塊
from time import sleep
from pynput.keyboard import Controller # 鍵盤控制單元#(1)捕捉電腦攝像頭
cap = cv2.VideoCapture(0) # 0代表自己的電腦攝像頭,1代表外接攝像頭
cap.set(3, 1280) # 設(shè)置顯示框的寬1280
cap.set(4, 720) # 設(shè)置顯示框的高720#(2)接收手部檢測(cè)方法
detector = HandDetector(mode=False, # 視頻流圖像 maxHands=1, # 最多檢測(cè)一只手detectionCon=0.5, # 最小檢測(cè)置信度minTrackCon=0.5) # 最小跟蹤置信度# 接收鍵盤控制單元
keyboard = Controller()#(3)創(chuàng)建一個(gè)類用于構(gòu)造鍵盤按鍵
class Button:# 初始化,按鍵的左上坐標(biāo)pos(列表類型),文本信息text(字符串類型),按鍵的寬高sizedef __init__(self, pos:list, text:str, size=[90,90]):# 分配屬性self.pos = posself.text = textself.size = size# 在類的內(nèi)部定義方法,默認(rèn)內(nèi)部深藍(lán)色填充,邊框?yàn)闇\藍(lán)色def draw(self, img, colorIn, colorBd):x1, y1 = self.pos # 矩形框的左上角坐標(biāo)w, h = self.size # 矩形框的寬高# img畫板,矩形框左上角坐標(biāo),矩形框右下角坐標(biāo),顏色,-1代表顏色填充cv2.rectangle(img, (x1, y1), (x1+w, y1+h), colorIn, -1)# 美化一下矩形框cv2.rectangle(img, (x1, y1), (x1+w, y1+h), colorBd, 4)# 在矩形框上顯示字符串信息cv2.putText(img, self.text, (x1+25, y1+65), cv2.FONT_HERSHEY_COMPLEX, 1.8, (255,255,255), 3)# 創(chuàng)建一個(gè)列表存放鍵盤上每個(gè)按鍵的文本信息
keys = [['Q','W','E','R','T','Y','U','I','O','P'],['A','S','D','F','G','H','J','K','L',';'],['Z','X','C','V','B','N','M',',','.','/']]# 保存最終的輸出結(jié)果
finalText = ''# 存放每一個(gè)按鍵的信息
buttonList = []# 矩形按鍵的顏色
colorIn = (255,0,0) # 按鍵內(nèi)部填充的顏色
colorBd = (255,255,0) # 按鍵的邊框顏色 # 通過(guò)循環(huán)來(lái)實(shí)例化所有按鍵
for i in range(3): # 鍵盤文本列表有三行# 分別實(shí)例化每一行的按鈕信息 for x, key in enumerate(keys[i]): #返回每個(gè)元素的索引和值# 確定每個(gè)按鍵的左上角坐標(biāo)位置px = 115*x + 30 + 40*i #水平方向每?jī)蓚€(gè)按鍵之間間隔115,每次換行縮進(jìn)40,初始位置x=30py = 115*i + 50 # 豎直方向每?jī)蓚€(gè)按鍵指尖間隔115,初始位置y=50# 將實(shí)例化后的對(duì)象存放在列表中buttonList.append(Button([px, py], key))# 每次換行后px坐標(biāo)重置x = 0#(4)處理每一幀圖像
while True:# 返回是否讀取成功,和讀取的幀圖像success, img = cap.read()# 翻轉(zhuǎn)圖像,讓自己和攝像頭呈鏡像關(guān)系img = cv2.flip(img, 1) # 1代表水平翻轉(zhuǎn),0代表上下翻轉(zhuǎn)#(5)繪制鍵盤for i in range(3*len(keys[0])): # 一共有3行10列個(gè)按鍵# 調(diào)用類中的繪圖方法,顯示每個(gè)鍵盤按鍵buttonList[i].draw(img, colorIn, colorBd)#(6)檢測(cè)手部關(guān)鍵點(diǎn)# 檢測(cè)手部關(guān)鍵點(diǎn)信息,返回手部信息hands,繪制關(guān)鍵點(diǎn)后的圖像imghands, img = detector.findHands(img, flipType=False)# 如果檢測(cè)到手了,才執(zhí)行下一步if hands:# 獲取21個(gè)手部關(guān)鍵點(diǎn)信息lmList = hands[0]['lmList']# 獲取食指指尖關(guān)鍵點(diǎn)坐標(biāo)x1, y1 = lmList[8]# 獲取中指指尖關(guān)鍵點(diǎn)坐標(biāo)x2, y2 = lmList[12]#(7)遍歷所有的按鍵,檢查食指指尖在哪個(gè)按鍵的范圍內(nèi)for index, button in enumerate(buttonList): # botton存放的是類實(shí)例化后的對(duì)象# 所在矩形的左上坐標(biāo)和寬高x0, y0 = button.posw, h = button.size# 如果食指指尖在某個(gè)矩形框中,改變鍵盤按鍵顏色if x0<=x1<=x0+w and y0<=y1<=y0+h:# 按鍵內(nèi)部填充顏色cv2.rectangle(img, (x0, y0), (x0+w, y0+h), (0,255,0), -1)# 按鍵邊框顏色cv2.rectangle(img, (x0, y0), (x0+w, y0+h), (0,0,255), 4)# 按鍵上的字符串cv2.putText(img, button.text, (x0+25, y0+65), cv2.FONT_HERSHEY_COMPLEX, 1.8, (255,255,255), 3)#(8)計(jì)算食指和中指指尖之間的距離distance, _, img = detector.findDistance((x1,y1), (x2,y2), img)# 如果指尖距離小于50,認(rèn)為是點(diǎn)擊按鍵if distance<50:# 點(diǎn)擊按鍵改變按鍵顏色cv2.rectangle(img, (x0, y0), (x0+w, y0+h), (0,0,255), -1)# 按鍵上的字符串cv2.putText(img, button.text, (x0+25, y0+65), cv2.FONT_HERSHEY_COMPLEX, 1.8, (255,255,255), 3)# 點(diǎn)擊鍵盤上某個(gè)按鍵keyboard.press(button.text) # 鍵盤上的某個(gè)符號(hào),'A'# 在文本框中顯示該字符finalText += button.text# 點(diǎn)擊一次后,0.2秒之后才能再點(diǎn)一次sleep(0.2)#(9)創(chuàng)建虛擬文本框# 文本框內(nèi)部cv2.rectangle(img, (100, 450), (700, 550), (255,255,255), -1)# 文本框邊框cv2.rectangle(img, (100, 450), (700, 550), (0,0,0), 5) # 按鍵上的字符串cv2.putText(img, finalText, (110, 525), cv2.FONT_HERSHEY_COMPLEX, 1.8, (0,0,0), 3)#(10)顯示圖像cv2.imshow('video', img)# 每幀圖像滯留時(shí)間,ESC鍵退出if cv2.waitKey(1) & 0xFF==27:break# 釋放視頻資源
cap.release()
cv2.destroyAllWindows()
顯示結(jié)果如圖,當(dāng)食指在某個(gè)按鍵的范圍內(nèi),并且指尖距離大于規(guī)定值,認(rèn)為是搜索按鍵,按鍵變成綠色,邊界框變成紅色;如果指尖距離小于規(guī)定值,認(rèn)為是點(diǎn)擊按鍵,按鍵內(nèi)部和邊框都變成紅色。使用百度搜索框測(cè)試,能夠?qū)崿F(xiàn)同步輸入。
總結(jié)
以上是生活随笔為你收集整理的【机器视觉案例】(9) AI视觉,手势控制电脑键盘,附python完整代码的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【面向对象编程】(1) 类实例化的基本方
- 下一篇: 【面向对象编程】(2) 类属性的定义及使