opencv实现车牌识别之车牌号定位_2

简介

  前一篇讲解到了将用蓝色筛选后的图片,再一次灰阶/二值化。现在从这里继续讲解。

矩形检测

  因为车牌是一个矩形。所以接着将又一次二值化之后的图片,进行膨胀,之后在进行矩形检测。框选出可能是车牌号的矩形区域。
代码如下:
int** car_License_box(Mat& mat1, Mat& mat2, int* number){
	Mat threshold_output;
	vector<vector<Point> > contours;
	vector<Vec4i> hierarchy;
	Point s1, s2;
	int width_1, height_1;
	int width = mat1.rows;
	int height = mat1.cols;
	int sum = 0;

	int morph_elem = 3;
	int morph_size = 3;

	int** a = (int**)malloc(width * sizeof(int*));

	//腐蚀
	Mat element = getStructuringElement(MORPH_RECT, Size( 2*morph_size + 1, 2*morph_size+1 ), Point( -1, -1));
	dilate(mat1, mat1, element);

	/// 找到轮廓
	findContours(mat1, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );

	/// 多边形逼近轮廓 + 获取矩形和圆形边界框
	vector<vector<Point> > contours_poly( contours.size() );
	vector<Rect> boundRect( contours.size() );
	vector<Point2f>center( contours.size() );
	vector<float>radius( contours.size() );

	for( int i = 0; i < contours.size(); i++ )
	{ approxPolyDP( Mat(contours[i]), contours_poly[i], 3, true );
		boundRect[i] = boundingRect( Mat(contours_poly[i]) );
		minEnclosingCircle( contours_poly[i], center[i], radius[i] );
	}

	/// 画多边形轮廓 + 包围的矩形框 + 圆形框
	mat2 = Mat::zeros(mat1.size(), CV_8UC3 );
	for( int i = 0; i< contours.size(); i++ )
	{
		s1 = boundRect[i].tl();
		s2 = boundRect[i].br();
		height_1 = s2.x - s1.x;
		width_1 =  s2.y - s1.y;

		if((height_1 > (3 * width_1)) && (width_1 > (width / 2))){
			a[sum] = (int* )malloc(4 * sizeof(int));
			a[sum][0] = s1.x;
			a[sum][1] = s1.y;
			a[sum][2] = s2.x;
			a[sum][3] = s2.y;
			sum += 1;
		}
	}
	*number = sum;
	return a;
}

int main(int argc, char **argv){
     .............
            pic_gray(img_3, img_3);
            threshold = histogram_Calculate(img_3, 3);
            pic_Thresholding(img_3, threshold);

            address_1 = car_License_box(img_3, img_4, &address_Number_1);

            sprintf(str, "%d", i);
            namedWindow(str);
            imshow(str, img_3);
        }
    }
    waitKey(0);
    return 0;
}
  在函数car_License_box中,img_3为传入的源图像,然后检测出合适矩形,将矩形左上和右下那个角点保存在二维数组address_1中,检测到的矩形数量保存在
address_Number_1中。
  该函数的具体流程如下:1、使用dilate来进行图像的膨胀。
                          2、使用opencv教程中讲解过的轮廓寻找,并将检测到的矩形角点保存在boundRect中。
                          3、根据矩形左上和右下的角点,可以计算出矩形的宽与高。车牌所在的矩形应该长至少是宽的三倍。
                             同时在之前分割的图片中,车牌的宽度至少应该是这个分割图片的一半以上才正常。
                          4、将满足了要求的矩形角点保存在二维数组a中,并将矩形探测计数+1,最后返回对应保存的二维数组。

矩形分割

  上面矩形分割,已经将可能是车牌的矩形位置角点保存在了address_1中,这里我们根据address_1中的角点坐标,将对应的矩形从原图像中复制到新图像中显示:
void pic_cutting_1(Mat& mat1, Mat& mat2, Point s1, Point s2){
    int i, j;
    IplImage pI_1;
    IplImage pI_2;
    CvScalar s;

    mat2 = cv::Mat(s2.y - s1.y, s2.x - s1.x, CV_8UC3, 1);
    pI_1 = mat1;
    pI_2 = mat2;

    for(i = s1.y; i < s2.y; i++){
        for(j=s1.x; j<s2.x; j++){
            s = cvGet2D(&pI_1, i, j);
            cvSet2D(&pI_2, i-s1.y, j-s1.x, s);
        }
    }
}

int main(int argc, char** argv){
      .....................
            address_1 = car_License_box(img_3, img_4, &address_Number_1);

            for(j=0; j< address_Number_1; j++){

                DE("address_0:%d, %d, %d, %d\n", address_1[j][0], address_1[j][1], address_1[j][2], address_1[j][3]);
                s1.y = address_1[j][1] + selection_1[i][0];
                s1.x = address_1[j][0];
                s2.y = address_1[j][1] + selection_1[i][1];
                s2.x = address_1[j][2];
                DE("address:%d, %d, %d, %d\n", s1.x, s1.y, s2.x, s2.y);

                pic_cutting_1(img, img_5, s1, s2);

                sprintf(str, "%d", j);
                namedWindow(str);
                imshow(str, img_5);
            }
        }
    }
    namedWindow("img");
    imshow("img",img);
    waitKey(0);
    return 0;
}
  这一步很简单,效果显示如下:
                              

最后定位

  在上面的效果图片中,我们看到现在探测出了两个可能是车牌的矩形位置。继续做一次筛选判断来确定车牌真正所在的位置。
int box_selection(Mat& mat1){
    int width_1, height_1;
    int width = mat1.rows;
    int height = mat1.cols;
    int i, j;

    IplImage pI_1 = mat1;

    CvScalar s;
    int find_blue = 0;
    int blueToWhite = 0;
    int sum =0;

    for(i=0; i<width; i++){
        find_blue = 0;
        blueToWhite = 0;
        for(j=0; j<height; j++){
            s = cvGet2D(&pI_1, i, j);
            if((s.val[0] - s.val[1] > 10) && (s.val[0] - s.val[2] > 10) && (s.val[1] < 150) && (s.val[2] < 150)){
                find_blue = 1;
            }
            else if((s.val[1] > 150) && (s.val[2] > 150) && (s.val[0] > 150) && (find_blue == 1)){
                blueToWhite += 1;
                find_blue = 0;
            }
        }
        if(blueToWhite > 5){
            sum += 1;
        }
    }
    return sum;
}

int main(int argc, char **argv){
  ............
   for(j=0; j< address_Number_1; j++){

                DE("address_0:%d, %d, %d, %d\n", address_1[j][0], address_1[j][1], address_1[j][2], address_1[j][3]);
                s1.y = address_1[j][1] + selection_1[i][0];
                s1.x = address_1[j][0];
                s2.y = address_1[j][1] + selection_1[i][1];
                s2.x = address_1[j][2];
                DE("address:%d, %d, %d, %d\n", s1.x, s1.y, s2.x, s2.y);

                pic_cutting_1(img, img_5, s1, s2);
                box_flag = box_selection(img_5);
                DE("box_flag:%d\n", box_flag);

                if(box_flag > 5){
                    rectangle(img, s1, s2, color, 2, 8, 0 );
                    sprintf(str, "%d", j);
                    namedWindow(str);
                    imshow(str, img_5);
                }
            }
        }
    }
    namedWindow("img");
    imshow("img",img);
    waitKey(0);
    return 0;
}
  因为车牌号是蓝底白字,同时会交替出现7次。所以在box_selection,我们在蓝色之后,跳变到白色的次数至少大于五次,表示该矩形位置是框选了车牌。
来排除掉其他的矩形,最后将确定的车牌位置新图像显示出来,同时在原图像车牌的位置画上黄色方框。
  进而最后的效果演示如下:
                                

注意

  该方法的准确率并不太高。如可能出现如下情况:
                                
   代码下载如下:http://download.csdn.net/detail/u011630458/8431445
时间: 2024-12-24 06:24:03

opencv实现车牌识别之车牌号定位_2的相关文章

opencv实现车牌识别之车牌号定位_1

简介 按照在哪里跌倒就在哪里爬起来的精神,本章继续做车牌号的检测识别.所有步骤分为3步完成:车牌号定位,车牌号字符分割.字符识别. 本章为第一部分:车牌号定位. 效果演示 正式开始讲解之前,先看下车牌号定位出来的效果演示.注:本文所有图片均来源于网络. 如图所示,定位到车牌号之后,将车牌号用黄色框选起来,同时将该车牌复制为新图片显示出来. 代码及实现原理讲解 图像灰阶/二值化 首先也是常用的操作,将图像灰阶化,然后从像素值为255一侧开始,以累积像素占总像素5%的的地方作为二值化的阀值,进而获得

opencv实现车牌识别之字符识别

简介 在前面已经讲了车牌的定位和对车牌字符的分割,这里继续是最后对车牌的识别. 字符识别 主要是用了两张办法,第一个是前面 <opencv实现车牌识别之失败经验> 这一篇中用到过的,opencv自带的getPSNR函数,这里不再对它进行讲解. 另一种方法是将分割出来的字符和模板字符都分割成9宫格形式,对比比较每个块中,像素占的比例来匹配分辨出字符. 具体代码如下: double proCale(Mat& mat1, int width_1, int height_1, int widt

opencv实现车牌识别之字符分割

简介 在前一篇中,我们已经定位出来了在图片中车牌号的位置,并且将车牌号图片复制成了新图片,并显示出来,本章在这些被截取出来的图片上继续处理. 截取出来的新图片如下: 图像灰阶/二值化 首先也是选择将图像进行灰阶,然后采用以255一遍开始,取占了总pixel为5%的地方作为阀值,进行二值化. 代码如下: #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <math.h

基于opencv的车牌识别系统

前言 学习了很长一段时间了,需要沉淀下,而最好的办法就是做一个东西来应用学习的东西,同时也是一个学习的过程. 概述     OpenCV的全称是:Open Source Computer Vision Library.OpenCV是一个基于(开源)发行的跨平台计算机视觉库,可以运行在Linux.Windows和Mac OS操作系统上.它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python.Ruby.MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算

毕业设计 python opencv实现车牌识别 界面

主要代码参考https://blog.csdn.net/wzh191920/article/details/79589506 GitHub:https://github.com/yinghualuowu 答辩通过了,补完~ 这里主要是用两种方法进行定位识别 # -*- coding: utf-8 -*- __author__ = '樱花落舞' import tkinter as tk from tkinter.filedialog import * from tkinter import ttk

CNN:人工智能之神经网络算法进阶优化,六种不同优化算法实现手写数字识别逐步提高,应用案例自动驾驶之捕捉并识别周围车牌号—Jason niu

import mnist_loader from network3 import Network from network3 import ConvPoolLayer, FullyConnectedLayer, SoftmaxLayer training_data, validation_data, test_data = mnist_loader.load_data_wrapper() mini_batch_size = 10 #NN算法:sigmoid函数:准确率97% net = Netw

毕业设计 python opencv实现车牌识别 颜色判断

主要代码参考https://blog.csdn.net/wzh191920/article/details/79589506 GitHub:https://github.com/yinghualuowu 答辩通过了,补完~ 该部分代码还包括缩小边界 def img_color(card_imgs): colors = [] for card_index, card_img in enumerate(card_imgs): green = yello = blue = black = white

毕业设计 python opencv实现车牌识别 矩形矫正

主要代码参考https://blog.csdn.net/wzh191920/article/details/79589506 GitHub:https://github.com/yinghualuowu 答辩通过了,补完~ 用的是仿射变换 def img_Transform(car_contours,oldimg,pic_width,pic_hight): car_imgs = [] for car_rect in car_contours: if car_rect[2] > -1 and ca

文通Android平台车牌识别SDK

关键词: Android平台,车牌识别.车牌号识别.汽车牌照识别. 产品描述 文通车牌识别系统是北京文通科技有限公司开发的基于移动平台的车牌识别应用程序,支持Android等多种主流移动操作系统.该产品采用手机.平板电脑摄像头拍摄汽车牌照图像,然后通过OCR软件对车牌颜色.车牌号进行识别. 产品特色 整牌识别率高,尤其汉字识别遥遥领先同类产品: 识别速度快,极致优化的车牌定位和识别算法: 支持牌照全,包括蓝牌.黄牌(双).军牌(双).武警牌(双).警牌.农用车牌.教练车牌.大使馆车牌等各种规格牌