4. 使用Edge TPU在Coral Dev Board上运行姿态估计模型
任务目标
在 Coral Dev Board 上利用 Edge TPU 加速,运行 PoseNet 模型,对摄像头实时画面进行人体姿态关键点检测,并将检测结果(骨架连线与关键点)叠加显示在视频帧上。
环境与依赖
- 硬件:Coral Dev Board(搭载 Edge TPU 协处理器)
- 系统: Mendel Linux(Dev Board 出厂系统)
- Python 包:
pycoral、opencv-python、numpy、Pillow - 模型文件:
posenet_mobilenet_v1_075_353_481_quant_decoder_edgetpu.tflite(含内置解码器,输入尺寸 353×481)
安装依赖:
pip3 install pycoral opencv-python numpy Pillow
模型文件可从 Coral 官方模型库 下载,或使用以下命令获取:
wget https://github.com/google-coral/test_data/raw/master/posenet_mobilenet_v1_075_353_481_quant_decoder_edgetpu.tflite
完整实现代码
以下代码从 USB 摄像头读取帧,缩放至模型输入尺寸后送入 Edge TPU 推理,再将检测到的 17 个关键点坐标映射回原始帧并绘制骨架:
import cv2
import numpy as np
from pycoral.adapters import common
from pycoral.utils.edgetpu import make_interpreter
MODEL = "posenet_mobilenet_v1_075_353_481_quant_decoder_edgetpu.tflite"
INPUT_SIZE = (481, 353) # (宽, 高)
KEYPOINT_NAMES = [
"nose", "left_eye", "right_eye", "left_ear", "right_ear",
"left_shoulder", "right_shoulder", "left_elbow", "right_elbow",
"left_wrist", "right_wrist", "left_hip", "right_hip",
"left_knee", "right_knee", "left_ankle", "right_ankle"
]
SKELETON = [
(0, 1), (0, 2), (1, 3), (2, 4), (5, 6), (5, 7), (7, 9),
(6, 8), (8, 10), (5, 11), (6, 12), (11, 12), (11, 13),
(13, 15), (12, 14), (14, 16)
]
def draw_pose(frame, keypoints, threshold=0.3):
h, w = frame.shape[:2]
coords = []
for kp in keypoints:
y, x, score = kp
if score > threshold:
px, py = int(x * w), int(y * h)
coords.append((px, py))
cv2.circle(frame, (px, py), 4, (0, 255, 0), -1)
else:
coords.append(None)
for a, b in SKELETON:
if coords[a] and coords[b]:
cv2.line(frame, coords[a], coords[b], (255, 0, 0), 2)
return frame
def main():
interpreter = make_interpreter(MODEL)
interpreter.allocate_tensors()
cap = cv2.VideoCapture(0)
if not cap.isOpened():
raise RuntimeError("无法打开摄像头")
while True:
ret, frame = cap.read()
if not ret:
break
# 缩放并填充至模型输入尺寸
resized = cv2.resize(frame, INPUT_SIZE)
rgb = cv2.cvtColor(resized, cv2.COLOR_BGR2RGB)
common.set_input(interpreter, rgb)
interpreter.invoke()
# 输出张量: [1, 17, 3] -> (y, x, score),已归一化
output = interpreter.get_output_tensor(0)
keypoints = output.copy().reshape(17, 3)
draw_pose(frame, keypoints)
cv2.imshow("Edge TPU PoseNet", frame)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
cap.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
main()
运行方式
- 将上述代码保存为
posenet_demo.py,与模型文件放在同一目录。 - 连接 USB 摄像头至 Dev Board。
- 执行:
python3 posenet_demo.py
验证方法与判定标准
- 正常启动:程序无报错,弹出名为 "Edge TPU PoseNet" 的窗口,显示摄像头画面。
- 检测生效:人站在摄像头前,画面中人体关键点位置出现绿色圆点,相邻关键点之间有蓝色连线。
- 实时性:移动身体时,骨架跟随动作变化,无明显卡顿(Edge TPU 推理延迟通常在数十毫秒量级)。
- 退出:按键盘
q键,窗口关闭,程序正常结束。
若画面无检测结果,请确认人体完整出现在画面中且光线充足;若程序报模型加载错误,检查模型文件名是否与代码一致。
关键说明
PoseNet 输出为每个关键点的归一化坐标 (y, x, score),代码中已按此顺序解析并映射回原始帧分辨率。模型输入尺寸为 353(高)×481(宽),代码使用 cv2.resize 直接缩放,未保持宽高比,因此检测坐标映射回原始帧时可能存在轻微偏移,但对姿态可视化影响可忽略。若需精确映射,应使用 letterbox 填充方案。