MobileLPR 移动端的准商业级车牌识别库

damone大约 209 分钟工作总结NCNN车牌识别深度学习

logo
logo

Mobile-LPR 是一个面向移动端的准商业级车牌识别库,以 NCNN 作为推理后端,使用 DNN 作为算法核心,支持多种车牌检测算法,支持车牌识别和车牌颜色识别。

Android Demo 见 example/android-example

特点

  • 超轻量,核心库只依赖 NCNN,并且对模型量化进行支持
  • 多检测,支持 SSD,MTCNN,LFFD 等目标检测算法
  • 精度高,LFFD 目标检测在 CCPD 检测 AP 达到 98.9,车牌识别达到 99.95%, 综合识别率超过 99%
  • 易使用,只需要 10 行代码即可完成车牌识别
  • 易扩展,可快速扩展各类检测算法

算法流程

构建及安装

  1. 下载源码
git clone <https://github.com/xiangweizeng/mobile-lpr.git>
  1. 准备环境
  • 安装 opencv4.0 及以上, freetype 库
  • 安装 cmake3.0 以上版本,支持 c++11 的 c++ 编译器,如 gcc-6.3
  1. 编译安装
mkdir build
cd build
cmake ..
make install

使用及样例

  1. 使用 MTCNN 检测
  • 代码样例
void test_mtcnn_plate(){
    pr::fix_mtcnn_detector("../../models/float", pr::mtcnn_float_detector);
    pr::PlateDetector detector = pr::IPlateDetector::create_plate_detector(pr::mtcnn_float_detector);

    pr::fix_lpr_recognizer("../../models/float", pr::float_lpr_recognizer);
    pr::LPRRecognizer lpr =  pr::float_lpr_recognizer.create_recognizer();
    Mat img = imread("../../image/plate.png");

    ncnn::Mat sample = ncnn::Mat::from_pixels(img.data, ncnn::Mat::PIXEL_BGR, img.cols, img.rows);
    std::vector<pr::PlateInfo> objects;
    detector->plate_detect(sample, objects);
    lpr->decode_plate_infos(objects);

    for (auto pi : objects)
    {
        cout << "plate_no: " << pi.plate_color << pi.plate_no << " box:" << pi.bbox.xmin << ","
        << pi.bbox.ymin << "," << pi.bbox.xmax << "," << pi.bbox.ymax << "," << pi.bbox.score << endl;
    }
}

  • 效果示例:
  1. 使用 LFFD 检测
  • 代码样例
void test_lffd_plate()
{
    pr::fix_lffd_detector("../../models/float", pr::lffd_float_detector);
    pr::PlateDetector detector = pr::IPlateDetector::create_plate_detector(pr::lffd_float_detector);

    pr::fix_lpr_recognizer("../../models/float", pr::float_lpr_recognizer);
    pr::LPRRecognizer lpr =  pr::float_lpr_recognizer.create_recognizer();
    Mat img = imread("../../image/plate.png");

    ncnn::Mat sample = ncnn::Mat::from_pixels(img.data, ncnn::Mat::PIXEL_BGR, img.cols, img.rows);
    std::vector<pr::PlateInfo> objects;
    detector->plate_detect(sample, objects);
    lpr->decode_plate_infos(objects);

    for (auto pi : objects)
    {
        cout << "plate_no: " << pi.plate_color << pi.plate_no << " box:" << pi.bbox.xmin << ","
             << pi.bbox.ymin << "," << pi.bbox.xmax << "," << pi.bbox.ymax << "," << pi.bbox.score << endl;
    }
}

  • 效果示例:
  1. 使用 SSD 检测
  • 代码样例
void test_ssd_plate()
{
    pr::fix_ssd_detector("../../models/float", pr::ssd_float_detector);
    pr::PlateDetector detector = pr::IPlateDetector::create_plate_detector(pr::ssd_float_detector);

    pr::fix_lpr_recognizer("../../models/float", pr::float_lpr_recognizer);
    pr::LPRRecognizer lpr =  pr::float_lpr_recognizer.create_recognizer();
    Mat img = imread("../../image/manys.jpeg");

    ncnn::Mat sample = ncnn::Mat::from_pixels(img.data, ncnn::Mat::PIXEL_BGR, img.cols, img.rows);
    std::vector<pr::PlateInfo> objects;
    detector->plate_detect(sample, objects);
    lpr->decode_plate_infos(objects);

    for (auto pi : objects)
    {
        cout << "plate_no: " << pi.plate_color << pi.plate_no << " box:" << pi.bbox.xmin << ","
             << pi.bbox.ymin << "," << pi.bbox.xmax << "," << pi.bbox.ymax << "," << pi.bbox.score << endl;
    }
}

  • 效果示例:
  1. 使用量化模型
  • 代码样例
void test_quantize_mtcnn_plate(){
    pr::fix_mtcnn_detector("../../models/quantize", pr::mtcnn_int8_detector);
    pr::PlateDetector detector = pr::IPlateDetector::create_plate_detector(pr::mtcnn_int8_detector);

    pr::fix_lpr_recognizer("../../models/quantize", pr::int8_lpr_recognizer);
    pr::LPRRecognizer lpr =  pr::int8_lpr_recognizer.create_recognizer();
    Mat img = imread("../../image/plate.png");

    ncnn::Mat sample = ncnn::Mat::from_pixels(img.data, ncnn::Mat::PIXEL_BGR, img.cols, img.rows);
    std::vector<pr::PlateInfo> objects;
    detector->plate_detect(sample, objects);
    lpr->decode_plate_infos(objects);

    for (auto pi : objects)
    {
        cout << "plate_no: " << pi.plate_color << pi.plate_no << " box:" << pi.bbox.xmin << ","
             << pi.bbox.ymin << "," << pi.bbox.xmax << "," << pi.bbox.ymax << "," << pi.bbox.score << endl;
    }
}


  • 效果示例:

后续工作

  • 添加更优的算法支持
  • 优化模型,支持更多的车牌类型,目前支持普通车牌识别,欢迎各位大神提供更好的模型
  • 优化模型,更高的精度
  • 性能评估

参考

  1. light-LPRopen in new window 本项目的模型大部分来自与此
  2. NCNNopen in new window 使用 NCNN 作为后端推理
  3. LFFDopen in new window LFFD 的模型及实现
  4. CCPDopen in new window 中国车牌数据集,达到 200 万样本
  5. HyperLPRopen in new window 一个开源的车牌识别框架