基于CRNN的中文车牌识别

1、概述

       目前HyperLRP是一个开源的、基于深度学习高性能中文车牌识别库,本文主要在其基础上进行改动,自己训练一个crnn车牌识别模型。

2、可识别的车牌类型

  •  单行蓝牌
  •  单行黄牌
  •  新能源车牌
  •  白色警用车牌
  •  使馆/港澳车牌
  •  教练车牌

3、可识别的车牌类型 

         此处我们有依旧采用HyperLPR的

  • cascade.xml 车牌检测模型 - 目前效果最好的cascade检测模型
    PlateDetection::PlateDetection(std::string filename_cascade)
    {
    	cascade.load(filename_cascade);
    };
    
    void PlateDetection::plateDetectionRough(cv::Mat InputImage, std::vector  &plateInfos, int min_w, int max_w) 
    {
    	cv::Mat processImage;
    	cv::cvtColor(InputImage, processImage, cv::COLOR_BGR2GRAY);
    	std::vector platesRegions;
    	cv::Size minSize(min_w, min_w / 4);
    	cv::Size maxSize(max_w, max_w / 4);
    	cascade.detectMultiScale(processImage, platesRegions, 1.1, 3, cv::CASCADE_SCALE_IMAGE, minSize, maxSize);
    	for (auto plate : platesRegions)
    	{
            //此处稍微调整了一下,放大车牌截图
    		int zeroadd_x = static_cast(plate.width * 0.1);
    		int zeroadd_y = static_cast(plate.height * 0.4);
    		int zeroadd_w = static_cast(plate.width * 0.2);
    		int zeroadd_h = static_cast(plate.height * 0.8);
    		plate.x -= zeroadd_x;
    		plate.y -= zeroadd_y;
    		plate.height += zeroadd_h;
    		plate.width += zeroadd_w;
    		cv::Mat plateImage = util::cropFromImage(InputImage, plate);
    		PlateInfo plateInfo(plateImage, plate);
    		plateInfos.push_back(plateInfo);
    	}
    }
  • crnn.onnx端到端的车牌识别模型

        车牌识别模型训练,参考https://gitee.com/ghangouc/crnn-pytorch.git

PlateRecognizer::PlateRecognizer(std::string filename_crnn)
{
	net = cv::dnn::readNet(filename_crnn);
	net.setPreferableBackend(cv::dnn::DNN_BACKEND_OPENCV);
	//net.setPreferableBackend(cv::dnn::DNN_BACKEND_INFERENCE_ENGINE);
	net.setPreferableTarget(cv::dnn::DNN_TARGET_CPU);
}

inline float PlateRecognizer::Sigmoid(float x, std::vector line_num)
{
	float sum = 0.f;
	for (int i = 0; i < line_num.size(); i++)
		sum += exp(line_num[i]);
	return static_cast(exp(x) / sum);
}

std::pair PlateRecognizer::getPlateName(cv::Mat &plateImg)
{
	cv::Mat srcImg = plateImg.clone();
	if (plateImg.channels() == 3) {
		cvtColor(plateImg, srcImg, CV_BGR2GRAY);
	}
	srcImg.convertTo(srcImg, CV_32F, 1.0 / 255);
	srcImg -= 0.5; srcImg /= 0.5;
	cv::Mat blob = cv::dnn::blobFromImage(srcImg);
	net.setInput(blob);
	cv::Mat res = net.forward();
	std::string plate, temp_C = "-";
	float confidence = 0.0;
	int length = 0;
	std::vector temp;
	for (int r = 0; r < res.size[0]; r++)
	{
		cv::Mat slice = cv::Mat(1, res.size[2], CV_32F, res.ptr(r));
		float *line = (float*)res.ptr(r);
		for (int i = 0; i < slice.size[1]; i++) {
			temp.push_back(line[i]);
		}
		cv::Point p; double m;
		cv::minMaxLoc(slice, 0, &m, 0, &p);
		std::string c = p.x > 0 ? alphabet[p.x - 1] : "-";
		if (c != "-")
		{
			if (temp_C != c) {
				plate += alphabet[p.x - 1];
			}
			length++;
			confidence += Sigmoid((float)m, temp);
		}
		temp_C = c;
		temp.clear();
	}
	std::pair plate_conf("none", 0.f);
	if (length > 0){
		plate_conf.first = plate;
		plate_conf.second = confidence / length;
	}
	return plate_conf;
}

4、检测结果

基于CRNN的中文车牌识别_第1张图片

基于CRNN的中文车牌识别_第2张图片

你可能感兴趣的:(智能交通,opencv,人工智能,c++)