You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.02 07:24:52