zoukankan      html  css  js  c++  java
  • 基于opencv的车牌识别系统

    前言

    学习了很长一段时间了,需要沉淀下,而最好的办法就是做一个东西来应用学习的东西,同时也是一个学习的过程。

    PS:这篇小文是毕业之前和同学做的一个小项目,所以写的比较匆忙,代码也是直接粘贴的,基于qt开发的C++代码,不能保证没有错误,请慎重。不希望对你产生误导,有任何问题可以联系我,一起探讨下。最后,我现在已经没有搞嵌入式方面的开发了。

    概述    

    OpenCV的全称是:Open Source Computer Vision Library。OpenCV是一个基于(开源)发行的跨平台计算机视觉库,可以运行在Linux、Windows和Mac OS操作系统上。它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。

    来自百度的解释,之所以选择opencv是因为:首先向学习一个新的东西来看看自己的学习接受能力,然后是感觉opencv很酷,处理图片真实说一不二的(你可以理解为处理图片很方便)。

    车牌识别系统重点在于车牌的识别,还有后台的处理。要使它成为一个系统,缺一不可。

    大致上分为三个部分:信息采集和传输,接收图片并识别客户端请求,信息的存储和查询


    1.信息采集和传输

    这里我们采用的是 网上买的小摄像头+网上的开源项目mjpg-stream

    对于mjpg-stream的使用,网上已经有很多博客了,你可以找到很多。

    mjpg-stream 不仅能调用摄像头拍摄照片还可以作为服务器发送图片数据,所以我这里直接使用它作为服务器发送给我自己写的客户端数据。

    2.接收图片并进行图片识别和显示

    这里就需要用到opencv来进行处理了。

    大致上车牌识别分为:车牌提取,字符提取,字符识别

    车牌提取:需要调用opencv里面图片处理的几个函数接口:

    灰度处理-》竖向边缘检测(因为车牌大部分竖向的)-》二值化处理-》形态学处理-》车牌截取

     1 string read_plate(string path)
     2 {
     3      /*加载图片*/
     4      const char* imagename = path.c_str();
     5      IplImage * img = cvLoadImage(imagename);
     6      if(!img)
     7      {
     8             exit(1);
     9      }
    10     
    11      if( !img->imageData ) // 检查是否正确载入图像
    12            exit(1);
    13     
    14      cvNamedWindow("image", CV_WINDOW_AUTOSIZE); //创建窗口
    15     // cvShowImage("image", img); //显示图像
    16     /*灰度化处理*/
    17      IplImage* img1 = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);//创建目标图像
    18      cvCvtColor(img,img1,CV_BGR2GRAY);//cvCvtColor(src,des,CV_BGR2GRAY)
    19      cvNamedWindow("gray_image",CV_WINDOW_AUTOSIZE);//创建显示目标的窗口
    20     
    21     // cvShowImage("gray_image",img1);//显示灰度图像
    22     /*滤波处理*/
    23      IplImage* temp = cvCreateImage(cvGetSize(img1), IPL_DEPTH_8U, 1);//创建目标图像
    24      cvSmooth(img1,temp,CV_GAUSSIAN,1,1);//高斯模糊
    25     // cvShowImage("guolv_image",temp);//显示过滤图
    26      
    27      /*竖向边缘检测  竖向只是参数的改变*/
    28      IplImage * sobel=cvCreateImage(cvGetSize(temp),IPL_DEPTH_16S,1);
    29      IplImage *sobelimg=cvCreateImage(cvGetSize(temp),IPL_DEPTH_8U,1);
    30      cvSobel(temp,sobel,2,0,7);
    31      cvConvertScaleAbs(sobel,sobelimg, 0.00390625,0);
    32     // cvShowImage("灰度图像Sobel变换",sobelimg);
    33     
    34     /*二值化处理*/
    35      IplImage *two=cvCreateImage(cvGetSize(temp),IPL_DEPTH_8U,1);
    36      cvThreshold(sobelimg, two, 0, 255, CV_THRESH_BINARY| CV_THRESH_OTSU);
    37     // cvShowImage("two",two);
    38      
    39      /*形态学处理  腐蚀膨胀*/
    40      IplImage *closeimg=cvCreateImage(cvGetSize(temp),IPL_DEPTH_8U,1);
    41      IplConvKernel* kernal=cvCreateStructuringElementEx(3,1, 1, 0, CV_SHAPE_RECT);
    42      cvDilate(two, closeimg, kernal, 6);
    43      cvErode(closeimg, closeimg, kernal, 4);
    44      cvDilate(closeimg, closeimg, kernal, 2);
    45      kernal = cvCreateStructuringElementEx(1, 3, 0, 1, CV_SHAPE_RECT);
    46      cvErode(closeimg, closeimg, kernal, 4);
    47      cvDilate(closeimg, closeimg, kernal, 2);
    48      //cvShowImage("closeimg",closeimg);
    49      
    50      /*筛选最大的那块矩形*/
    51      IplImage* copy = cvCloneImage(closeimg);
    52      IplImage* dst  =   cvCloneImage(img);
    53      CvMemStorage* storage = cvCreateMemStorage();
    54      CvSeq* contours;
    55      CvRect rect,max;
    56      int count=0;
    57      double wide=0,height=0;
    58       count= cvFindContours (copy, storage, &contours, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
    59       for (;contours != NULL; contours = contours->h_next)
    60       {
    61            rect = cvBoundingRect(contours);
    62            if(rect.width > (rect.height*2))
    63            {
    64                if(rect.height>height && rect.width>wide)
    65                {
    66                     max = rect;
    67                     height = rect.height;
    68                     wide = rect.width;
    69     
    70                }
    71            }
    72       }
    73       cvSetImageROI(dst,cvRect(max.x+11,max.y+2,max.width-16,max.height-2));
    74       cvShowImage("choose",dst);     
    75         
    76 }
    plate shot

    代码中对截取车牌进行了操作

    下面是字符的识别:字符识别有很多方法,但是都是算法的,我研究的不是很深,选取了最简单的一种,自己做字符库,然后比对。

      1 //车牌识别
      2 #include "char.h"
      3 
      4 //中文字模   注意绝对路径= =
      5 const char *mb_ku_zw[31] = {
      6     "/home/panhao/QtProject/MyANPR/char_img/zw1.bmp","/home/panhao/QtProject/MyANPR/char_img/zw2.bmp","/home/panhao/QtProject/MyANPR/char_img/zw3.bmp",
      7     "/home/panhao/QtProject/MyANPR/char_img/zw4.bmp","/home/panhao/QtProject/MyANPR/char_img/zw5.bmp",
      8     "/home/panhao/QtProject/MyANPR/char_img/zw6.bmp","/home/panhao/QtProject/MyANPR/char_img/zw7.bmp","/home/panhao/QtProject/MyANPR/char_img/zw8.bmp",
      9     "/home/panhao/QtProject/MyANPR/char_img/zw9.bmp","/home/panhao/QtProject/MyANPR/char_img/zw10.bmp","/home/panhao/QtProject/MyANPR/char_img/zw11.bmp",
     10     "/home/panhao/QtProject/MyANPR/char_img/zw12.bmp","/home/panhao/QtProject/MyANPR/char_img/zw13.bmp","/home/panhao/QtProject/MyANPR/char_img/zw14.bmp",
     11     "/home/panhao/QtProject/MyANPR/char_img/zw15.bmp","/home/panhao/QtProject/MyANPR/char_img/zw16.bmp","/home/panhao/QtProject/MyANPR/char_img/zw17.bmp",
     12     "/home/panhao/QtProject/MyANPR/char_img/zw18.bmp","/home/panhao/QtProject/MyANPR/char_img/zw19.bmp","/home/panhao/QtProject/MyANPR/char_img/zw20.bmp",
     13     "/home/panhao/QtProject/MyANPR/char_img/zw21.bmp","/home/panhao/QtProject/MyANPR/char_img/zw22.bmp","/home/panhao/QtProject/MyANPR/char_img/zw23.bmp",
     14     "/home/panhao/QtProject/MyANPR/char_img/zw24.bmp","/home/panhao/QtProject/MyANPR/char_img/zw25.bmp","/home/panhao/QtProject/MyANPR/char_img/zw26.bmp",
     15     "/home/panhao/QtProject/MyANPR/char_img/zw27.bmp","/home/panhao/QtProject/MyANPR/char_img/zw28.bmp","/home/panhao/QtProject/MyANPR/char_img/zw29.bmp",
     16     "/home/panhao/QtProject/MyANPR/char_img/zw30.bmp","/home/panhao/QtProject/MyANPR/char_img/zw31.bmp",
     17 };
     18 const char *mb_ku_zf[24] ={
     19     "/home/panhao/QtProject/MyANPR/char_img/A.bmp","/home/panhao/QtProject/MyANPR/char_img/B.bmp",
     20     "/home/panhao/QtProject/MyANPR/char_img/C.bmp","/home/panhao/QtProject/MyANPR/char_img/D.bmp",
     21     "/home/panhao/QtProject/MyANPR/char_img/E.bmp","/home/panhao/QtProject/MyANPR/char_img/F.bmp",
     22     "/home/panhao/QtProject/MyANPR/char_img/G.bmp","/home/panhao/QtProject/MyANPR/char_img/H.bmp",
     23     "/home/panhao/QtProject/MyANPR/char_img/J.bmp","/home/panhao/QtProject/MyANPR/char_img/K.bmp",
     24     "/home/panhao/QtProject/MyANPR/char_img/L.bmp","/home/panhao/QtProject/MyANPR/char_img/M.bmp",
     25     "/home/panhao/QtProject/MyANPR/char_img/N.bmp","/home/panhao/QtProject/MyANPR/char_img/P.bmp",
     26     "/home/panhao/QtProject/MyANPR/char_img/Q.bmp","/home/panhao/QtProject/MyANPR/char_img/R.bmp",
     27     "/home/panhao/QtProject/MyANPR/char_img/S.bmp","/home/panhao/QtProject/MyANPR/char_img/T.bmp",
     28     "/home/panhao/QtProject/MyANPR/char_img/U.bmp","/home/panhao/QtProject/MyANPR/char_img/V.bmp",
     29     "/home/panhao/QtProject/MyANPR/char_img/W.bmp","/home/panhao/QtProject/MyANPR/char_img/X.bmp",
     30     "/home/panhao/QtProject/MyANPR/char_img/Y.bmp","/home/panhao/QtProject/MyANPR/char_img/Z.bmp",
     31 };
     32 const char *mb_ku_sz[10] ={
     33     "/home/panhao/QtProject/MyANPR/char_img/0.bmp","/home/panhao/QtProject/MyANPR/char_img/1.bmp","/home/panhao/QtProject/MyANPR/char_img/2.bmp",
     34     "/home/panhao/QtProject/MyANPR/char_img/3.bmp","/home/panhao/QtProject/MyANPR/char_img/4.bmp","/home/panhao/QtProject/MyANPR/char_img/5.bmp",
     35     "/home/panhao/QtProject/MyANPR/char_img/6.bmp","/home/panhao/QtProject/MyANPR/char_img/7.bmp","/home/panhao/QtProject/MyANPR/char_img/8.bmp",
     36     "/home/panhao/QtProject/MyANPR/char_img/9.bmp",
     37 };
     38 const char *mb_ku_sf[34] = {
     39     "/home/panhao/QtProject/MyANPR/char_img/0.bmp","/home/panhao/QtProject/MyANPR/char_img/1.bmp","/home/panhao/QtProject/MyANPR/char_img/2.bmp",
     40     "/home/panhao/QtProject/MyANPR/char_img/3.bmp","/home/panhao/QtProject/MyANPR/char_img/4.bmp","/home/panhao/QtProject/MyANPR/char_img/5.bmp",
     41     "/home/panhao/QtProject/MyANPR/char_img/6.bmp","/home/panhao/QtProject/MyANPR/char_img/7.bmp","/home/panhao/QtProject/MyANPR/char_img/8.bmp",
     42     "/home/panhao/QtProject/MyANPR/char_img/9.bmp","/home/panhao/QtProject/MyANPR/char_img/A.bmp","/home/panhao/QtProject/MyANPR/char_img/B.bmp",
     43     "/home/panhao/QtProject/MyANPR/char_img/C.bmp","/home/panhao/QtProject/MyANPR/char_img/D.bmp","/home/panhao/QtProject/MyANPR/char_img/E.bmp",
     44     "/home/panhao/QtProject/MyANPR/char_img/F.bmp","/home/panhao/QtProject/MyANPR/char_img/G.bmp","/home/panhao/QtProject/MyANPR/char_img/H.bmp",
     45     "/home/panhao/QtProject/MyANPR/char_img/J.bmp","/home/panhao/QtProject/MyANPR/char_img/K.bmp","/home/panhao/QtProject/MyANPR/char_img/L.bmp",
     46     "/home/panhao/QtProject/MyANPR/char_img/M.bmp","/home/panhao/QtProject/MyANPR/char_img/N.bmp","/home/panhao/QtProject/MyANPR/char_img/P.bmp",
     47     "/home/panhao/QtProject/MyANPR/char_img/Q.bmp","/home/panhao/QtProject/MyANPR/char_img/R.bmp","/home/panhao/QtProject/MyANPR/char_img/S.bmp",
     48     "/home/panhao/QtProject/MyANPR/char_img/T.bmp","/home/panhao/QtProject/MyANPR/char_img/U.bmp","/home/panhao/QtProject/MyANPR/char_img/V.bmp",
     49     "/home/panhao/QtProject/MyANPR/char_img/W.bmp","/home/panhao/QtProject/MyANPR/char_img/X.bmp","/home/panhao/QtProject/MyANPR/char_img/Y.bmp",
     50     "/home/panhao/QtProject/MyANPR/char_img/Z.bmp",
     51 
     52 };
     53 
     54 string shibie(char *imgpath)
     55 {
     56     IplImage *pSrcImage = cvLoadImage(imgpath, 1);       //定位后车牌路径
     57     IplImage *pGrayImage = NULL;
     58     IplImage *pBinaryImage = NULL;
     59     IplImage *ty_cpimg = NULL;
     60     // 转为灰度图
     61     pGrayImage =  cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1);
     62     cvCvtColor(pSrcImage, pGrayImage, CV_BGR2GRAY);
     63     // 创建二值图
     64     pBinaryImage = cvCreateImage(cvGetSize(pGrayImage), IPL_DEPTH_8U, 1);
     65     //转为二值图,自适二值化CV_THRESH_OTSU
     66     cvThreshold(pGrayImage, pBinaryImage, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);
     67 
     68     cvNamedWindow("input",1);
     69     cvShowImage("input",pBinaryImage);
     70 
     71     //识别铆钉
     72     const int height_md_yz = pBinaryImage->height / 10;        //y轴方向的阈值
     73     const int width_md_yz  = pBinaryImage->width;              //x轴方向的阈值
     74     IplImage* cyp = cvCloneImage( pBinaryImage );
     75     int width_md = 0;
     76     int height_md  = 0;
     77     int count_bd = 0;
     78     uchar count_bd_str[width_md_yz];
     79     for(count_bd = 0; count_bd < width_md_yz; count_bd++)
     80         count_bd_str[count_bd] = 0;
     81     uchar *pt = (uchar *)cyp->imageData;
     82     const uchar step = cyp->widthStep;
     83 
     84     //扫描白点并记录
     85     for(width_md  = 0 ; width_md < width_md_yz; width_md++)
     86     {
     87         for(height_md = 0 ; height_md < height_md_yz; height_md++)
     88         {
     89             if(pt[height_md*step + width_md])
     90                 count_bd_str[width_md]++;
     91         }
     92     }
     93 
     94 
     95     int width_bf   = 0;
     96     int width_ls   = 0;
     97     for(width_md  = 0 ; width_md < width_md_yz; width_md++)
     98     {
     99         if(count_bd_str[width_md] > height_md_yz/2)
    100             if(width_md < width_md_yz-1)
    101                 if(count_bd_str[++width_md]> height_md_yz/2)
    102                 {
    103                     if(!width_bf)
    104                     {
    105                         if(width_md > width_md_yz*0.2)
    106                             width_bf = width_md;
    107                     }
    108                     else if(width_md - width_bf > width_md_yz/3)
    109                     {
    110                         if(width_md > width_md_yz*0.6)
    111                             width_ls = width_md;
    112                     }
    113                 }
    114     }
    115     //如果判断是柳钉则使用柳钉计算比例定位
    116     if(width_md_yz*0.4 < (width_ls - width_bf) && (width_ls - width_bf) < width_md_yz*0.6)
    117     {
    118         float img_bl = ((float)(width_ls - width_bf))/220;
    119         int width_left_new = width_bf - (int)(img_bl*78);
    120         int width_right_new = width_ls + (int)(img_bl*78);
    121         if(width_left_new<0)width_left_new=0;
    122         if(width_right_new>pBinaryImage->width)width_right_new=pBinaryImage->width;
    123         int height_top_new = 0;
    124         int height_down_new = pBinaryImage->height;
    125         const uchar height_yz_x = pBinaryImage->height/5;
    126         uchar count_bd_x_str[height_yz_x];
    127         for(count_bd = 0; count_bd < height_yz_x; count_bd++)             //数组清零
    128             count_bd_x_str[count_bd] = 0;
    129         for(int height_ydw = 0; height_ydw < height_yz_x; height_ydw++)
    130         {
    131             for(width_md  = 0 ; width_md < width_md_yz; width_md++)
    132             {
    133                 if(pt[height_ydw*step + width_md])
    134                     count_bd_x_str[height_ydw]++;
    135             }
    136         }
    137         for(int height_ydw = 0; height_ydw < height_yz_x; height_ydw++)
    138         {
    139             if(count_bd_x_str[height_ydw] < (int)(pBinaryImage->width*25/100))    //切割条件->白点个数 阈值
    140                 height_top_new = height_ydw;
    141         }
    142 
    143         for(count_bd = 0; count_bd < height_yz_x; count_bd++)
    144             count_bd_x_str[count_bd] = 0;
    145         for(int height_ydw = 0; height_ydw < height_yz_x; height_ydw++)
    146         {
    147             for(width_md  = 0 ; width_md < width_md_yz; width_md++)
    148             {
    149                 if(pt[(pBinaryImage->height - height_ydw)*step + width_md])
    150                     count_bd_x_str[height_ydw]++;
    151             }
    152         }
    153         for(int height_ydw = 0; height_ydw < height_yz_x; height_ydw++)
    154         {
    155             if(count_bd_x_str[height_ydw] < (int)(pBinaryImage->width*25/100))
    156                 height_down_new = pBinaryImage->height - height_ydw;
    157         }
    158 
    159         IplImage* cyp_ptx = cvCloneImage( pBinaryImage );
    160         CvRect ptx;
    161         ptx.x = width_left_new;
    162         ptx.y = height_top_new;
    163         ptx.height = height_down_new - height_top_new;
    164         ptx.width  = width_right_new - width_left_new;
    165         cvSetImageROI(cyp_ptx, ptx);
    166         cvSaveImage("/home/panhao/QtProject/MyANPR/img/cyp_ptx.jpg", cyp_ptx);
    167         ty_cpimg = cvCloneImage(cyp_ptx);
    168         cvResetImageROI(cyp_ptx);
    169     }
    170     //如果无法识别铆钉,那就先投影切割后按比例切割字符
    171     else
    172     {
    173         int width_left_new_y = 0;
    174         int width_right_new_y = pBinaryImage->width;
    175         int height_top_new_y = 0;
    176         int height_down_new_y = pBinaryImage->height;
    177         const uchar height_yz_y = pBinaryImage->height/5;
    178         const uchar width_yz_y = pBinaryImage->width/16;    //阈值 请修改
    179         uchar width_bd_ptr_y[width_yz_y];
    180         uchar height_bd_ptr_y[height_yz_y];
    181         for(count_bd = 0; count_bd < width_yz_y; count_bd++)
    182             width_bd_ptr_y[count_bd] = 0;
    183         for(count_bd = 0; count_bd < height_yz_y; count_bd++)
    184             height_bd_ptr_y[count_bd] = 0;
    185         for(int width_yd_y = 0; width_yd_y < width_yz_y; width_yd_y++)
    186             for(int height_yd_y = 0; height_yd_y < pBinaryImage->height; height_yd_y++)
    187             {
    188                 if(pt[height_yd_y*step + width_yd_y])
    189                     width_bd_ptr_y[width_yd_y]++;
    190             }
    191         for(int width_yd_y = 0; width_yd_y < width_yz_y; width_yd_y++)
    192         {
    193             if(width_bd_ptr_y[width_yd_y] < (int)(pBinaryImage->height*2/10))
    194                 width_left_new_y = width_yd_y;
    195 //            int x = width_bd_ptr_y[width_yd_y];
    196         }
    197         for(count_bd = 0; count_bd < width_yz_y; count_bd++)
    198             width_bd_ptr_y[count_bd] = 0;
    199         for(int width_yd_y = 0; width_yd_y < width_yz_y; width_yd_y++)
    200             for(int height_yd_y = 0; height_yd_y < pBinaryImage->height; height_yd_y++)
    201             {
    202                 if(pt[height_yd_y*step + pBinaryImage->width - width_yd_y])
    203                     width_bd_ptr_y[width_yd_y]++;
    204             }
    205         for(int width_yd_y = 0; width_yd_y < width_yz_y; width_yd_y++)
    206         {
    207             if(width_bd_ptr_y[width_yd_y] < (int)(pBinaryImage->height*2/10))
    208                 width_right_new_y =pBinaryImage->width - width_yd_y;
    209         }
    210 
    211         for(int height_yd_y = 0; height_yd_y < height_yz_y; height_yd_y++)
    212             for(int width_yd_y = 0; width_yd_y < pBinaryImage->width; width_yd_y++)
    213             {
    214                 if(pt[height_yd_y*step + width_yd_y])
    215                     height_bd_ptr_y[height_yd_y]++;
    216             }
    217         for(int height_yd_y = 0; height_yd_y < height_yz_y; height_yd_y++)
    218         {
    219             if(height_bd_ptr_y[height_yd_y] < (int)(pBinaryImage->width*18/100))
    220                 height_top_new_y = height_yd_y;
    221         }
    222         for(count_bd = 0; count_bd < height_yz_y; count_bd++)
    223             height_bd_ptr_y[count_bd] = 0;
    224         for(int height_yd_y = 0; height_yd_y < height_yz_y; height_yd_y++)
    225             for(int width_yd_y = 0; width_yd_y < pBinaryImage->width; width_yd_y++)
    226             {
    227                 if(pt[(pBinaryImage->height - height_yd_y)*step + width_yd_y])
    228                     height_bd_ptr_y[height_yd_y]++;
    229             }
    230         for(int height_yd_y = 0; height_yd_y < height_yz_y; height_yd_y++)
    231         {
    232             if(height_bd_ptr_y[height_yd_y] < (int)(pBinaryImage->width*18/100))    //上下切
    233                 height_down_new_y = pBinaryImage->height - height_yd_y;
    234         }
    235         IplImage* cyp_ptx = cvCloneImage( pBinaryImage );
    236         CvRect ptx;
    237         ptx.x = width_left_new_y;
    238         ptx.y = height_top_new_y;
    239         ptx.height = height_down_new_y - height_top_new_y;
    240         ptx.width  = width_right_new_y - width_left_new_y;
    241         cvSetImageROI(cyp_ptx, ptx);
    242         cvSaveImage("/home/panhao/QtProject/MyANPR/img/cyp_ptx_y.jpg", cyp_ptx);        //保存查看投影切割的结果
    243         ty_cpimg = cvCloneImage(cyp_ptx);
    244         cvResetImageROI(cyp_ptx);
    245     }
    246 
    247     //图片统一尺寸180x40  开始字符切割(字符切割使用的是最最简单的按比例切割,效果不是很理想,如果要高识别率,需要对字符进行上下左右的投影切割,然后再进行归一化,这样可以提高识别率)
    248     IplImage *img_ty = NULL;
    249     CvSize dst_cvsize;
    250     dst_cvsize.height = 40;
    251     dst_cvsize.width = 180;
    252     img_ty = cvCreateImage(dst_cvsize, ty_cpimg->depth, ty_cpimg->nChannels);
    253     cvResize(ty_cpimg, img_ty, CV_INTER_LINEAR);         //二线性插值法会出现灰度
    254     ty_cpimg = cvCloneImage( img_ty );
    255     cvThreshold(ty_cpimg, img_ty, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);   //再次二值化
    256     cvSaveImage("/home/panhao/QtProject/MyANPR/img/img_ty.jpg", img_ty);
    257     dst_cvsize.height = 40;
    258     dst_cvsize.width = 20;
    259     IplImage *pic1 = cvCreateImage(dst_cvsize, img_ty->depth, img_ty->nChannels);
    260     IplImage *pic2 = cvCreateImage(dst_cvsize, img_ty->depth, img_ty->nChannels);
    261     IplImage *pic3 = cvCreateImage(dst_cvsize, img_ty->depth, img_ty->nChannels);
    262     IplImage *pic4 = cvCreateImage(dst_cvsize, img_ty->depth, img_ty->nChannels);
    263     IplImage *pic5 = cvCreateImage(dst_cvsize, img_ty->depth, img_ty->nChannels);
    264     IplImage *pic6 = cvCreateImage(dst_cvsize, img_ty->depth, img_ty->nChannels);
    265     IplImage *pic7 = cvCreateImage(dst_cvsize, img_ty->depth, img_ty->nChannels);
    266     IplImage* copy_zf = NULL;
    267     copy_zf = cvCloneImage( img_ty );
    268     CvRect ptx;
    269     ptx.x = 0;
    270     ptx.y = 0;
    271     ptx.height = 40;
    272     ptx.width  = 20;
    273     cvSetImageROI(copy_zf, ptx);
    274     cvCopy(copy_zf, pic1);
    275     cvSaveImage("/home/panhao/QtProject/MyANPR/img/copy_zf1.jpg", pic1);                        //注意绝对路径 出错请debug
    276     pic1 = cvLoadImage("/home/panhao/QtProject/MyANPR/img/copy_zf1.jpg", 1);                    //注意 这两句必须要,否则后面结果就不对
    277 
    278 
    279     copy_zf = cvCloneImage( img_ty );
    280     ptx.x = 20+6;
    281     ptx.y = 0;
    282     ptx.height = 40;
    283     ptx.width  = 20;
    284     cvSetImageROI(copy_zf, ptx);
    285     cvCopy(copy_zf, pic2);
    286     cvSaveImage("/home/panhao/QtProject/MyANPR/img/copy_zf2.jpg", pic2);
    287     pic2 = cvLoadImage("/home/panhao/QtProject/MyANPR/img/copy_zf2.jpg", 1);
    288 
    289 
    290     copy_zf = cvCloneImage( img_ty );
    291     ptx.x = 20+6+20+15;
    292     ptx.y = 0;
    293     ptx.height = 40;
    294     ptx.width  = 20;
    295     cvSetImageROI(copy_zf, ptx);
    296     cvCopy(copy_zf, pic3);
    297     cvSaveImage("/home/panhao/QtProject/MyANPR/img/copy_zf3.jpg", pic3);
    298     pic3 = cvLoadImage("/home/panhao/QtProject/MyANPR/img/copy_zf3.jpg", 1);
    299 
    300 
    301     copy_zf = cvCloneImage( img_ty );
    302     ptx.x = 20+6+20+15+20+4;
    303     ptx.y = 0;
    304     ptx.height = 40;
    305     ptx.width  = 20;
    306     cvSetImageROI(copy_zf, ptx);
    307     cvCopy(copy_zf, pic4);
    308     cvSaveImage("/home/panhao/QtProject/MyANPR/img/copy_zf4.jpg", pic4);
    309     pic4 = cvLoadImage("/home/panhao/QtProject/MyANPR/img/copy_zf4.jpg", 1);
    310 
    311 
    312     copy_zf = cvCloneImage( img_ty );
    313     ptx.x = 20+6+20+15+20+6+20+4;
    314     ptx.y = 0;
    315     ptx.height = 40;
    316     ptx.width  = 20;
    317     cvSetImageROI(copy_zf, ptx);
    318     cvCopy(copy_zf, pic5);
    319     cvSaveImage("/home/panhao/QtProject/MyANPR/img/copy_zf5.jpg", pic5);
    320     pic5 = cvLoadImage("/home/panhao/QtProject/MyANPR/img/copy_zf5.jpg", 1);
    321 
    322 
    323     copy_zf = cvCloneImage( img_ty );
    324     ptx.x = 20+6+20+15+20+6+20+6+20+2;
    325     ptx.y = 0;
    326     ptx.height = 40;
    327     ptx.width  = 20;
    328     cvSetImageROI(copy_zf, ptx);
    329     cvCopy(copy_zf, pic6);
    330     cvSaveImage("/home/panhao/QtProject/MyANPR/img/copy_zf6.jpg", pic6);
    331     pic6 = cvLoadImage("/home/panhao/QtProject/MyANPR/img/copy_zf6.jpg", 1);
    332 
    333 
    334     copy_zf = cvCloneImage( img_ty );
    335     ptx.x = 20+6+20+15+20+6+20+6+20+6+20+1;
    336     ptx.y = 0;
    337     ptx.height = 40;
    338     ptx.width  = 20;
    339     cvSetImageROI(copy_zf, ptx);
    340     cvCopy(copy_zf, pic7);
    341     cvSaveImage("/home/panhao/QtProject/MyANPR/img/copy_zf7.jpg", pic7);
    342     pic7 = cvLoadImage("/home/panhao/QtProject/MyANPR/img/copy_zf7.jpg", 1);
    343 
    344 
    345 
    346     //字符识别(使用模版逐点比对式,相似点*100/总点数=成功率)
    347     string wz_1 = db_successlv_1(pic1);                     //车牌第一个字符   以下以此类推   做返回值string中若有中文会有乱码
    348     string wz_2 = db_successlv_2(pic2);
    349     string wz_3 = db_successlv_3(pic3);
    350     string wz_4 = db_successlv_3(pic4);
    351     string wz_5 = db_successlv_4_7(pic5);
    352     string wz_6 = db_successlv_4_7(pic6);
    353     string wz_7 = db_successlv_4_7(pic7);
    354     string finish = wz_1 + wz_2 + wz_3 + wz_4 + wz_5 + wz_6 + wz_7;    //最后结果
    355     //cout << "finish:"<<finish << endl;
    356     //printf("endl
    ");
    357 
    358 
    359     cvReleaseImage(&pic1);
    360     cvReleaseImage(&pic2);
    361     cvReleaseImage(&pic3);
    362     cvReleaseImage(&pic4);
    363     cvReleaseImage(&pic5);
    364     cvReleaseImage(&pic6);
    365     cvReleaseImage(&pic7);
    366     cvReleaseImage(&copy_zf);
    367     cvReleaseImage(&img_ty);
    368     cvReleaseImage(&ty_cpimg);
    369     cvReleaseImage(&pSrcImage);
    370     cvReleaseImage(&pGrayImage);
    371     cvReleaseImage(&pBinaryImage);
    372     cvReleaseImage(&cyp);
    373 
    374     return finish;
    375 }
    376 
    377 
    378 int sb_count_bd(IplImage *img)
    379 {
    380     int count = 0;
    381     uchar *pt = (uchar *)img->imageData;
    382     const uchar step = img->widthStep;
    383     for(int w = 0; w < img->width; w++)
    384         for(int h = 0; h < img->height; h++)
    385             if(pt[h*step + w])
    386                 count += w*h;
    387     return count;
    388 }
    389 
    390 string db_successlv_3(IplImage *cs)
    391 {
    392     uchar *pt_cs = (uchar *)cs->imageData;
    393     uchar i = 0;
    394     uchar max = 0;
    395     uchar max_backup = 0;
    396     uchar zf  = 0;
    397     string fhz = "";
    398     for(i = 0; i < 34; i++)
    399     {
    400         IplImage *mb = cvLoadImage(mb_ku_sf[i], 1);
    401         uchar cgl = 0;
    402 
    403         int cg_count = 0;
    404         int bd_count = 0;
    405         uchar *pt_mb = (uchar *)mb->imageData;
    406         const uchar step_cs = cs->widthStep;
    407         const uchar step_mb = mb->widthStep;
    408         for(int w = 0; w < cs->width; w++)
    409             for(int h = 0; h < cs->height; h++)
    410             {
    411                 if((pt_cs[h*step_cs + w] == pt_mb[h*step_mb + w]))
    412                     cg_count++;
    413                 if(pt_mb[h*step_mb + w])
    414                     bd_count++;
    415             }
    416         cvReleaseImage(&mb);
    417             cgl = (uchar)(((float)cg_count/(cs->height*cs->width))*100);
    418         max = max<cgl? cgl : max;
    419         if(max != max_backup)
    420             zf = i;
    421         max_backup = max;
    422     }
    423     switch(zf)
    424     {
    425     case 0: fhz = "0";break; case 1: fhz = "1";break; case 2: fhz = "2";break; case 3: fhz = "3";break;
    426     case 4: fhz = "4";break; case 5: fhz = "5";break; case 6: fhz = "6";break; case 7: fhz = "7";break;
    427     case 8: fhz = "8";break; case 9: fhz = "9";break; case 10: fhz = "A";break; case 11: fhz = "B";break;
    428     case 12: fhz = "C";break; case 13: fhz = "D";break; case 14: fhz = "E";break; case 15: fhz = "F";break;
    429     case 16: fhz = "G";break; case 17: fhz = "H";break; case 18: fhz = "J";break; case 19: fhz = "K";break;
    430     case 20: fhz = "L";break; case 21: fhz = "M";break; case 22: fhz = "N";break; case 23: fhz = "P";break;
    431     case 24: fhz = "Q";break; case 25: fhz = "R";break; case 26: fhz = "S";break; case 27: fhz = "T";break;
    432     case 28: fhz = "U";break; case 29: fhz = "V";break; case 30: fhz = "W";break; case 31: fhz = "X";break;
    433     case 32: fhz = "Y";break; case 33: fhz = "Z";break;
    434     }
    435     return (fhz);
    436 }
    437 
    438 string db_successlv_1(IplImage *cs)
    439 {
    440     string fhz = "";
    441     uchar *pt_cs = (uchar *)cs->imageData;
    442     uchar i = 0;
    443     uchar max = 0;
    444     uchar max_backup = 0;
    445     uchar zf  = 0;
    446     for(i = 0; i < 31; i++)
    447     {
    448         IplImage *mb = cvLoadImage(mb_ku_zw[i], 1);
    449         uchar cgl = 0;
    450 
    451         int cg_count = 0;
    452         int bd_count = 0;
    453         uchar *pt_mb = (uchar *)mb->imageData;
    454         const uchar step_cs = cs->widthStep;
    455         const uchar step_mb = mb->widthStep;
    456         for(int w = 0; w < cs->width; w++)
    457             for(int h = 0; h < cs->height; h++)
    458             {
    459                 if((pt_cs[h*step_cs + w] == pt_mb[h*step_mb + w]))
    460                     cg_count++;
    461                 if(pt_mb[h*step_mb + w])
    462                     bd_count++;
    463             }
    464         cvReleaseImage(&mb);
    465             cgl = (uchar)(((float)cg_count/(cs->height*cs->width))*100);
    466         max = max<cgl? cgl : max;
    467         if(max != max_backup)
    468             zf = i;
    469         max_backup = max;
    470         //printf("zf=%d
    ",(int)zf);
    471     }
    472 
    473     switch(zf)
    474     {
    475     case 0: fhz = "";break; case 1: fhz = "";break; case 2: fhz = "";break; case 3: fhz = "";break;
    476     case 4: fhz = "";break; case 5: fhz = "";break; case 6: fhz = "";break; case 7: fhz = "";break;
    477     case 8: fhz = "";break; case 9: fhz = "";break; case 10: fhz = "";break; case 11: fhz = "";break;
    478     case 12: fhz = "";break; case 13: fhz = "";break; case 14: fhz = "";break; case 15: fhz = "";break;
    479     case 16: fhz = "";break; case 17: fhz = "";break; case 18: fhz = "";break; case 19: fhz = "";break;
    480     case 20: fhz = "";break; case 21: fhz = "";break; case 22: fhz = "";break; case 23: fhz = "";break;
    481     case 24: fhz = "";break; case 25: fhz = "";break; case 26: fhz = "";break; case 27: fhz = "";break;
    482     case 28: fhz = "";break; case 29: fhz = "";break; case 30: fhz = "";break;
    483     }
    484     //cout << "return"<<endl;
    485     return (fhz);
    486 }
    487 
    488 string db_successlv_2(IplImage *cs)
    489 {
    490     string fhz = "";
    491     uchar *pt_cs = (uchar *)cs->imageData;
    492     uchar i = 0;
    493     uchar max = 0;
    494     uchar max_backup = 0;
    495     uchar zf  = 0;
    496     for(i = 0; i < 24; i++)
    497     {
    498         IplImage *mb = cvLoadImage(mb_ku_zf[i], 1);
    499         uchar cgl = 0;
    500 
    501         int cg_count = 0;
    502         int bd_count = 0;
    503         uchar *pt_mb = (uchar *)mb->imageData;
    504         const uchar step_cs = cs->widthStep;
    505         const uchar step_mb = mb->widthStep;
    506         for(int w = 0; w < cs->width; w++)
    507             for(int h = 0; h < cs->height; h++)
    508             {
    509                 if((pt_cs[h*step_cs + w] == pt_mb[h*step_mb + w]))
    510                     cg_count++;
    511                 if(pt_mb[h*step_mb + w])
    512                     bd_count++;
    513             }
    514         cvReleaseImage(&mb);
    515             cgl = (uchar)(((float)cg_count/(cs->height*cs->width))*100);
    516         max = max<cgl? cgl : max;
    517         if(max != max_backup)
    518             zf = i;
    519         max_backup = max;
    520         //printf("wz_2  i=%d,zf=%d,max=%d
    ",(int)i,(int)zf,(int)max);
    521     }
    522     switch(zf)
    523     {
    524     case 0: fhz = "A";break; case 1: fhz = "B";break;
    525     case 2: fhz = "C";break; case 3: fhz = "D";break; case 4: fhz = "E";break; case 5: fhz = "F";break;
    526     case 6: fhz = "G";break; case 7: fhz = "H";break; case 8: fhz = "J";break; case 9: fhz = "K";break;
    527     case 10: fhz = "L";break; case 11: fhz = "M";break; case 12: fhz = "N";break; case 13: fhz = "P";break;
    528     case 14: fhz = "Q";break; case 15: fhz = "R";break; case 16: fhz = "S";break; case 17: fhz = "T";break;
    529     case 18: fhz = "U";break; case 19: fhz = "V";break; case 20: fhz = "W";break; case 21: fhz = "X";break;
    530     case 22: fhz = "Y";break; case 23: fhz = "Z";break;
    531     }
    532     return (fhz);
    533 }
    534 
    535 string db_successlv_4_7(IplImage *cs)
    536 {
    537     string fhz = "";
    538     uchar *pt_cs = (uchar *)cs->imageData;
    539     uchar i = 0;
    540     uchar max = 0;
    541     uchar max_backup = 0;
    542     uchar zf  = 0;
    543     for(i = 0; i < 10; i++)
    544     {
    545         IplImage *mb = cvLoadImage(mb_ku_sz[i], 1);
    546         uchar cgl = 0;
    547 
    548         int cg_count = 0;
    549         int bd_count = 0;
    550         uchar *pt_mb = (uchar *)mb->imageData;
    551         const uchar step_cs = cs->widthStep;
    552         const uchar step_mb = mb->widthStep;
    553         for(int w = 0; w < cs->width; w++)
    554             for(int h = 0; h < cs->height; h++)
    555             {
    556                 if((pt_cs[h*step_cs + w] == pt_mb[h*step_mb + w]))
    557                     cg_count++;
    558                 if(pt_mb[h*step_mb + w])
    559                     bd_count++;
    560             }
    561         cvReleaseImage(&mb);
    562             cgl = (uchar)(((float)cg_count/(cs->height*cs->width))*100);
    563         max = max<cgl? cgl : max;
    564         if(max != max_backup)
    565             zf = i;
    566         max_backup = max;
    567     }
    568     switch(zf)
    569     {
    570     case 0: fhz = "0";break; case 1: fhz = "1";break; case 2: fhz = "2";break; case 3: fhz = "3";break;
    571     case 4: fhz = "4";break; case 5: fhz = "5";break; case 6: fhz = "6";break; case 7: fhz = "7";break;
    572     case 8: fhz = "8";break; case 9: fhz = "9";break;
    573     }
    574     return (fhz);
    575 }
    char

    前面的路径中就是字符库的图片路径。

    最后可以得到车牌号码的 字符串,接下来就是后台的处理。

    3.对进出用户的信息存储和读取。

    这里我们使用的是Qt界面程序语言编写的客户端。

    这里是真正的发挥空间,可以使用得来的数据进行存储,还有手机客户端给用户信息。

     

     

  • 相关阅读:
    CSS常用伪类
    HTML5常用API
    HTML5新技术FormData提交表单数据
    WebPack打包后如何调试
    layui的初体验(layer的使用)
    java数组
    java:注解
    java反射:框架设计的灵魂
    885历年编程题
    2020年专业课编程题
  • 原文地址:https://www.cnblogs.com/panhao/p/4803582.html
Copyright © 2011-2022 走看看