Mediapipe C++计算器:如何匹配左右手与对应手部关键点坐标?
问题
在Mediapipe框架下开发了C++计算器Hand_Landmark_Write_To_File_Calculator,用于根据左右手属性(Handedness)将归一化手部关键点(x,y,z)写入文件。该计算器接收HandLandmarkTrackingCpu节点的两个输入:
- HANDENESS:检测到的手的左右手属性,类型为
std::vector<ClassificationList> - LANDMARKS:检测到的手部关键点集合,类型为
std::vector<NormalizedLandmarkList>
当前代码在单只手检测时可正确输出对应手标签的关键点x坐标,但检测两只手时,因始终调用input_landmarks[0]获取关键点,导致左右手标签与对应手部关键点无法正确关联(比如两只手时会重复输出首个检测手的坐标)。需要实现两只手检测时Handedness与对应手部关键点的匹配。
附当前计算器核心代码片段:
std::string label; for (int i = 0; i < classifications.size(); i++) { label = classifications[i].classification(0).label(); if (label.compare("Right") == 1) { std::cout << "Right : " << input_landmarks[0].landmark(0).x() << std::endl; } else { std::cout << "Left : " << input_landmarks[0].landmark(0).x() << std::endl; } }
已将该计算器添加至示例计算图hand_trancking_desktop_live.pbtxt中。
解决方案
Mediapipe中HandLandmarkTrackingCpu输出的HANDENESS和LANDMARKS是按索引一一对应的:即classifications[i]对应的就是input_landmarks[i]的手的属性,不需要额外匹配逻辑。
只需要修改代码,将固定的input_landmarks[0]替换为循环变量对应的input_landmarks[i],同时修正字符串比较的错误(compare返回0表示相等,之前的==1逻辑错误):
std::string label; // 遍历每一只手的分类和关键点,索引一一对应 for (int i = 0; i < classifications.size(); i++) { // 确保当前索引在关键点列表的有效范围内 if (i >= input_landmarks.size()) { continue; } label = classifications[i].classification(0).label(); // 修正compare的判断逻辑:返回0表示字符串相等 if (label.compare("Right") == 0) { std::cout << "Right : " << input_landmarks[i].landmark(0).x() << std::endl; } else { std::cout << "Left : " << input_landmarks[i].landmark(0).x() << std::endl; } }
关键说明
- 索引对应关系:Mediapipe在输出手部数据时,会保证同一只手的Handedness分类和Landmarks处于相同的索引位置,直接通过循环变量
i关联即可。 - 字符串比较修正:
std::string::compare函数返回0代表两个字符串完全匹配,之前的==1是错误的判断条件,会导致逻辑反转或错误。 - 边界检查:添加
i >= input_landmarks.size()的判断,避免因分类列表和关键点列表长度不一致导致的越界访问。
内容的提问来源于stack exchange,提问作者Myosin
相关产品推荐
相关产品推荐

