为了进一步提升代码的效率和可维护性,可以考虑以下几个方面的优化:
1. **视频解码优化**:
- 使用OpenCV的`preprocess`功能来直接从原始视频帧中提取RGB图像,避免不必要的复制和转换。
2. **模型推理优化**:
- 使用ONNX Runtime的定制配置,如启用自动形状推测和启用量化模式,来进一步提高模型推理速度。
3. **结果后处理优化**:
- 使用更高效的非极大值抑制(NMS)实现,如使用OpenCV自带的NMS函数。
4. **线程池优化**:
- 根据CPU核心数量动态调整线程池大小,避免创建过多的线程导致上下文切换开销。
5. **性能监控和日志记录**:
- 添加性能监控代码,记录每个阶段(如模型推理、NMS、绘制边界框)的时间消耗。
- 使用日志记录功能来记录关键事件和性能指标,便于调试和优化。
6. **异常处理和资源管理**:
- 确保所有创建的线程在程序结束前都被正确地终止。
- 添加更详细的异常处理逻辑,确保程序在发生错误时能做出适当的响应。
7. **代码结构和注释**:
- 重构代码,使其更加模块化,每个部分都有明确的职责和清晰的接口。
- 添加详细的注释,说明代码的功能和目的,方便他人理解和维护。
以下是优化后的示例代码:
import cv2
import onnxruntime as ort
import numpy as np
from concurrent.futures import ThreadPoolExecutor, as_completed
# 配置ONNX Runtime推理环境
ort_session = ort.InferenceSession('yolov5s.onnx')
ort_session.enable_auto_shape_inference = True
# 定义处理帧的函数
def process_frame(frame, ort_session):
# 预处理帧
input_shape = ort_session.get_inputs()[0].shape
frame = cv2.resize(frame, dsize=None, fx=input_shape[2] / frame.shape[1], fy=input_shape[3] / frame.shape[0])
input_tensor = np.transpose(frame.astype(np.float32), (2, 0, 1))
# 推理
results = ort_session.run(None, {'input': input_tensor})
# NMS后处理
boxes, scores, classes = results[0], results[1], results[2]
indices = cv2.computeWeightedMedian(scores, boxes, weight=1.0, method=cv2.NMSBOXES_UNION)
boxes = boxes[indices]
scores = scores[indices]
classes = classes[indices]
# 绘制边界框和标签
for box, score, class_id in zip(boxes, scores, classes):
if score > 0.5:
class_name = f'{class_id}({int(score * 100)}%)