日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

圣诞纯情手势告白(Mediapipe基本使用手势识别详解)

發(fā)布時間:2024/3/24 编程问答 116 豆豆
生活随笔 收集整理的這篇文章主要介紹了 圣诞纯情手势告白(Mediapipe基本使用手势识别详解) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 前言
  • 環(huán)境安裝
  • 快速上手(手勢捕捉)
    • 獲取手的坐標(biāo)
    • 返回參數(shù)詳解
  • 不同算子
  • 手勢識別案例
    • 手指狀態(tài)判斷
    • 編碼
    • 升級版(圣誕表白器)
  • 總結(jié)

前言

本來不想寫這個的,但是轉(zhuǎn)了一圈國內(nèi)mediapipe 的比較少教程。沒有那么全面,所以這邊還是記錄一下吧。

環(huán)境安裝

如果你是 Anconada 那么你不需要安裝,但如果不是,你只需要輸入以下指令

pip install mediapipe

再次之前你必須掌握 python3
pyharm 使用
opencv 基本使用

快速上手(手勢捕捉)

這邊我們舉一個快爛大街的東西。

import mediapipe as mp import cv2cap = cv2.VideoCapture(0)mpHand = mp.solutions.hands #mp的手部捕捉 Hand = mpHand.Hands() #找到圖片當(dāng)中的手 mphanddraw = mp.solutions.drawing_utils #繪制工具while True:flag,img = cap.read()RGBImage = cv2.cvtColor(img,cv2.COLOR_BGR2RGB) #把圖片進(jìn)行轉(zhuǎn)換result = Hand.process(RGBImage)if(result.multi_hand_landmarks): #如果有手,那么就會得到手的列表記錄了手的坐標(biāo)for handlist in result.multi_hand_landmarks:mphanddraw.draw_landmarks(img,handlist,mpHand.HAND_CONNECTIONS)#繪制手的關(guān)節(jié) HAND_CONNECTIONS 把點(diǎn)連接起來cv2.imshow("Hands",img)if(cv2.waitKey(1)==ord("q")):breakcap.release() cv2.destroyAllWindows()


注釋應(yīng)該說得很清楚了,這里就還不闡述了。

獲取手的坐標(biāo)

從剛才的效果你可以發(fā)現(xiàn),handlist 包含了我們的一只手的完整坐標(biāo),并且可以繪制21個點(diǎn)
那么事實(shí)上 handlist 就是21個點(diǎn)的編號和坐標(biāo)(這個坐標(biāo)是按照百分比來算的),每個點(diǎn)對應(yīng)下面的圖

所以我們可以非常清楚的去捕捉到我們手的狀態(tài)。
接下來我們來對我們的手進(jìn)行重新繪制。

import mediapipe as mp import cv2cap = cv2.VideoCapture(0)mpHand = mp.solutions.hands #mp的手部捕捉 Hand = mpHand.Hands() #找到圖片當(dāng)中的手 mphanddraw = mp.solutions.drawing_utils #繪制工具while True:flag,img = cap.read()RGBImage = cv2.cvtColor(img,cv2.COLOR_BGR2RGB) #把圖片進(jìn)行轉(zhuǎn)換result = Hand.process(RGBImage)if(result.multi_hand_landmarks): #如果有手,那么就會得到手的列表記錄了手的坐標(biāo)for handlist in result.multi_hand_landmarks:for id,lm in enumerate(handlist.landmark):h,w,c = img.shapecx,cy = int(lm.x * w),int(lm.y * h)cv2.circle(img,(cx,cy),15,(255,0,255),cv2.FILLED)mphanddraw.draw_landmarks(img,handlist,mpHand.HAND_CONNECTIONS,)#繪制手的關(guān)節(jié) HAND_CONNECTIONS 把點(diǎn)連接起來cv2.imshow("Hands",img)if(cv2.waitKey(1)==ord("q")):breakcap.release() cv2.destroyAllWindows()

之后的話我們可以對代碼進(jìn)行優(yōu)化,我們知道我們可以直接獲取一個手掌的每一個關(guān)節(jié)的坐標(biāo),在我們的圖片上,這樣一來我們就可以對我們手的姿態(tài)進(jìn)行預(yù)測,判斷。這樣一來就好玩了。
例如這樣:

import mediapipe as mp import cv2 import mathcap = cv2.VideoCapture(0) cap.set(3,1280) cap.set(4,720)mpHand = mp.solutions.hands #mp的手部捕捉 Hand = mpHand.Hands() #找到圖片當(dāng)中的手 mphanddraw = mp.solutions.drawing_utils #繪制工具while True:flag,img = cap.read()RGBImage = cv2.cvtColor(img,cv2.COLOR_BGR2RGB) #把圖片進(jìn)行轉(zhuǎn)換result = Hand.process(RGBImage)if(result.multi_hand_landmarks): #如果有手,那么就會得到手的列表記錄了手的坐標(biāo)hands_data = result.multi_hand_landmarksfor handlist in hands_data:h, w, c = img.shapeshizhi_postion = (int(handlist.landmark[8].x*w),int(handlist.landmark[8].y*h))muzhi_postion = (int(handlist.landmark[4].x * w), int(handlist.landmark[4].y * h))cv2.line(img, muzhi_postion, shizhi_postion, (255, 0, 0), 5)location = int(shizhi_postion[0]-muzhi_postion[0])**2\+ int(shizhi_postion[1]-muzhi_postion[1])**2location = int(math.sqrt(location))showpostion = (int(((muzhi_postion[0]+shizhi_postion[0])/2)) ,int(((muzhi_postion[1]+shizhi_postion[1])/2)))cv2.putText(img, str(location), showpostion, cv2.FONT_HERSHEY_PLAIN, 1, (255, 0, 255), 1)for id,lm in enumerate(handlist.landmark):cx,cy = int(lm.x * w),int(lm.y * h)# 我們標(biāo)注出大拇指和食指的距離cv2.circle(img,(cx,cy),15,(255,0,255),cv2.FILLED)cv2.putText(img,str(id),(cx,cy),cv2.FONT_HERSHEY_PLAIN,1,(0,255,255),1)mphanddraw.draw_landmarks(img,handlist,mpHand.HAND_CONNECTIONS,)#繪制手的關(guān)節(jié) HAND_CONNECTIONS 把點(diǎn)連接起來cv2.imshow("Hands",img)if(cv2.waitKey(1)==ord("q")):breakcap.release() cv2.destroyAllWindows()

所以就好玩了。

返回參數(shù)詳解

這個返回參數(shù)很重要,看前面的例子是吧。
首先 hands_data 是多只手的總體坐標(biāo),幾只手在屏幕上,那么 len()就是幾

handlist 是包含了一只手的21個點(diǎn)

handlist 包含了 [{點(diǎn)1},{點(diǎn)2}…]
所以么獲取 拇指頭就是 handlist.landmark[4].x * w
所以就ok了。

不同算子

這個其實(shí)我也不太好說那玩意叫啥,這里的話我先叫他算子。
那么這個有啥用呢,其實(shí)就是使用不同的算法模型,來幫助我們提取不同的特征,以便處理。

這里可以看到這里有很多不同的算子。
調(diào)用方式都是類似的,但是處理的方式可能有些許不同。
當(dāng)然我們這里還是先探討關(guān)于 hands這個東西改怎么玩。后面我們再來說說其他的玩意,到本系列最后說不定可以做一個手勢系統(tǒng),用我們身體的姿態(tài)來控制電腦,例如我們可以使用我們的手來充當(dāng)我們的鼠標(biāo)(右手)等等,那玩意應(yīng)該會比較酷!或者我們結(jié)合VR游戲驅(qū)動,我們將不需要游戲手柄,只需要一個像素良好的攝像頭,并且由于 mediapipe 是直接在CPU當(dāng)中運(yùn)行的,這就意味著我們可以在沒有顯卡 GPU 的設(shè)備運(yùn)行,Google官方也說過這玩意可以用到移動端,linux等。

ok 繼續(xù),關(guān)于前面的代碼,我們其實(shí)已經(jīng)可以來做一個簡單的音量控制器了,我們只需要對手指間距進(jìn)行換算即可。不夠這個任然不是我們的主題,我們今天的主題其實(shí)是如何識別出我們的手勢,例如識別
1 ~ 5。

手勢識別案例

OK ,那么接下來開始我們的案例,這個案例其實(shí)就是
Opencv 快速使用(基礎(chǔ)使用&手勢識別)


部分,當(dāng)時這個部分是直接copy的,結(jié)果發(fā)現(xiàn)這哥們的其實(shí)是抄我發(fā)的那個視頻的代碼(吐槽一波寫的真爛,有很嚴(yán)重的 OOM 問題。所以我打算自己寫一個算了,反正這個挺好玩的)

手指狀態(tài)判斷

首先我們不難發(fā)現(xiàn)其實(shí),其實(shí)對比官方給出的手指圖片以及我前面的那個手指的圖片。我們只需要對比關(guān)節(jié)的坐標(biāo)就可以判斷手有沒有立起來。


相當(dāng)直觀是吧。
但是這里其實(shí)還有個問題,那就是大拇指的問題。
由于大拇指太 短了 所以沒辦法這樣直接判斷,所以我們需要去使用x 的坐標(biāo)來判斷我們的手。但是這樣一來又出現(xiàn)問題了,那就是我們左右手的構(gòu)造有點(diǎn)不一樣。

所以我們有時候得去判斷一下我們那個手是左手還是右手

判斷左右手的方式相當(dāng)簡單,看 1 5 號 X 的相對位置就好了。但是還有個問題那就是手心手背的問題但是其實(shí)手心手背的投影和那個左右手的投影是一樣的。

編碼

import mediapipe as mp import cv2 import mathcap = cv2.VideoCapture(0)mpHand = mp.solutions.hands #mp的手部捕捉 Hand = mpHand.Hands() #找到圖片當(dāng)中的手 mphanddraw = mp.solutions.drawing_utils #繪制工具TipsId = [4,8,12,16,20] #定點(diǎn)的坐標(biāo) while True:flag,img = cap.read()RGBImage = cv2.cvtColor(img,cv2.COLOR_BGR2RGB) #把圖片進(jìn)行轉(zhuǎn)換result = Hand.process(RGBImage)if(result.multi_hand_landmarks): #如果有手,那么就會得到手的列表記錄了手的坐標(biāo)hands_data = result.multi_hand_landmarksfor handlist in hands_data:h, w, c = img.shapefingers = []#判斷大拇指的開關(guān)if(handlist.landmark[TipsId[0]-3].x < handlist.landmark[TipsId[0]+1].x):if handlist.landmark[TipsId[0]].x > handlist.landmark[TipsId[0]-1].x:fingers.append(0)else:fingers.append(1)else:if handlist.landmark[TipsId[0]].x < handlist.landmark[TipsId[0] - 1].x:fingers.append(0)else:fingers.append(1)# 判斷其他手指for id in range(1,5):if(handlist.landmark[TipsId[id]].y > handlist.landmark[TipsId[id]-2].y):fingers.append(0)else:fingers.append(1)# 獲得手指個數(shù)totoalfingle = fingers.count(1)cv2.putText(img,str(totoalfingle),(50,50),cv2.FONT_HERSHEY_PLAIN,5,(255,255,255),5)# 這個只是繪制手指關(guān)節(jié)的,可以忽略這段代碼for id,lm in enumerate(handlist.landmark):cx,cy = int(lm.x * w),int(lm.y * h)cv2.circle(img,(cx,cy),15,(255,0,255),cv2.FILLED)cv2.putText(img,str(id),(cx,cy),cv2.FONT_HERSHEY_PLAIN,1,(0,255,255),1)mphanddraw.draw_landmarks(img,handlist,mpHand.HAND_CONNECTIONS,)cv2.imshow("Hands",img)if(cv2.waitKey(1)==ord("q")):breakcap.release() cv2.destroyAllWindows()

效果

升級版(圣誕表白器)

接下來到此我們應(yīng)該就已經(jīng)結(jié)束了,但是突然想起來那啥,我們其實(shí)不僅可以顯示文字在我們的文字,還可以疊加圖片,
SO MAYBE IT CAN WORK SOME INTERESTING THINGS SUCH AS
CONFESS TO SOMEBODY WHICH I CAN NOT USE IT RIGHT NOW!

FUCK,叫我狗糧制造機(jī),謝謝!
效果

代碼

import mediapipe as mp import cv2 import oscap = cv2.VideoCapture(0) cap.set(3,1280) cap.set(4,720) mpHand = mp.solutions.hands #mp的手部捕捉 Hand = mpHand.Hands() #找到圖片當(dāng)中的手 mphanddraw = mp.solutions.drawing_utils #繪制工具MediaPath = "Media" picsdir = os.listdir(MediaPath) pics = [] for pic in picsdir:img = cv2.imread(f"{MediaPath}/{pic}")pics.append(img)TipsId = [4,8,12,16,20] #定點(diǎn)的坐標(biāo) while True:flag,img = cap.read()RGBImage = cv2.cvtColor(img,cv2.COLOR_BGR2RGB) #把圖片進(jìn)行轉(zhuǎn)換result = Hand.process(RGBImage)if(result.multi_hand_landmarks): #如果有手,那么就會得到手的列表記錄了手的坐標(biāo)hands_data = result.multi_hand_landmarksfor handlist in hands_data:h, w, c = img.shapefingers = []#判斷大拇指的開關(guān)if(handlist.landmark[TipsId[0]-2].x < handlist.landmark[TipsId[0]+1].x):if handlist.landmark[TipsId[0]].x > handlist.landmark[TipsId[0]-1].x:fingers.append(0)else:fingers.append(1)else:if handlist.landmark[TipsId[0]].x < handlist.landmark[TipsId[0] - 1].x:fingers.append(0)else:fingers.append(1)# 判斷其他手指for id in range(1,5):if(handlist.landmark[TipsId[id]].y > handlist.landmark[TipsId[id]-2].y):fingers.append(0)else:fingers.append(1)# 獲得手指個數(shù),繪制圖片totoalfingle = fingers.count(1)coverpic = pics[totoalfingle-1]hc, wc, cc = coverpic.shapeimg[0:wc,0:hc] = coverpic# 這個只是繪制手指關(guān)節(jié)的,可以忽略這段代碼for id,lm in enumerate(handlist.landmark):cx,cy = int(lm.x * w),int(lm.y * h)cv2.circle(img,(cx,cy),15,(255,0,255),cv2.FILLED)mphanddraw.draw_landmarks(img,handlist,mpHand.HAND_CONNECTIONS,)cv2.imshow("Hands",img)if(cv2.waitKey(1)==ord("q")):breakcap.release() cv2.destroyAllWindows()

圖片自己準(zhǔn)備去(如果有人表白成功了記得踹我)

總結(jié)

最基本的使用其實(shí)就是這樣的,后面你想怎么架構(gòu),就怎么架構(gòu),這個無所謂,按照這個模板來套就可以了。

總結(jié)

以上是生活随笔為你收集整理的圣诞纯情手势告白(Mediapipe基本使用手势识别详解)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 日本激情小视频 | 国产视频日韩 | 一级精品视频 | 亚洲视频国产视频 | 欧美三级免费看 | 无码人妻aⅴ一区二区三区有奶水 | 中文字幕一区二区久久人妻 | 樱空桃在线 | 奇米色影视 | julia在线播放88mav | av免费播放网站 | 二区欧美 | 欧美性xxxxx| 69亚洲精品久久久蜜桃小说 | 久久精品国产99 | 成人xx视频| 老女人做爰全过程免费的视频 | 日本一区二区三区电影在线观看 | 久久久久免费视频 | 日韩一区二区三区免费 | 国产熟妇另类久久久久 | 美女狠狠干 | 中文字幕日韩三级片 | 色呦呦国产精品 | 亚洲精品综合网 | 欧美 日韩 国产 成人 在线观看 | 四虎成人永久免费视频 | 男人av资源网 | 婷婷色综合网 | 婷婷色一区二区三区 | 激情小说视频在线 | 日本一区二区在线播放 | 99爱这里只有精品 | 亚洲AV成人无码电影在线观看 | 欧美日韩人妻精品一区 | 一区二区三区美女视频 | 欧美乱妇狂野欧美视频 | 一区二区在线观看免费 | 亚洲国产精彩视频 | 久久五 | 国模在线观看 | 91porny九色 | 自宅警备员在线观看 | 狠狠操夜夜爽 | 国产偷人视频 | 亚洲图片在线观看 | 欧美成人黄色小视频 | 日韩精品国产一区 | 日本护士做爰视频 | 探花视频在线版播放免费观看 | 欧美日韩一区二区不卡 | 国产一级免费在线观看 | 一本色道久久综合无码人妻 | 在线看h网站 | 在线免费观看黄色av | 国产成人麻豆免费观看 | 国产艳情片 | 波多野结衣一区二区三区在线 | 神马午夜我不卡 | 欧美一级片一区二区 | 97精品视频在线观看 | 超碰在线99 | 日韩在线一 | 99久久婷婷国产综合精品青牛牛 | 日韩久久成人 | 狠狠的色| 一级黄色在线 | 国产精品人人妻人人爽 | 久久久久久久久久国产精品 | av影片在线看| 麻豆av在线看| aaa国产视频 | 成人导航网站 | 国产女人水真多18毛片18精品 | 手机av免费看 | 精品亚洲一区二区三区 | 三级性生活视频 | 99人妻少妇精品视频一区 | 亚洲男人第一天堂 | 秘密基地动漫在线观看免费 | 噜噜噜久久久 | 免费簧片在线观看 | 黑人干日本少妇 | 成人中文字幕在线观看 | 18禁免费观看网站 | 日韩毛片在线视频 | 91美女视频| 久久一级电影 | 污网站免费在线观看 | xxx国产在线观看 | 极品尤物在线观看 | 国产一区二区内射 | 丁香婷婷激情 | 日韩乱论 | 国产黄频在线观看 | 中文字幕在线观看视频网站 | 日韩成人福利 | 国内精品在线播放 | 精品欧美日韩 |