这段代码使用OpenCV和MediaPipe库从摄像头捕获实时视频流,并对手部进行跟踪和关键点检测。它首先将摄像头捕获的图像从BGR转换为RGB格式,并传递给MediaPipe的手部跟踪模型。模型处理图像后返回手部的关键点信息,这些信息随后被用来在图像上绘制手部关键点和连接线。绘制后的图像被转换回BGR格式,并通过OpenCV的窗口显示出来。用户可以实时查看手部跟踪的结果,并且当按下ESC键时,程序将退出
导入库
import opencv as cv
import mediapipe as mp
从mediapipe的solutions模块中导入绘图工具和手部跟踪模块
mp_drawing = mp.solutions.drawing_utils
mp_hands = mp.solutions.hands
初始化手部跟踪模型
hands = mp_hands.Hands(
static_image_mode=False, # 设置模型处理动态视频流,而不是静态图像
max_num_hands=4, # 设置最多检测的手部数量
min_detection_confidence=0.5, # 设置手部检测的最低置信度阈值
min_tracking_confidence=0.5) # 设置手部跟踪的最低置信度阈值
打开摄像头,无限循环并处理视频每一帧
cap = cv.VideoCapture(0)
while True:
ret, frame = cap.read()
frame = cv.flip(frame, 1)
results = hands.process(frame)
frame = cv.cvtColor(frame, cv2.COLOR_RGB2BGR)
如果检测到手部:
- 遍历检测到的每只手及其左右手分类。
- 打印手部的标签(左手或右手)。
- 在图像上绘制手部标签。
- 使用
mp_drawing.draw_landmarks
绘制手部的关键点。 -
if results.multi_hand_landmarks: # 检查是否检测到了手部的关键点 for hand_landmarks, handedness in zip(results.multi_hand_landmarks, results.multi_handedness): # 遍历检测到的所有手部的关键点 # 获取并打印手部标签(左右手) hand_label = handedness.classification[0].label print(f'Hand: {hand_label}') # 在画面上方显示手部标签 cv.putText(frame, f'{hand_label}', (int(hand_landmarks.landmark[0].x * frame.shape[1]), int(hand_landmarks.landmark[0].y * frame.shape[0]) - 20), cv.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2, cv.LINE_AA) # 使用MediaPipe的绘图工具在图像上绘制手部关键点 mp_drawing.draw_landmarks( frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)
最后显示并退出
cv.imshow('Hands', frame) if cv.waitKey(1) & 0xFF == 27: break cap.release() cv.destroyAllWindows()
显示结果,我上面设置了最多能同时显示四只手
-
完整代码
-
import cv2 as cv import mediapipe as mp mp_drawing = mp.solutions.drawing_utils mp_hands = mp.solutions.hands # 调整参数 hands = mp_hands.Hands( static_image_mode=False, max_num_hands=4, min_detection_confidence=0.5, # 降低检测置信度以便更容易检测 min_tracking_confidence=0.5) # 同样降低跟踪置信度 cap = cv.VideoCapture(0) while True: ret, frame = cap.read() frame = cv.cvtColor(frame, cv.COLOR_BGR2RGB) frame = cv.flip(frame, 1) results = hands.process(frame) frame = cv.cvtColor(frame, cv.COLOR_RGB2BGR) if results.multi_hand_landmarks: for hand_landmarks, handedness in zip(results.multi_hand_landmarks, results.multi_handedness): # 获取并打印手部标签(左右手) hand_label = handedness.classification[0].label print(f'Hand: {hand_label}') # 在画面上方显示手部标签 cv.putText(frame, f'{hand_label}', (int(hand_landmarks.landmark[0].x * frame.shape[1]), int(hand_landmarks.landmark[0].y * frame.shape[0]) - 20), cv.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2, cv.LINE_AA) mp_drawing.draw_landmarks( frame, hand_landmarks, mp_hands.HAND_CONNECTIONS) cv.imshow('Hands', frame) if cv.waitKey(1) & 0xFF == 27: break cap.release() cv.destroyAllWindows()
喜欢我的文章,麻烦点个小小关注!!!