在本项目中,我们将构建一个 车牌号识别网站,用户可以上传车辆图片,系统会通过 OCR 车牌识别模型(PaddleOCR / HyperLPR) 提取车牌号码,并将结果展示到前端。同时,用户可以选择不同的 OCR 模型,并查看识别历史记录。
car-plate-recognition/
├── backend/ # FastAPI 后端
│ ├── main.py # FastAPI 入口
│ ├── models.py # 数据库模型
│ ├── routes/ # API 路由
│ │ ├── ocr.py # 车牌识别 API
│ │ ├── auth.py # 用户认证 API
│ │ ├── history.py # 识别历史 API
│ ├── services/ # 业务逻辑
│ │ ├── ocr_service.py # OCR 识别处理
│ ├── database.py # 数据库连接
│ ├── config.py # 配置文件
│ ├── requirements.txt # 依赖库
│ ├── Dockerfile # 容器化部署
├── frontend/ # React 前端
│ ├── src/
│ │ ├── components/ # 组件
│ │ ├── pages/ # 页面
│ │ ├── services/ # API 请求
│ │ ├── App.tsx # 入口
│ │ ├── index.tsx # 渲染入口
│ ├── package.json # 前端依赖
│ ├── vite.config.ts # Vite 配置
├── docker-compose.yml # 一键部署
pip install fastapi uvicorn paddleocr hyperlpr mysql-connector-python sqlalchemy python-multipart pydantic jwt
backend/main.py
from fastapi import FastAPI
from routes import ocr, auth, history
from database import engine, Base
# 初始化数据库
Base.metadata.create_all(bind=engine)
app = FastAPI()
# 注册 API 路由
app.include_router(ocr.router)
app.include_router(auth.router)
app.include_router(history.router)
@app.get("/")
async def root():
return {"message": "车牌识别 API"}
backend/routes/ocr.py
from fastapi import APIRouter, UploadFile, File, Form
from services.ocr_service import process_image
import shutil
import os
router = APIRouter(prefix="/ocr", tags=["OCR"])
UPLOAD_FOLDER = "uploads"
@router.post("/recognize")
async def recognize_license_plate(
file: UploadFile = File(...),
model: str = Form("paddleocr") # 默认使用 PaddleOCR
):
file_path = f"{UPLOAD_FOLDER}/{file.filename}"
# 保存上传的图片
with open(file_path, "wb") as buffer:
shutil.copyfileobj(file.file, buffer)
# 进行 OCR 识别
plate_number = process_image(file_path, model)
return {"filename": file.filename, "plate_number": plate_number, "model": model}
backend/services/ocr_service.py
from paddleocr import PaddleOCR
from hyperlpr import HyperLPR
import cv2
ocr_paddle = PaddleOCR(use_angle_cls=True, lang="ch")
def process_image(image_path: str, model: str):
image = cv2.imread(image_path)
if model == "paddleocr":
result = ocr_paddle.ocr(image_path, cls=True)
plate_number = result[0][0][1][0] if result else "未识别"
elif model == "hyperlpr":
result = HyperLPR().Run(image)
plate_number = result[0][0] if result else "未识别"
return plate_number
npx create-vite@latest frontend --template react-ts
cd frontend
npm install antd axios
frontend/src/pages/OCRPage.tsx
import React, { useState } from "react";
import { Upload, Button, Select, message } from "antd";
import axios from "axios";
const OCRPage: React.FC = () => {
const [image, setImage] = useState(null);
const [model, setModel] = useState("paddleocr");
const [result, setResult] = useState("");
const handleUpload = async () => {
if (!image) {
message.error("请上传图片!");
return;
}
const formData = new FormData();
formData.append("file", image);
formData.append("model", model);
const response = await axios.post("http://localhost:8000/ocr/recognize", formData);
setResult(response.data.plate_number);
};
return (
车牌识别
{ setImage(file); return false; }}>
识别结果: {result}
);
};
export default OCRPage;
uvicorn main:app --reload --host 0.0.0.0 --port 8000
cd frontend
npm run dev
docker-compose.yml
version: '3.8'
services:
backend:
build: ./backend
ports:
- "8000:8000"
frontend:
build: ./frontend
ports:
- "3000:3000"
docker-compose up -d
基于 FastAPI + React + PaddleOCR/HyperLPR 构建车牌号识别网站
✅ 支持上传图片并自动识别车牌
✅ 支持多种 OCR 车牌识别模型
✅ 支持 API 交互,前后端分离
✅ 支持数据库存储识别历史
✅ 可容器化部署,支持 Docker
完整的车牌识别网站搭建完成!