AttributeError求助:'NormalizedLandmark'对象无'landmark'属性
MediaPipe手部关键点识别AttributeError问题解决
问题描述
使用MediaPipe进行手部关键点识别时触发AttributeError,提示'NormalizedLandmark' object has no attribute 'landmark'。尝试过将对象转换为元组、列表,修改循环代码,均未解决问题。
错误输出
Exception has occurred: AttributeError 'NormalizedLandmark' object has no attribute 'landmark' `for hand_point in hand_landmark.landmark:` AttributeError: 'NormalizedLandmark' object has no attribute 'landmark'
尝试过的错误代码片段
if LastLandmarks: for hand_landmark in LastLandmarks: for hand_point in hand_landmark: print(f"POINT: {hand_point.x:.2f} {hand_point.y:.2f} {hand_point.z:.2f}")
完整代码
import numpy as np from time import time import cv2 import mediapipe as mp from mediapipe.tasks.python import vision from mediapipe.tasks import python LastLandmarks=None BaseOptions=mp.tasks.BaseOptions HandLandmarker= mp.tasks.vision.HandLandmarker HandLandmarkerResult=mp.tasks.vision.HandLandmarkerResult HandLandmarkerOptions=mp.tasks.vision.HandLandmarkerOptions VisionRunningMode=mp.tasks.vision.RunningMode def print_results(result:HandLandmarkerResult,image:mp.Image,timestamp_ms: int): global LastLandmarks if result and result.hand_landmarks: LastLandmarks=result.hand_landmarks[0] print("HAND_LANDMARK_LENGTH: ",len(LastLandmarks)) _options=HandLandmarkerOptions( base_options=BaseOptions(model_asset_path="./hand_landmarker.task"), running_mode=VisionRunningMode.LIVE_STREAM, result_callback=print_results ) cam=cv2.VideoCapture(0) with HandLandmarker.create_from_options(_options) as landmarker: while cam.isOpened(): isFrame,frame=cam.read() if not isFrame:break frame=cv2.flip(frame,1) rgb_frame=cv2.cvtColor(frame,cv2.COLOR_BGR2RGB) h,w,_f=frame.shape mediapipe_image=mp.Image(mp.ImageFormat.SRGB,rgb_frame) timestamp_ms=int(time()*1000) landmarker.detect_async(mediapipe_image,timestamp_ms) if LastLandmarks: #ERROR AREA for hand_landmark in LastLandmarks: for hand_point in hand_landmark.landmark: print(f"POINT: {hand_point.x:.2f} {hand_point.y:.2f} {hand_point.z:.2f}") #ERROR AREA END cv2.putText(frame,"ESC to exit",(15,25),cv2.FONT_HERSHEY_PLAIN,0.9,(0,0,0),1) if cv2.waitKey(5)&0xFF==27:break cv2.imshow("HAND",frame)
问题分析与解决
核心问题
在print_results函数中,LastLandmarks = result.hand_landmarks[0]已经获取了单只手的所有关键点列表,列表中的每个元素都是**NormalizedLandmark对象**(本身就是单个关键点,包含x/y/z属性)。
错误代码中,第一层循环for hand_landmark in LastLandmarks取出的是单个NormalizedLandmark对象,却试图访问它的landmark属性,不符合MediaPipe的数据结构,因此触发错误。
修复代码
将错误区域的两层循环改为单层循环,直接遍历LastLandmarks中的每个关键点对象:
if LastLandmarks: # 直接遍历每个NormalizedLandmark关键点 for hand_point in LastLandmarks: print(f"POINT: {hand_point.x:.2f} {hand_point.y:.2f} {hand_point.z:.2f}")
如果需要处理多只手的情况,不要在print_results中取result.hand_landmarks[0],而是保留整个列表,然后通过两层循环处理:
# 修改print_results中的赋值 LastLandmarks = result.hand_landmarks # 主循环中的处理代码 if LastLandmarks: # 遍历每只手 for hand_landmarks in LastLandmarks: # 遍历当前手的所有关键点 for hand_point in hand_landmarks: print(f"POINT: {hand_point.x:.2f} {hand_point.y:.2f} {hand_point.z:.2f}")
内容的提问来源于stack exchange,提问作者CrazyProgrammer
相关产品推荐
相关产品推荐

