Python+OpenCV姿态检测代码报TypeError错误,求解决方案
解决cvzone PoseModule中TypeError: unsupported operand type(s) for -: 'int' and 'list'错误
问题重现
使用OpenCV和cvzone.PoseModule编写姿态关键点位置记录代码,运行时触发类型错误。代码如下:
import cv2 from cvzone.PoseModule import PoseDetector cap=cv2.VideoCapture('Video (1).mp4') detector=PoseDetector() posList = [] while True: # This line starts an infinite loop. The code inside this loop will continue to run until it encounters a break statement or the program is terminated manually. success, img = cap.read() img = detector.findPose(img) lmList,bboxInfo = detector.findPosition(img) if bboxInfo: lmString = '' for lm in lmList: # print(lm) lmString += f'{lm[1]},{img.shape[0]-lm[2]},{lm[3]}' posList.append(lmString) print(posList) # num_points = len(lmList) # print("Number of Points Detected:", num_points) cv2.imshow("Image",img) cv2.waitKey(1)
报错信息:
INFO: Created TensorFlow Lite XNNPACK delegate for CPU. Traceback (most recent call last): File "d:\py_projects\motionDetector\motionCap.py", line 22, in <module> lmString += f'{lm[1]},{img.shape[0]-lm[2]},{lm[3]}' TypeError: unsupported operand type(s) for -: 'int' and 'list'
错误原因
报错显示整数类型的img.shape[0]无法与列表类型的lm[2]执行减法运算,说明lmList中每个关键点元素的结构不符合预期——你假设lm[2]是y坐标的整数值,但实际它是一个列表。这种情况通常由cvzone版本差异或findPosition方法返回的数据结构与预期不一致导致。
解决方案
步骤1:确认关键点数据结构
先在循环中打印单个关键点的内容,明确其具体结构:
if bboxInfo: lmString = '' for lm in lmList: print(lm) # 打印单个关键点结构,确认坐标位置 lmString += f'{lm[1]},{img.shape[0]-lm[2]},{lm[3]}' posList.append(lmString)
步骤2:调整坐标提取方式
根据打印结果修改代码:
- 如果打印结果为
[0, 150, 300, 0](结构为[id, x, y, z]),则说明是版本问题,执行以下命令更新依赖:pip install --upgrade cvzone opencv-python - 如果打印结果为
[0, 150, [300], 0](y坐标嵌套在列表中),则修改减法部分为:lmString += f'{lm[1]},{img.shape[0]-lm[2][0]},{lm[3]}'
步骤3:修复视频循环终止逻辑
原代码未处理视频播放结束的情况,需添加退出判断:
while True: success, img = cap.read() if not success: # 视频读取失败或播放完毕时退出循环 break # 后续代码...
修正后的完整代码
import cv2 from cvzone.PoseModule import PoseDetector cap=cv2.VideoCapture('Video (1).mp4') detector=PoseDetector() posList = [] while True: success, img = cap.read() if not success: break img = detector.findPose(img) lmList,bboxInfo = detector.findPosition(img) if bboxInfo: lmString = '' for lm in lmList: # 根据实际结构调整索引,此处假设结构为[id, x, y, z] # 如果y坐标是嵌套列表,改为lm[2][0] lmString += f'{lm[1]},{img.shape[0]-lm[2]},{lm[3]},' posList.append(lmString.rstrip(',')) # 移除末尾多余的逗号 cv2.imshow("Image",img) if cv2.waitKey(1) & 0xFF == ord('q'): # 按q键可手动退出 break cap.release() cv2.destroyAllWindows()
内容的提问来源于stack exchange,提问作者Dipanwita Biswas
相关产品推荐
相关产品推荐

