如何将Keras训练的.h5交通标志分类模型加载到OpenCV代码中
加载.h5交通标志分类模型实现OpenCV视频流检测的实现方案
首先明确前提:你手里的.h5文件是Keras/TensorFlow训练产出的模型文件,需要先确认是包含模型结构+权重的完整模型(如果仅存权重需要先补全结构导出完整模型再使用)。另外如果你的模型仅实现图像级分类能力,需要先结合目标定位逻辑(如Haar级联、YOLO等)裁剪出视频帧中的交通标志候选区域,再送入分类模型推理。
方案1:直接用OpenCV DNN模块加载.h5模型
适用于OpenCV 4.5及以上版本,原生支持读取Keras导出的完整.h5模型:
- 第一步:导出完整.h5模型(如果现有文件是仅权重文件)
from tensorflow.keras.models import load_model # 如果你只有权重文件,先构建和训练时完全一致的模型结构 from your_train_script import build_model model = build_model() model.load_weights("your_weights_only.h5") # 导出包含结构+权重的完整模型 model.save("full_traffic_classifier.h5")
- 第二步:OpenCV加载模型并接入视频流
import cv2 import numpy as np # 加载模型 net = cv2.dnn.readNetFromKeras("full_traffic_classifier.h5") # 你训练时的分类标签对应,按自己的实际情况修改 class_names = ["限速20", "限速30", "禁止通行", "注意行人"] # 训练时的输入尺寸、预处理参数,必须和训练时完全一致 INPUT_SIZE = (32, 32) NORMALIZE_SCALE = 1/255.0 MEAN = (0.0, 0.0, 0.0) SWAP_RB = True # OpenCV默认读入是BGR,Keras训练一般用RGB,需要交换通道 # 打开视频流,0是本地摄像头,也可以填视频文件路径 cap = cv2.VideoCapture(0) while cap.isOpened(): ret, frame = cap.read() if not ret: break # ------------------- 这里需要先加目标检测逻辑定位交通标志区域 ------------------- # 示例默认拿整帧测试,实际使用需要替换为检测到的交通标志裁剪区域 roi = frame # ---------------------------------------------------------------------------- # 预处理 blob = cv2.dnn.blobFromImage(roi, NORMALIZE_SCALE, INPUT_SIZE, MEAN, swapRB=SWAP_RB, crop=False) net.setInput(blob) # 推理 preds = net.forward() # 后处理取最高置信度分类 class_id = np.argmax(preds) conf = preds[0][class_id] # 置信度阈值过滤,阈值按需求调整 if conf > 0.7: cv2.putText(frame, f"{class_names[class_id]}: {conf:.2f}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,255,0), 2) cv2.imshow("Traffic Sign Detection", frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
方案2:转ONNX格式加载(兼容性更强,推荐)
如果遇到OpenCV版本不兼容.h5格式、部分自定义层无法读取的问题,可以先将.h5模型转为ONNX通用格式再加载:
- 第一步:转换.h5模型为ONNX格式
import tensorflow as tf # 先安装依赖:pip install tensorflow tf2onnx model = tf.keras.models.load_model("full_traffic_classifier.h5") # 导出为SavedModel临时文件 tf.saved_model.save(model, "./tmp_savedmodel")
执行命令行转换:
python -m tf2onnx.convert --saved-model ./tmp_savedmodel --output traffic_classifier.onnx
- 第二步:OpenCV加载ONNX模型
仅需要修改方案1中的模型加载代码即可,其余逻辑完全一致:
net = cv2.dnn.readNetFromONNX("traffic_classifier.onnx")
注意事项
- 所有预处理参数(输入尺寸、归一化比例、均值、通道交换逻辑)必须和模型训练时的参数完全一致,否则会出现推理准确率严重下降的问题
- 如果需要实现完整的检测功能,需要额外接入交通标志定位逻辑,优先推荐轻量版YOLO系列模型做检测,裁剪出ROI后再送分类模型推理
- 若要提升实时性,可以设置DNN推理后端为OpenCL、CUDA等,调用
net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA)即可
内容的提问来源于stack exchange,提问作者Hussein Jammal
相关产品推荐
相关产品推荐

