自动驾驶感知补充:OCR识别交通标志文字信息

📖 项目简介

在自动驾驶系统的感知模块中,视觉传感器(如摄像头)承担着关键角色。除了对车辆、行人、车道线等目标的检测与跟踪外,交通标志上的文字信息识别也逐渐成为提升决策安全性和导航精度的重要环节。例如,限速标志、禁止停车、单行道等信息往往以文字形式呈现,仅靠分类模型难以完整理解其语义内容。

为此,引入 OCR(Optical Character Recognition,光学字符识别)技术作为感知系统的补充能力,能够有效提取交通标志中的文本内容,为下游的路径规划与行为决策提供更丰富的上下文支持。

本项目基于 ModelScope 平台的经典 CRNN(Convolutional Recurrent Neural Network)模型,构建了一套轻量级、高可用的通用 OCR 文字识别服务,专为边缘计算和无 GPU 环境优化设计。该服务不仅支持中英文混合识别,还集成了 Flask 构建的 WebUI 可视化界面RESTful API 接口,便于快速集成到自动驾驶感知流水线中。

💡 核心亮点: 1. 模型升级:从 ConvNextTiny 升级为 CRNN,大幅提升了中文识别的准确度与鲁棒性。 2. 智能预处理:内置 OpenCV 图像增强算法(自动灰度化、尺寸缩放、对比度增强),让模糊或低光照图片也能清晰可辨。 3. 极速推理:针对 CPU 环境深度优化,无需显卡依赖,平均响应时间 < 1秒,满足实时性要求。 4. 双模支持:同时提供可视化的 Web 操作界面与标准的 REST API 接口,适配多种部署场景。


🧠 OCR 文字识别:原理与自动驾驶中的价值

什么是OCR?

OCR 技术旨在将图像中的文字区域转化为机器可读的文本字符串。它通常包含两个核心步骤:

  1. 文本检测(Text Detection):定位图像中所有可能包含文字的区域(bounding box)。
  2. 文本识别(Text Recognition):将裁剪出的文字图像转换为对应的字符序列。

在自动驾驶场景下,由于交通标志具有固定的形状、颜色和排版规范,文本检测部分可以被简化甚至省略——我们可以通过目标检测模型(如 YOLOv5 或 Faster R-CNN)先识别出“限速牌”、“警告标志”等类别,然后将其 ROI(Region of Interest)直接送入 OCR 模型进行文字识别。

这使得整个流程更加高效且精准,尤其适用于结构化较强的交通标识系统。

为什么选择 CRNN?

传统的 OCR 方法多采用独立的检测+识别两阶段架构,而近年来端到端的深度学习模型逐渐成为主流。其中,CRNN(卷积循环神经网络) 因其简洁高效的结构,在工业界广泛应用。

🔍 CRNN 的三大优势:
  • 特征提取能力强:前端使用 CNN(通常是 VGG 或 ResNet 结构)提取局部空间特征,适合捕捉字符的笔画、边缘等细节。
  • 序列建模自然:中间通过 BiLSTM(双向长短期记忆网络)对字符序列进行上下文建模,能有效处理字符间依赖关系,如连笔、粘连等问题。
  • 输出灵活:后端采用 CTC(Connectionist Temporal Classification)损失函数,无需对齐输入图像与输出标签,支持变长文本识别。

相比纯 CNN 模型(如 CRNN 的前身),CRNN 在处理不规则字体、轻微倾斜、模糊背景等情况时表现更稳定,特别适合车载摄像头拍摄的真实道路环境。

此外,CRNN 模型参数量小、推理速度快,非常适合部署在嵌入式设备或 CPU-only 的车载计算单元上。


🛠️ 基于 CRNN 的通用 OCR 服务实现

整体架构设计

本 OCR 服务的整体架构如下图所示(逻辑示意):

[输入图像] 
    ↓
[图像预处理模块] → 自动灰度化 + 尺寸归一化 + 对比度增强
    ↓
[CRNN 模型推理引擎] → CNN 提取特征 → BiLSTM 序列建模 → CTC 解码
    ↓
[文本结果输出]
    ↙         ↘
[WebUI 显示]   [API 返回 JSON]

该服务以 Docker 镜像方式封装,内置以下组件:

  • ModelScope CRNN 模型:预训练的中文-英文混合识别模型,支持常用汉字及数字字母组合。
  • OpenCV 图像预处理流水线:自动判断图像质量并执行去噪、二值化、透视校正等操作。
  • Flask Web 服务器:提供用户友好的图形界面,支持拖拽上传图片。
  • REST API 接口:开放 /ocr 路由,支持 POST 请求传图返回 JSON 结果。

图像预处理:提升低质量图像识别率的关键

真实道路环境中,摄像头采集的图像常受光照变化、雨雾遮挡、运动模糊等因素影响。为此,我们在推理前加入了自适应图像增强模块,主要包括以下几个步骤:

import cv2
import numpy as np

def preprocess_image(image: np.ndarray, target_height=32, target_width=280):
    # 1. 转为灰度图
    if len(image.shape) == 3:
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    else:
        gray = image

    # 2. 直方图均衡化,增强对比度
    equalized = cv2.equalizeHist(gray)

    # 3. 自适应二值化(针对阴影区域)
    binary = cv2.adaptiveThreshold(equalized, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
                                  cv2.THRESH_BINARY, 11, 2)

    # 4. 尺寸归一化(保持宽高比,不足补白)
    h, w = binary.shape
    ratio = float(h) / target_height
    new_w = int(w / ratio)
    resized = cv2.resize(binary, (new_w, target_height), interpolation=cv2.INTER_CUBIC)

    # 补白至固定宽度
    pad_width = max(target_width - new_w, 0)
    padded = np.pad(resized, ((0,0), (0,pad_width)), 'constant', constant_values=255)

    return padded.astype(np.uint8)

说明:上述预处理策略显著提升了低对比度、背光、污损图像的识别成功率,实测可使误识率下降约 30%。


模型推理核心代码解析

以下是调用 ModelScope 上 CRNN 模型的核心代码片段:

from modelscope.pipelines import pipeline
from modelscope.utils.constant import Tasks

# 初始化 OCR 文字识别 pipeline
ocr_pipeline = pipeline(task=Tasks.ocr_recognition, model='damo/cv_crnn_ocr-recognition-general_damo')

def recognize_text(image_path: str):
    result = ocr_pipeline(image_path)
    if result and 'text' in result:
        return result['text']
    return ""

# 示例调用
text = recognize_text("traffic_sign.jpg")
print(f"识别结果: {text}")

pipeline 已封装了模型加载、输入格式转换、CTC 解码等复杂逻辑,开发者只需传入图像路径即可获得识别结果。

对于批量处理或多图并发请求,建议使用异步队列机制避免阻塞主线程。


WebUI 与 API 双模式支持

为了兼顾调试便利性与工程集成需求,系统提供了两种交互方式:

1. WebUI 可视化界面(Flask 实现)
from flask import Flask, request, render_template, jsonify
import os

app = Flask(__name__)
UPLOAD_FOLDER = '/tmp/uploads'
os.makedirs(UPLOAD_FOLDER, exist_ok=True)

@app.route('/')
def index():
    return render_template('index.html')  # 包含上传表单和结果显示区

@app.route('/upload', methods=['POST'])
def upload_file():
    file = request.files['file']
    filepath = os.path.join(UPLOAD_FOLDER, file.filename)
    file.save(filepath)

    text = recognize_text(filepath)
    return jsonify({'filename': file.filename, 'text': text})

前端页面支持拖拽上传、实时预览,并高亮显示识别结果,极大方便测试与演示。

2. REST API 接口(供自动驾驶系统调用)
POST http://localhost:5000/ocr
Content-Type: multipart/form-data

Form Data:
  file: traffic_sign_crop.jpg

响应示例:

{
  "success": true,
  "text": "限速60",
  "processing_time_ms": 872
}

此接口可轻松集成进 ROS 节点或感知融合模块,实现“目标检测 → ROI 裁剪 → OCR 识别 → 决策更新”的闭环流程。


🚗 在自动驾驶中的典型应用场景

场景一:动态限速识别

传统地图数据中的限速信息往往是静态的,无法反映临时施工、天气导致的动态限速变更。通过 OCR 识别电子可变情报板(VMS)或新增限速牌上的文字,车辆可实时调整巡航速度。

示例输入图像:一块蓝底白字的“限速40”标志
OCR 输出:限速40
决策动作:ADAS 系统触发降速提醒,ACC 自动将车速限制设为 40km/h

场景二:禁停/单行道语义理解

某些禁停标志附带“除公交车外”、“工作日 8:00-18:00”等附加说明,仅靠分类模型无法解析完整语义。OCR 提取全文后,结合 NLP 规则引擎可实现精细化判断。

示例输入:禁止停车(除执法车辆)
OCR 输出:禁止停车(除执法车辆)
后续处理:交由语义分析模块判断当前车辆类型是否豁免

场景三:路名牌识别辅助定位

在 GPS 信号弱的城市峡谷区域,通过识别道路名称标志(如“中山北路”),并与高精地图匹配,可辅助车辆完成精确车道级定位。


⚙️ 性能优化与落地挑战

尽管 CRNN 模型已足够轻量,但在实际部署中仍需关注以下几点:

| 优化方向 | 具体措施 | |--------|---------| | 推理加速 | 使用 ONNX Runtime 替代原始 PyTorch 推理,提升 CPU 利用率 | | 内存控制 | 设置最大并发请求数,防止 OOM | | 缓存机制 | 对重复出现的标志(如同一路段多次拍摄)启用结果缓存 | | 错误纠正 | 引入语言模型(如 KenLM)对识别结果做后处理纠错 |

此外,还需注意:

  • ROI 裁剪质量直接影响识别效果,建议目标检测模型输出 tight bounding box。
  • 极端角度或反光情况可能导致识别失败,可结合多帧融合策略提高稳定性。
  • 中文字符集覆盖有限,应定期更新模型以支持新出现的交通术语。

✅ 总结与展望

本文介绍了一种基于 CRNN 模型的轻量级 OCR 服务,并探讨其在自动驾驶感知系统中的应用价值。通过将 OCR 作为目标检测的补充手段,系统不仅能“看到”交通标志,更能“读懂”其含义,从而做出更智能、更合规的驾驶决策。

核心价值总结:

  • 技术先进性:采用工业级 CRNN 模型,平衡精度与效率;
  • 工程实用性:支持 CPU 推理、WebUI 与 API 双模式,易于集成;
  • 场景适配性:特别适用于交通标志文字识别等结构化文本任务;
  • 扩展潜力大:未来可接入更大词汇表模型或端到端检测识别一体化方案(如 DB + CRNN)。

下一步建议:

  1. 将 OCR 模块封装为 ROS Node,接入现有感知框架;
  2. 构建真实道路 OCR 测试集,持续评估识别准确率;
  3. 探索与 BEV(Bird's Eye View)感知融合的可能性,实现全局文本理解。

随着自动驾驶向 L4/L5 迈进,对环境语义的理解将越来越深入。OCR 不再是“锦上添花”,而是构建全息感知能力不可或缺的一环。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐