Ubuntu20.04下通过Python API调用MediaPipe模板匹配遇错求助
问题解决步骤
你现在遇到的报错核心是BoxDetectorCalculator无法正确读取你传入的KNIFT索引文件,可按照以下步骤排查修复:
1. 优先检查参数传递正确性
你在calculator_params中传入的键需要和计算图中节点的name字段完全匹配:
- 打开你使用的
template_matching_desktop.pbtxt文件,找到calculator: "BoxDetectorCalculator"对应的节点,查看它的name字段值 - 如果节点
name是BoxDetectorCalculator而非BoxDetector,则需要把参数键修改为BoxDetectorCalculator.index_proto_filename
2. 修正路径处理逻辑
Mediapipe C++侧的计算器默认会优先从运行时资源目录(也就是你报错的/usr/local/lib/python3.8/dist-packages/mediapipe路径)读取文件,直接传入普通绝对路径可能会被错误拼接,可选择以下两种方案之一修复:
- 方案一:将你的
object_knift_index.pb文件放到/usr/local/lib/python3.8/dist-packages/mediapipe目录下,参数传入文件名即可 - 方案二:对传入的路径做完全展开处理,确保没有相对路径、
~等Shell专属标识:index_path = os.path.abspath(os.path.expanduser("/path/to/my/object_knift_index.pb"))
3. 检查二进制计算图的正确性
SolutionBase的binary_graph_path参数要求传入二进制格式的计算图(.pb后缀),不能直接传入文本格式的.pbtxt文件,如果你没有做格式转换,可通过以下命令将pbtxt转为二进制pb:
cd ~/mediapipe bazel run //mediapipe/framework:calculator_graph_config_parser -- \ --input_text_proto=mediapipe/graphs/template_matching/template_matching_desktop.pbtxt \ --output_binary_proto=template_matching_binary.pb
转换完成后再把template_matching_binary.pb的路径传给binary_graph_path即可。
4. 替代实现方案(避坑推荐)
如果不想修改SolutionBase相关代码,可以直接用底层CalculatorGraph接口加载修改后的计算图,避免参数传递逻辑的坑:
import os import cv2 import time import numpy as np import mediapipe as mp from mediapipe.framework import calculator_pb2 from google.protobuf import text_format from mediapipe.calculators.video import box_detector_calculator_pb2 # 路径展开 pbtxt_path = os.path.abspath(os.path.expanduser("~/mediapipe/mediapipe/graphs/template_matching/template_matching_desktop.pbtxt")) index_pb_path = os.path.abspath(os.path.expanduser("/path/to/my/object_knift_index.pb")) # 加载并修改计算图配置 with open(pbtxt_path, 'r') as f: graph_config = calculator_pb2.CalculatorGraphConfig() text_format.Parse(f.read(), graph_config) # 直接修改配置里的索引文件路径 for node in graph_config.node: if node.calculator == "BoxDetectorCalculator": options = box_detector_calculator_pb2.BoxDetectorCalculatorOptions() node.options.Unpack(options) options.index_proto_filename = index_pb_path node.options.Pack(options) break # 初始化并启动计算图 graph = mp.CalculatorGraph(graph_config=graph_config) graph.start_run() # 读取摄像头帧处理 cap = cv2.VideoCapture(0) while cap.isOpened(): ret, frame = cap.read() if not ret: break frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # 塞入输入流 graph.add_packet_to_input_stream( "input_video", mp.packet_creator.create_image_frame( image_format=mp.ImageFormat.SRGB, data=frame_rgb ).at(mp.Timestamp(int(time.time() * 1e6))) ) # 后续自行补充输出流读取、结果渲染逻辑
内容的提问来源于stack exchange,提问作者Daniel Fitzgerald
相关产品推荐
相关产品推荐

