TensorFlow训练的EAST模型用OpenCV.dnn加载失败该如何解决?
报错核心诱因
你通过east.model.save('saved_model/my_model')导出的是TensorFlow标准SavedModel格式,该格式根目录下的saved_model.pb并非OpenCV DNN模块支持的纯冻结推理图(Frozen GraphDef)。SavedModel的pb文件包含模型签名、元数据、变量引用等额外结构,和仅存储算子、权重参数的纯GraphDef格式结构不兼容,因此cv2.dnn.readNet解析时会触发GraphDef解析失败报错。
其他可能的次要诱因:
- pb文件下载/保存过程中损坏
- 传入的文件路径拼写错误、读取权限不足
- OpenCV版本过低,不支持模型用到的新算子
修复方案
方案1:导出OpenCV兼容的纯冻结GraphDef文件
针对TensorFlow 2.x版本执行以下代码转换:
import tensorflow as tf from tensorflow.python.framework.convert_to_constants import convert_variables_to_constants_v2 # 加载原有SavedModel loaded_model = tf.saved_model.load('saved_model/my_model') # 获取推理签名 infer_fn = loaded_model.signatures['serving_default'] # 将模型变量全部转换为常量,生成纯推理图 frozen_fn = convert_variables_to_constants_v2(infer_fn) frozen_graph = frozen_fn.graph.as_graph_def() # 保存冻结pb文件 tf.io.write_graph( graph_or_graph_def=frozen_graph, logdir='./frozen_east', name='east_frozen.pb', as_text=False )
转换完成后调用cv2.dnn.readNet('./frozen_east/east_frozen.pb')即可正常加载。
注:加载前可通过打印
frozen_graph.node的name属性,确认模型输入、输出节点名称和EAST推理需要的节点匹配。
方案2:转ONNX格式加载(兼容性更强)
ONNX是跨框架的模型格式,OpenCV 4.x以上版本对ONNX的支持成熟度更高:
- 安装转换工具:
pip install tf2onnx - 执行转换命令:
python -m tf2onnx.convert --saved-model saved_model/my_model --output east.onnx
- 加载ONNX模型:
net = cv2.dnn.readNetFromONNX('east.onnx')
方案3:直接用TensorFlow接口推理(无需转换)
如果没有强制使用OpenCV DNN模块的需求,可直接调用TensorFlow接口加载原有SavedModel做推理,结果处理后送入Tesseract即可:
import tensorflow as tf # 加载原模型 model = tf.saved_model.load('saved_model/my_model') # 预处理输入图像后推理 input_tensor = tf.convert_to_tensor(preprocessed_img, dtype=tf.float32)[tf.newaxis, ...] score_map, geo_map = model(input_tensor)
内容的提问来源于stack exchange,提问作者e.iluf
相关产品推荐
相关产品推荐

