【計算機視覺】手勢識別

手勢識別是計算機視覺領域中的重要方向,通過對攝像機采集的手部相關的圖像序列進行分析處理,進而識別其中的手勢,手勢被識別后用戶就可以通過手勢來控制設備或者與設備交互。完整的手勢識別一般有手的檢測和姿態估計、手部跟蹤和手勢識別等。

一、手掌檢測

import cv2
import mediapipe as mp# 初始化 MediaPipe 手部模型
mp_hands = mp.solutions.hands
hands = mp_hands.Hands()# 初始化視頻流
cap = cv2.VideoCapture(0)while True:ret, frame = cap.read()if not ret:break# 轉換為 RGBrgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)# 獲取手部關鍵點results = hands.process(rgb_frame)# 如果檢測到手部if results.multi_hand_landmarks:for landmarks in results.multi_hand_landmarks:# 繪制手部關鍵點mp.solutions.drawing_utils.draw_landmarks(frame, landmarks, mp_hands.HAND_CONNECTIONS)# 顯示圖像cv2.imshow('Hand Detection', frame)# 按 'q' 鍵退出if cv2.waitKey(1) & 0xFF == ord('q'):break# 釋放資源
cap.release()
cv2.destroyAllWindows()

這段代碼是一個簡單的手部檢測應用程序,使用了 OpenCV 和 MediaPipe 庫來實時檢測和繪制手部關鍵點。下面是對代碼的詳細解釋:

1. 導入必要的庫
import cv2
import mediapipe as mp
  • cv2 是 OpenCV 的 Python 接口庫,用于圖像處理和計算機視覺任務。
  • mediapipe 是 Google 提供的一個跨平臺框架,用于實現高效的計算機視覺任務,這里用它來做手部關鍵點檢測。
2. 初始化 MediaPipe 手部模型
mp_hands = mp.solutions.hands
hands = mp_hands.Hands()
  • mp_hands 是 MediaPipe 提供的手部檢測模塊。通過 mp.solutions.hands 訪問。
  • hands = mp_hands.Hands() 創建了一個 Hands 對象,用于進行手部檢測。它會自動處理圖像中的手部檢測、手部關鍵點識別和跟蹤。
3. 初始化視頻流
cap = cv2.VideoCapture(0)
  • cv2.VideoCapture(0) 打開了計算機的默認攝像頭(0表示第一個攝像頭)。返回的 cap 對象用于讀取視頻流。
4. 開始處理視頻流
while True:ret, frame = cap.read()if not ret:break
  • cap.read() 從攝像頭讀取一幀圖像并返回兩個值:retframeret 是布爾值,表示圖像是否成功讀取,frame 是當前幀的圖像。
  • 如果 retFalse,則說明讀取圖像失敗,程序退出循環。
5. 轉換圖像為 RGB
rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
  • OpenCV 使用 BGR(藍綠紅)色彩空間,而 MediaPipe 要求輸入圖像為 RGB(紅綠藍)色彩空間。因此,我們用 cv2.cvtColor 將圖像從 BGR 轉換為 RGB。
6. 處理圖像以檢測手部關鍵點
results = hands.process(rgb_frame)
  • hands.process(rgb_frame) 將 RGB 圖像傳遞給 MediaPipe 的 Hands 模型進行處理。
  • results 包含了檢測到的手部信息,包括手部關鍵點的位置。如果圖像中沒有手部,results.multi_hand_landmarks 會是空的。
7. 繪制手部關鍵點
if results.multi_hand_landmarks:for landmarks in results.multi_hand_landmarks:mp.solutions.drawing_utils.draw_landmarks(frame, landmarks, mp_hands.HAND_CONNECTIONS)
  • results.multi_hand_landmarks 是一個包含所有檢測到的手的關鍵點位置的列表。如果檢測到手部,它會返回一個非空列表。
  • landmarks 是每個手部的關鍵點集合,每個關鍵點是一個 (x, y, z) 坐標。
  • mp.solutions.drawing_utils.draw_landmarks(frame, landmarks, mp_hands.HAND_CONNECTIONS) 將每個手的關鍵點繪制到 frame 圖像上,并且連接關鍵點,形成手的骨架結構。mp_hands.HAND_CONNECTIONS 用于連接不同的關鍵點。
8. 顯示處理后的圖像
cv2.imshow('Hand Detection', frame)
  • cv2.imshow 顯示處理后的圖像(frame)。窗口的標題是 ‘Hand Detection’。
9. 按鍵退出
if cv2.waitKey(1) & 0xFF == ord('q'):break
  • cv2.waitKey(1) 等待鍵盤輸入,1 表示等待 1 毫秒。返回值是按下鍵的 ASCII 碼。
  • 如果按下 q 鍵,ord('q') 的值與 cv2.waitKey(1) 返回值相等,程序就會退出循環,停止視頻流。
10. 釋放資源并關閉窗口
cap.release()
cv2.destroyAllWindows()
  • cap.release() 釋放攝像頭資源。
  • cv2.destroyAllWindows() 關閉所有 OpenCV 顯示的窗口。

二、手關鍵點估計

要進行手關鍵點估計,可以使用 MediaPipe 庫來進行高效的手部檢測,結合 OpenCV 來進行圖像處理和顯示。這里將展示一個基于 MediaPipe 手部模型的手關鍵點估計的完整代碼。

MediaPipe 提供了一個預訓練的模型來檢測手部的 21 個關鍵點,包括手指關節和手掌部位。我們將使用 MediaPipe 提供的 Hands 模塊來檢測手部關鍵點。

import cv2
import mediapipe as mp# 初始化 MediaPipe 手部檢測模型
mp_hands = mp.solutions.hands
hands = mp_hands.Hands(min_detection_confidence=0.7, min_tracking_confidence=0.5)
mp_drawing = mp.solutions.drawing_utils# 打開攝像頭
cap = cv2.VideoCapture(0)while True:# 讀取每一幀圖像ret, frame = cap.read()if not ret:print("無法獲取視頻幀")break# 將圖像轉換為 RGB 格式,MediaPipe 需要 RGB 輸入rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)# 獲取手部關鍵點檢測結果results = hands.process(rgb_frame)# 如果檢測到手部if results.multi_hand_landmarks:for landmarks in results.multi_hand_landmarks:# 繪制手部關鍵點和連接線mp_drawing.draw_landmarks(frame, landmarks, mp_hands.HAND_CONNECTIONS)# 獲取并顯示每個關鍵點的坐標for idx, landmark in enumerate(landmarks.landmark):h, w, c = frame.shapecx, cy = int(landmark.x * w), int(landmark.y * h)cv2.putText(frame, str(idx), (cx, cy), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1, cv2.LINE_AA)cv2.circle(frame, (cx, cy), 5, (0, 0, 255), -1)  # 繪制紅色的關鍵點# 顯示圖像cv2.imshow('Hand Keypoint Estimation', frame)# 按 'q' 鍵退出if cv2.waitKey(1) & 0xFF == ord('q'):break# 釋放攝像頭資源并關閉窗口
cap.release()
cv2.destroyAllWindows()
1.代碼解釋
  1. 初始化 MediaPipe 手部模型

    • 使用 mp.solutions.hands.Hands() 創建手部檢測模型,min_detection_confidence=0.7min_tracking_confidence=0.5 表示最低的檢測和追蹤置信度閾值,適用于動態環境中。
  2. 打開攝像頭

    • 使用 cv2.VideoCapture(0) 打開計算機的默認攝像頭,并獲取實時視頻流。
  3. 圖像轉換

    • OpenCV 默認使用 BGR 色彩空間,但 MediaPipe 需要 RGB 色彩空間,因此使用 cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) 將圖像轉換為 RGB 格式。
  4. 處理圖像并獲取手部關鍵點

    • hands.process(rgb_frame) 用于處理圖像并檢測手部關鍵點。results 對象包含手部信息,如果檢測到手部,results.multi_hand_landmarks 將返回手部的 21 個關鍵點的位置。
  5. 繪制關鍵點和連接線

    • mp_drawing.draw_landmarks(frame, landmarks, mp_hands.HAND_CONNECTIONS) 繪制手的 21 個關鍵點以及它們之間的連接線(即手指的骨架)。
    • landmarks.landmark 包含了每個關鍵點的 (x, y, z) 坐標,其中 xy 是圖像中的像素坐標,z 是深度信息(在 3D 空間中的位置,但對于 2D 圖像可忽略)。
  6. 顯示關鍵點坐標

    • 對于每個關鍵點,通過 cv2.putText 在圖像上顯示關鍵點的索引。cv2.circle 用來在圖像上繪制關鍵點位置。
  7. 顯示視頻流

    • 使用 cv2.imshow() 來顯示處理過的每一幀圖像,展示檢測到的手部關鍵點。
  8. 退出條件

    • 按下 q 鍵退出程序并釋放攝像頭資源。
2.手部關鍵點索引

MediaPipe 的 Hands 模型檢測手部的 21 個關鍵點,索引如下(從 0 到 20):

  • 0: 手腕
  • 1: 大拇指根部
  • 2: 大拇指第一關節
  • 3: 大拇指第二關節
  • 4: 大拇指尖端
  • 5: 食指根部
  • 6: 食指第一關節
  • 7: 食指第二關節
  • 8: 食指尖端
  • 9: 中指根部
  • 10: 中指第一關節
  • 11: 中指第二關節
  • 12: 中指尖端
  • 13: 無名指根部
  • 14: 無名指第一關節
  • 15: 無名指第二關節
  • 16: 無名指尖端
  • 17: 小指根部
  • 18: 小指第一關節
  • 19: 小指第二關節
  • 20: 小指尖端

三、實例

YOLO(You Only Look Once)是一個非常強大的目標檢測算法,特別適用于實時應用。它將目標檢測任務轉化為一個回歸問題,能夠快速且準確地檢測圖像中的目標物體。雖然 YOLO 本身并沒有直接針對手部關鍵點估計的功能,但可以用它來檢測手部區域,然后結合其他模型(比如 MediaPipe 或深度學習的關鍵點檢測模型)來進行手關鍵點估計。

  1. YOLO 檢測手部:首先用 YOLO 模型檢測圖像中的手部位置,YOLO 會輸出手部的邊界框。
  2. 手部關鍵點估計:然后,我們可以通過一個手部關鍵點估計模型(如 MediaPipe 或自定義深度學習模型)來進一步估計手部的 21 個關鍵點。
import cv2
import torch
import mediapipe as mp# 初始化 MediaPipe 手部檢測模型
mp_hands = mp.solutions.hands
hands = mp_hands.Hands(min_detection_confidence=0.7, min_tracking_confidence=0.5)
mp_drawing = mp.solutions.drawing_utils# 加載 YOLOv5 模型(選擇合適的模型大小)
model = torch.hub.load('ultralytics/yolov5', 'yolov5s')  # 'yolov5s' 是一個小型的 YOLOv5 模型# 打開攝像頭
cap = cv2.VideoCapture(0)while True:# 讀取每一幀圖像ret, frame = cap.read()if not ret:print("無法獲取視頻幀")break# 使用 YOLOv5 檢測圖像中的物體(包括手部)results = model(frame)  # 檢測結果,包括邊界框、標簽、置信度等# 提取 YOLOv5 檢測到的手部(通常手部被標記為 0 或其他標簽,依賴于訓練數據)# 獲取所有檢測到的物體的邊界框hands_detections = results.xyxy[0]  # 獲取檢測結果,xyxy 形式 [x_min, y_min, x_max, y_max, confidence, class]for detection in hands_detections:if detection[5] == 0:  # 類別 0 代表手部(具體根據訓練數據集而定)x_min, y_min, x_max, y_max = map(int, detection[:4])# 在圖像上繪制手部邊界框cv2.rectangle(frame, (x_min, y_min), (x_max, y_max), (255, 0, 0), 2)# 提取手部區域并進行手部關鍵點估計hand_region = frame[y_min:y_max, x_min:x_max]rgb_hand_region = cv2.cvtColor(hand_region, cv2.COLOR_BGR2RGB)# 使用 MediaPipe 估計手部關鍵點hand_results = hands.process(rgb_hand_region)# 如果檢測到手部關鍵點if hand_results.multi_hand_landmarks:for landmarks in hand_results.multi_hand_landmarks:# 繪制手部關鍵點和連接線mp_drawing.draw_landmarks(frame, landmarks, mp_hands.HAND_CONNECTIONS)for idx, landmark in enumerate(landmarks.landmark):h, w, c = frame.shapecx, cy = int(landmark.x * w), int(landmark.y * h)cv2.putText(frame, str(idx), (cx, cy), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1, cv2.LINE_AA)cv2.circle(frame, (cx, cy), 5, (0, 0, 255), -1)  # 繪制紅色的關鍵點# 顯示圖像cv2.imshow('Hand Detection and Keypoint Estimation', frame)# 按 'q' 鍵退出if cv2.waitKey(1) & 0xFF == ord('q'):break# 釋放攝像頭資源并關閉窗口
cap.release()
cv2.destroyAllWindows()
1.代碼解析
  1. 加載 YOLOv5 模型
    • torch.hub.load('ultralytics/yolov5', 'yolov5s') 載入 YOLOv5 模型,yolov5s 是一個小型的 YOLOv5 模型,適合實時應用。可以根據需求選擇 yolov5myolov5l(更大的模型,精度更高但速度較慢)。
  2. 讀取攝像頭視頻流
    • 使用 cv2.VideoCapture(0) 打開攝像頭并讀取每一幀圖像。
  3. YOLOv5 物體檢測
    • 使用 model(frame) 進行圖像檢測,返回一個 results 對象,其中包含檢測到的邊界框、類別標簽、置信度等信息。
  4. 提取手部區域
    • 如果 YOLO 檢測到手部(通過檢測類別標號),提取手部的區域并將其轉化為 RGB 格式(因為 MediaPipe 需要 RGB 輸入)。
  5. MediaPipe 手部關鍵點估計
    • 使用 hands.process(rgb_hand_region) 進行手部關鍵點估計,返回手部的關鍵點信息。
    • 使用 mp_drawing.draw_landmarks() 繪制手部的 21 個關鍵點和連接線。
  6. 結果顯示
    • 將檢測到的手部邊界框、關鍵點及連接線顯示在視頻流上。
  7. 退出條件
    • 按下 q 鍵退出程序。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/72417.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/72417.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/72417.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Leetcode 37: 解數獨

Leetcode 37: 解數獨 是經典的回溯算法問題,考察如何利用遞歸和剪枝高效求解數獨問題。這題主要考察對回溯、遞歸、深度優先搜索 (DFS)、剪枝優化等算法思想的掌握。 題目描述 給定一個部分填充的數獨(9 x 9)網格,用一個有效的算…

VSCode 移除EmmyLua插件的紅色波浪線提示

VSCode 中安裝插件EmmyLua,然后打開lua文件的時候,如果lua代碼引用了C#腳本的變量,經常出現 “undefined global variable: UnityEngineEmmyLua(undefined-global)” 的紅色波浪線提示,這個提示看著比較煩人,我們可以通…

【音視頻】視頻基本概念

一、視頻的基本概念 1.1 視頻碼率(kb/s) 視頻碼率是指視頻文件在單位時間內使用的數據流量,也叫碼流率。碼率越大,說明單位時間內取樣率越大,數據流進度也就越高 1.2 視頻幀率(fps) 視頻幀率…

Grafana服務安裝并啟動

Grafana服務安裝并啟動 1、介紹2、下載Grafana3、解壓縮文件4、啟動Grafana服務5、增加數據源,填寫Prometheus訪問地址6、增加圖表 1、介紹 Grafana是一個開源的可視化系統監控和警報工具包。 2、下載Grafana 介紹:Grafana是一個開源的可視化系統監控和警報工具包…

如何將hf-mirror.com作為vllm默認的下載源? conda如何移除虛擬環境?conda 如何復制一份虛擬環境?

前言 上回咱說道,如果你沒辦法訪問huggingface.co,則可以把modelscope作為vllm默認的下載源。 但如果你非得用你用不了的huggingface.co呢?那你可以考慮將hf-mirror.com作為vllm默認的下載源。這里,hf-mirror.com和huggingface.co的效果是一樣的。 要將hf-mirror.com設為v…

MySQL零基礎教程14—子查詢

子查詢比較簡單,我們還是通過案例引入。 有時候我們查詢的時候,需要用到的不止一個表的數據,比如下面的場景: 查詢名字叫李曉紅同學的班主任姓名 我們提供三個表的基礎信息如下: 從三張表的結構,我們不難…

基于單片機和Wifi技術的智能臺燈設計

摘要 :本文主要介紹了基于單片機AT89C51和Wifi技術的智能臺燈的硬件和軟件設計。該智能臺燈具有根據當前光線自動調節燈光亮度的功能,還可對用戶使用臺燈時處于非正常的距離和姿態時給予報警提示,用戶可以隨時通過手機app查詢智能臺燈的報警記…

最新版AI大模型面試八股文

1、主流的開源大模型體系有哪些,并簡要介紹它們的特點? 這個問題考察面試者對當前大模型生態的了解,包括如 Transformer-based 模型(如 BERT, GPT 系 列)、T5、Switch Transformer 等,以及它們的架構特點和…

在MySQL拿到一條慢SQL語句要如何優化?

在工作的過程中,很多時候會發現執行業務邏輯的時候,某一條SQL語句執行得非常慢。這時候,要如何處理這條語句,如何判斷語句慢的地方在哪里? 一、初級排查 EXPLAIN慢SQL分析 MySQL官網用法: https://dev.mys…

leetcode hot 100 239. 滑動窗口最大值

給你一個整數數組 nums,有一個大小為 k 的滑動窗口從數組的最左側移動到數組的最右側。你只可以看到在滑動窗口內的 k 個數字。滑動窗口每次只向右移動一位。 返回 滑動窗口中的最大值 。 示例 1: 輸入:nums [1,3,-1,-3,5,3,6,7], k 3 輸…

Leetcode 189: 輪轉數組

Leetcode 189: 輪轉數組 這是一道經典問題,題目要求將一個數組向右輪轉 k 個位置,有多種解法可以快速求解,既可以通過額外空間,也可以在 O(1) 的空間復雜度內完成。本題考察數組操作、雙指針,以及算法優化能力。 題目…

優選算法的智慧之光:滑動窗口專題(二)

專欄:算法的魔法世界?????? 個人主頁:手握風云 目錄 一、例題講解 1.1. 最大連續1的個數 III 1.2. 找到字符串中所有字母異位詞 1.3. 串聯所有單詞的子串 1.4. 最小覆蓋子串 一、例題講解 1.1. 最大連續1的個數 III 題目要求是二進制數組&am…

Linux系統安裝Azure CLI完全指南

引言 Azure CLI是管理Azure云服務的重要命令行工具。本文將詳細介紹在Linux系統上安裝Azure CLI的兩種方法,并提供版本管理、故障排除等完整解決方案。 © ivwdcwso (ID: u012172506) 一、安裝前準備 1.1 系統要求 支持的Linux發行版: Ubuntu 20.04/22.04 LTSDebian 10/…

2025嵌入式軟件開發工程師--音頻方向

一、選擇題(每題3分,共30分) 1.以下哪個不是C語言中的關鍵字?( ) A. int B. Float C. Define D. Return 2.以下代碼的輸出是: ( ) inta 5, b 10; printf("%d“, a b); A. 15 B.16 …

TCP/IP四層模型:從入門到精通

第一部分:基礎概念 1.1 什么是TCP/IP? - TCP/IP 是互聯網的基礎通信協議簇,定義了數據如何在網絡中傳輸和路由。 - 與OSI七層模型的對比:TCP/IP更簡化,分為四層,注重實際應用。 1.2 四層模型結構 1. 應…

【Python 數據結構 1.零基礎復習】

目錄 一、輸入與輸出 1.輸入 2.格式化輸出 二、數字與變量 1.字符串 & 整型 2.字符串 & 整型 & 浮點型 3.變量 練習 2235. 兩整數相加 三、運算與操作 1.四則運算 練習 2769. 找出最大的可達成數字 3.取整與取余 練習 2651. 計算列車到站時間 ?編輯 四、真與假 1…

什么是 MGX:MetaGPT

什么是 MGX:MetaGPT MetaGPT是由思碼逸(OpenDILab)團隊開發的一款專注于生成式AI驅動的軟件開發框架,MGX可能是其衍生或升級的相關成果,它創新性地將大語言模型引入軟件開發流程,模擬人類軟件團隊的協作方式,能讓用戶通過自然語言描述需求,即可自動生成完整的軟件項目,…

大模型時代下的數據標注革命:工具、挑戰與未來趨勢

引言 隨著大模型技術的飛速發展,人工智能對高質量標注數據的依賴愈發顯著。傳統的人工標注方式在效率、成本和場景適應性上逐漸顯現瓶頸,而大模型憑借其強大的泛化能力和多模態理解能力,正在推動數據標注從“勞動密集型”向“智能工業化”轉…

【azure openai】用tts實現語音對話【demo】

能實現: 只要替換里面的key,就能跑通。 key的查找方法: 【保姆級教程】如何在azure里快速找到openai的key和demo-CSDN博客 代碼結構: azure_openai_client.py main.py prompts_config.py speech_utils.py stt01.py tts01.…

Spark(5)host配置

(一.)host配置的作用: hosts 文件是一個本地的文本文件,它的作用是將主機名映射到對應的 IP 地址,在 DNS(域名系統)解析之前,系統會先查詢 hosts 文件來確定目標主機的 IP 地址。 (二…