python车牌号OCR识别(centos版)

在实际应用中,车牌号的识别(OCR)是一个非常重要的需求,尤其是在停车场管理、道路监控等场景中。本文将介绍如何在CentOS环境下,通过Docker容器,基于PaddleOCR来实现车牌号的识别。具体内容包括构建Docker镜像的步骤、相关依赖安装、Python脚本实现,以及如何运行整个车牌识别流程。

一、环境准备

我们采用CentOS作为宿主机操作系统,利用Docker容器来构建Python车牌OCR识别环境。容器化可以有效简化环境配置,避免依赖冲突。

1.1 安装Docker

首先,确保宿主机已经安装了Docker。若尚未安装,可以通过以下命令安装:

bash 复制代码
yum update -y
yum install -y yum-utils
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install docker-ce docker-ce-cli containerd.io -y
systemctl start docker
systemctl enable docker
1.2 编写Dockerfile

为了简化依赖的安装,我们基于Ubuntu 22.04来构建镜像。下面是Dockerfile的内容:

Dockerfile 复制代码
# 使用 Ubuntu 22.04 作为基础镜像
FROM ubuntu:22.04

# 设置时区为上海
ENV TZ=Asia/Shanghai
RUN apt-get update && apt-get install -y tzdata && \
    ln -fs /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
    dpkg-reconfigure -f noninteractive tzdata

# 安装 Python3 和所需的依赖
RUN apt-get update && \
    apt-get install -y \
    python3 \
    python3-pip \
    python3-opencv \
    libglib2.0-0 \
    git && \
    rm -rf /var/lib/apt/lists/*

# 升级 pip
RUN pip3 install --upgrade pip -i https://mirrors.aliyun.com/pypi/simple/

# 安装 paddleocr、paddlepaddle 和 matplotlib
RUN pip3 install paddleocr paddlepaddle matplotlib -i https://mirrors.aliyun.com/pypi/simple/

# 设置工作目录
WORKDIR /app

# 复制当前目录到容器的 /app 目录
COPY . /app

此Dockerfile基于Ubuntu 22.04,并安装了Python3、PaddleOCR、PaddlePaddle和OpenCV等依赖。这些依赖都是车牌识别所必需的,安装过程中我们使用了阿里云的镜像源来加快速度。

二、车牌OCR识别Python脚本

接下来,我们编写车牌OCR识别的Python脚本。核心流程包括图像的预处理、车牌区域提取、PaddleOCR模型的加载与识别。

2.1 车牌识别核心代码
python 复制代码
# -*- coding: utf-8 -*-
import cv2
from paddleocr import PaddleOCR
import os
from matplotlib import pyplot as plt
import argparse
import logging
import matplotlib

# 使用 Agg 后端用于无显示的情况
matplotlib.use('Agg')

# 设置日志记录
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

def Morph_Distinguish(img):
    """ 使用形态学操作提取车牌区域 """
    gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
    
    # 图像增强:对比度增强和边缘检测
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (17, 17))
    tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, kernel)
    
    # Sobel算子进行边缘提取
    y = cv2.Sobel(tophat, cv2.CV_16S, 1, 0)
    absY = cv2.convertScaleAbs(y)
    
    # 自适应阈值处理
    ret, binary = cv2.threshold(absY, 75, 255, cv2.THRESH_BINARY)
    
    # 形态学操作(开闭操作去噪)
    kernel_open = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 15))
    opened = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel_open)
    kernel_close = cv2.getStructuringElement(cv2.MORPH_RECT, (41, 15))
    closed = cv2.morphologyEx(opened, cv2.MORPH_CLOSE, kernel_close)
    
    # 水平和垂直膨胀与腐蚀操作
    kernel_x = cv2.getStructuringElement(cv2.MORPH_RECT, (25, 7))
    kernel_y = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 11))
    dilate_x = cv2.dilate(closed, kernel_x)
    erode_y = cv2.erode(dilate_x, kernel_y)

    # 继续形态学操作以突出车牌
    kernel_plate = cv2.getStructuringElement(cv2.MORPH_RECT, (25, 9))
    plate_area = cv2.dilate(erode_y, kernel_plate)

    # 提取轮廓
    contours, _ = cv2.findContours(plate_area, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    img_copy = img.copy()
    cv2.drawContours(img_copy, contours, -1, (255, 0, 255), 2)
    
    # 遍历找到可能的车牌区域
    for contour in contours:
        area = cv2.contourArea(contour)
        x, y, w, h = cv2.boundingRect(contour)

        # 车牌宽高比范围和面积阈值调整
        if h * 2 < w < h * 6 and area > 1500:
            ROI = img[y:y + h, x:x + w]
            logging.info(f"找到车牌区域,位置: x={x}, y={y}, w={w}, h={h}")
            return ROI
    
    logging.warning("未能提取到车牌区域")
    return None

def main(image_path):
    """ 主函数:读取图像、预处理、OCR识别 """
    # PaddleOCR初始化
    ocr = PaddleOCR(use_angle_cls=False, use_gpu=False, lang="ch", show_log=False)

    # 读取图片
    img = cv2.imread(image_path)
    if img is None:
        logging.error(f"无法读取图片: {image_path}")
        return
    
    # 调整图像尺寸
    img_resized = cv2.resize(img, (int(img.shape[1] * 0.5), int(img.shape[0] * 0.5)))

    # 获取车牌区域
    plate_img = Morph_Distinguish(img_resized)
    if plate_img is None:
        logging.error("没有提取到车牌区域")
        return
    
    # 保存车牌图像用于调试
    plt.imshow(plate_img), plt.axis('off'), plt.title("车牌区域")
    plt.savefig("detected_plate.png")
    
    # OCR 识别车牌
    ocr_results = ocr.ocr(plate_img, cls=False)
    if ocr_results:
        for line in ocr_results:
            number_plate = line[-1][-1][0]
            logging.info(f"车牌号: {number_plate}")
            print(f"车牌号:{number_plate}")
    else:
        logging.warning("OCR 识别失败,未能找到有效车牌")

if __name__ == '__main__':
    # 使用argparse解析命令行参数
    parser = argparse.ArgumentParser(description="车牌识别程序")
    parser.add_argument('image_path', type=str, help='输入图片的路径')
    args = parser.parse_args()

    # 运行主程序
    main(args.image_path)
2.2 核心步骤说明
  1. 车牌区域提取:使用形态学操作、边缘检测等技术提取车牌区域。
  2. OCR识别:调用PaddleOCR库对车牌区域进行识别,返回车牌号。
  3. 日志与调试:将每个重要步骤记录到日志中,方便调试与监控。

三、运行车牌识别

在完成Docker镜像的构建与Python脚本编写后,我们可以通过以下命令来运行车牌识别程序:

bash 复制代码
docker run --rm \
  -v /www/wwwroot/ocr_py:/app \
  -v /www/cosfs/api-business:/images \
  -v /www/cosfs/paddleocr_models:/root/.paddleocr \
  plate_recognition \
  python3 /app/main.py /images/20241009/1728455029333.jpg
  • /www/wwwroot/ocr_py:/app 将当前代码挂载到容器的 /app 目录。
  • /www/cosfs/api-business:/images 挂载包含待识别车牌图片的路径。
  • `/www/cosfs/paddleocr_models:/root/.p

addleocr` 挂载PaddleOCR的模型文件路径。

运行完成后,程序会自动识别图片中的车牌号,并输出结果。

四、总结

本文介绍了如何在CentOS环境下,使用Docker容器搭建Python车牌号OCR识别系统。通过PaddleOCR进行车牌区域的检测和识别,整个过程简单高效。

五、示例图


相关推荐
AntBlack3 分钟前
这篇绝不是标题党 :太好用了 , 一天就能快速实现一个可创业小项目
前端·后端·python
天才少女爱迪生1 小时前
python程序对服务器cpu和内存资源占用的管理。
服务器·开发语言·python
薇远镖局1 小时前
python re模块 详解
开发语言·python
飞滕人生TYF2 小时前
java 数组 拼接 详解
java·开发语言·python
chenxiemin3 小时前
卡尔曼滤波:从理论到应用的简介
python·算法·filter·卡尔曼滤波·kalman
只怕自己不够好3 小时前
手写体识别Tensorflow实现
人工智能·python·tensorflow
想去看海9853 小时前
如何在pycharm中 判断是否成功安装pytorch环境
ide·python·pycharm
YRr YRr3 小时前
ubuntu20.04 解决Pycharm没有写入权限,无法通过检查更新更新的问题
ide·python·pycharm·ubuntu20.04
孤客网络科技工作室4 小时前
Python Tornado框架教程:高性能Web框架的全面解析
前端·python·tornado
青石横刀策马4 小时前
Python学习笔记(2)正则表达式
笔记·python·学习