基于 SpringBoot 3.x 与 OCR 的车牌识别系统

基于 SpringBoot 3.x 与 OCR 的车牌识别系统 — 后端接口设计

1. 技术选型

SpringBoot 3.x:后端框架Tesseract OCR / PaddleOCR:车牌识别引擎Spring Web (REST API):提供 HTTP 接口Spring Data JPA / H2 / MySQL:存储识别历史MultipartFile:处理图片上传


2. 数据模型



import jakarta.persistence.*;
import java.time.LocalDateTime;
 
@Entity
@Table(name = "license_plate_history")
public class LicensePlateHistory {
 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
 
    private String plateNumber;
 
    private String color;
 
    private Integer confidence; // 置信度百分比
 
    private String imagePath; // 存储图片路径或URL
 
    private LocalDateTime timestamp;
 
    // getters & setters
}

3. Repository



import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
 
@Repository
public interface LicensePlateHistoryRepository extends JpaRepository<LicensePlateHistory, Long> {
    List<LicensePlateHistory> findTop10ByOrderByTimestampDesc();
}

4. OCR 服务层

这里以 Tesseract OCR 为示例:



import net.sourceforge.tess4j.ITesseract;
import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;
import org.springframework.stereotype.Service;
 
import java.io.File;
 
@Service
public class OcrService {
 
    private final ITesseract tesseract;
 
    public OcrService() {
        tesseract = new Tesseract();
        tesseract.setDatapath("/usr/share/tessdata"); // tesseract 数据路径
        tesseract.setLanguage("chi_sim"); // 简体中文
    }
 
    public String recognize(File imageFile) throws TesseractException {
        // 返回识别文本
        return tesseract.doOCR(imageFile)
                        .replaceAll("s", ""); // 去掉空格
    }
 
    public int generateConfidence() {
        // 模拟置信度,实际可从OCR引擎返回值获取
        return (int) (85 + Math.random() * 13);
    }
 
    public String detectColor(File imageFile) {
        // 简单演示,实际可用OpenCV分析车牌颜色
        String[] colors = {"蓝色", "绿色", "黄色", "白色"};
        int idx = (int) (Math.random() * colors.length);
        return colors[idx];
    }
}

5. Controller 层



import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
 
import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List;
 
@RestController
@RequestMapping("/api/ocr")
public class LicensePlateController {
 
    @Autowired
    private OcrService ocrService;
 
    @Autowired
    private LicensePlateHistoryRepository historyRepository;
 
    // 1. 上传识别车牌
    @PostMapping("/license-plate")
    public ResponseEntity<?> recognize(@RequestParam("image") MultipartFile imageFile) throws IOException {
        // 保存图片到临时文件
        File tempFile = File.createTempFile("upload-", ".jpg");
        imageFile.transferTo(tempFile);
 
        try {
            String plateNumber = ocrService.recognize(tempFile);
            int confidence = ocrService.generateConfidence();
            String color = ocrService.detectColor(tempFile);
            LocalDateTime timestamp = LocalDateTime.now();
 
            // 保存历史记录
            LicensePlateHistory history = new LicensePlateHistory();
            history.setPlateNumber(plateNumber);
            history.setConfidence(confidence);
            history.setColor(color);
            history.setImagePath(tempFile.getAbsolutePath());
            history.setTimestamp(timestamp);
            historyRepository.save(history);
 
            return ResponseEntity.ok(new PlateResponse(plateNumber, confidence, color, timestamp));
        } catch (Exception e) {
            return ResponseEntity.status(500).body("OCR识别失败: " + e.getMessage());
        }
    }
 
    // 2. 获取历史记录
    @GetMapping("/history")
    public List<LicensePlateHistory> getHistory(@RequestParam(defaultValue = "10") int limit) {
        return historyRepository.findTop10ByOrderByTimestampDesc();
    }
 
    // 3. 导出结果(返回文本文件示例)
    @GetMapping("/export")
    public ResponseEntity<byte[]> exportResult(@RequestParam String plateNumber) {
        LicensePlateHistory history = historyRepository.findAll().stream()
                .filter(h -> h.getPlateNumber().equals(plateNumber))
                .findFirst()
                .orElse(null);
 
        if (history == null) {
            return ResponseEntity.notFound().build();
        }
 
        String content = String.format("车牌号码: %s
颜色: %s
置信度: %d%%
识别时间: %s",
                history.getPlateNumber(),
                history.getColor(),
                history.getConfidence(),
                history.getTimestamp());
 
        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename="" + plateNumber + ".txt"")
                .contentType(MediaType.TEXT_PLAIN)
                .body(content.getBytes());
    }
 
    // 响应 DTO
    static class PlateResponse {
        public String plateNumber;
        public int confidence;
        public String color;
        public LocalDateTime timestamp;
 
        public PlateResponse(String plateNumber, int confidence, String color, LocalDateTime timestamp) {
            this.plateNumber = plateNumber;
            this.confidence = confidence;
            this.color = color;
            this.timestamp = timestamp;
        }
    }
}

6. 后端功能说明

上传识别

POST /api/ocr/license-plate参数:MultipartFile image返回:JSON { plateNumber, confidence, color, timestamp }

历史记录查询

GET /api/ocr/history?limit=10返回:最近 limit 条识别历史

结果导出

GET /api/ocr/export?plate=XXX返回:车牌识别信息文本文件下载

存储机制

图片可以保存到本地或对象存储历史记录存储数据库(H2/MySQL)


7. 总结

后端设计遵循 RESTful API 规范通过 SpringBoot 3.x + OCR 实现车牌识别提供 识别、历史记录、导出 全套接口支持 高可用扩展:可对接对象存储、缓存置信度、集群部署

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
东北乌蝇哥的头像 - 鹿快
评论 抢沙发

请登录后发表评论

    暂无评论内容