在车牌识别系统中, 车牌字符能够正确分割的前提是车牌图像能够水平,以至于水平投影和垂直投影能够正常进行。如果车牌倾斜没有矫正,那么水平投影和垂直投影,甚至铆钉都无法正常处理。所以,当车辆信息中获取车牌的第一步,应该是检查倾斜角度,做倾斜矫正。

倾斜矫正,这里使用的算法:

1、倾斜角度检测: 霍夫变换

关于hough变换,可以参考前面图像处理博文:

http://blog.csdn.net/liujia2100/article/details/6989693   直线检测

http://blog.csdn.net/liujia2100/article/details/6989688   文本图像倾斜矫正

2、倾斜矫正: 图像旋转

下面详细说明倾斜矫正过程:

原车牌图像为(从车牌图像中,可以看到车牌有倾斜角度):

1、 获取车牌在车辆中的粗略位置(可以用多种方法,这里暂不分析)

2、提取车牌整体图片数据, 根据第一步结果,提取出,车牌在辆大体位置信息。

关于车牌定位,我使用两部,第一步粗略定位,然后做一些预处理,比如倾斜矫正,然后第二部才是精确定位,只提取车牌的位置信息图像

3、利用HSV颜色空间转换,获取车牌背景蓝色区域位置,获取车牌粗略信息图像后,由于车牌背景颜色与周围颜色有很明显的区别,这里采用HSV颜色过滤的方法,过滤绿色背景图像

4、水平膨胀, 水平膨胀的目的,是为了边缘检测,只要求检测边缘,尽量除去字符信息,也可以降低hough变换的运算量

5、水平差分运算,相当于 边缘检测,经过上面的处理后,才进行边缘检测

6、这个时候就可以利用hough变换检测直线了。

由于hough变换运算量十分大,所以,尽量减少图像中的白点,来降低计算量,因此前面才做了这么多步骤。

请看下图的红线,就是检测出来的角度,为177度(Hough代码在下面)。

7、利用旋转算法,旋转刚才粗略提取的车牌位置(旋转代码在下面),尽管旋转后的车牌有些锯齿,但是已经能够保证水平,就可以使用水平投影和垂直投影了

这是旋转后的车牌,有些锯齿出现,由于图像分辨率较低,就没有用差值运算。

8、精确提取车牌

9、正常分割字符

10、识别结果

由于正弦余弦运算,计算量比较大,这里进行一部分优化,就是正弦余弦计算用数组代替。

生成正弦,余弦数组的的代码如下:

[cpp] view plaincopy
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <math.h>
  5. int main(void)
  6. {
  7. char buf[20];
  8. int i;
  9. float p;
  10. float k;
  11. FILE *fcos;
  12. FILE *fsin;
  13. fcos = fopen(".\\cos.txt", "wb");
  14. fsin = fopen(".\\sin.txt", "wb");
  15. if(fcos == NULL || fsin == NULL)
  16. {
  17. printf("open error\n");
  18. exit(-1);
  19. }
  20. i = 0;
  21. for(i = 0; i <= 180; i++)
  22. {
  23. k = 3.1415926 * i / 180.0;
  24. p = cos(k);
  25. if((i%16 == 0))
  26. fwrite("\n",strlen("\n"),1,fcos);
  27. sprintf(buf,"%f, ", p);
  28. fwrite(buf,strlen(buf),1,fcos);
  29. }
  30. for(i = 0; i <= 180; i++)
  31. {
  32. k = 3.1415926 * i / 180.0;
  33. p = sin(k);
  34. if((i%16 == 0))
  35. fwrite("\n",strlen("\n"),1,fsin);
  36. sprintf(buf,"%f, ", p);
  37. fwrite(buf,strlen(buf),1,fsin);
  38. }
  39. fclose(fcos);
  40. fclose(fsin);
  41. return 0;
  42. }

生成数组为:

[cpp] view plaincopy
  1. float carCos[] = {
  2. 1.000000, 0.999848, 0.999391, 0.998630, 0.997564, 0.996195, 0.994522, 0.992546, 0.990268, 0.987688, 0.984808, 0.981627, 0.978148, 0.974370, 0.970296, 0.965926,
  3. 0.961262, 0.956305, 0.951057, 0.945519, 0.939693, 0.933580, 0.927184, 0.920505, 0.913545, 0.906308, 0.898794, 0.891007, 0.882948, 0.874620, 0.866025, 0.857167,
  4. 0.848048, 0.838671, 0.829038, 0.819152, 0.809017, 0.798636, 0.788011, 0.777146, 0.766044, 0.754710, 0.743145, 0.731354, 0.719340, 0.707107, 0.694658, 0.681998,
  5. 0.669131, 0.656059, 0.642788, 0.629320, 0.615662, 0.601815, 0.587785, 0.573576, 0.559193, 0.544639, 0.529919, 0.515038, 0.500000, 0.484810, 0.469472, 0.453991,
  6. 0.438371, 0.422618, 0.406737, 0.390731, 0.374607, 0.358368, 0.342020, 0.325568, 0.309017, 0.292372, 0.275637, 0.258819, 0.241922, 0.224951, 0.207912, 0.190809,
  7. 0.173648, 0.156434, 0.139173, 0.121869, 0.104528, 0.087156, 0.069757, 0.052336, 0.034900, 0.017452, 0.000000, -0.017452, -0.034899, -0.052336, -0.069756, -0.087156,
  8. -0.104528, -0.121869, -0.139173, -0.156434, -0.173648, -0.190809, -0.207912, -0.224951, -0.241922, -0.258819, -0.275637, -0.292372, -0.309017, -0.325568, -0.342020, -0.358368,
  9. -0.374607, -0.390731, -0.406737, -0.422618, -0.438371, -0.453990, -0.469472, -0.484810, -0.500000, -0.515038, -0.529919, -0.544639, -0.559193, -0.573576, -0.587785, -0.601815,
  10. -0.615661, -0.629320, -0.642788, -0.656059, -0.669131, -0.681998, -0.694658, -0.707107, -0.719340, -0.731354, -0.743145, -0.754710, -0.766044, -0.777146, -0.788011, -0.798635,
  11. -0.809017, -0.819152, -0.829038, -0.838671, -0.848048, -0.857167, -0.866025, -0.874620, -0.882948, -0.891007, -0.898794, -0.906308, -0.913545, -0.920505, -0.927184, -0.933580,
  12. -0.939693, -0.945519, -0.951056, -0.956305, -0.961262, -0.965926, -0.970296, -0.974370, -0.978148, -0.981627, -0.984808, -0.987688, -0.990268, -0.992546, -0.994522, -0.996195,
  13. -0.997564, -0.998630, -0.999391, -0.999848, -1.000000
  14. };
  15. float carSin[] = {
  16. 0.000000, 0.017452, 0.034899, 0.052336, 0.069756, 0.087156, 0.104528, 0.121869, 0.139173, 0.156434, 0.173648, 0.190809, 0.207912, 0.224951, 0.241922, 0.258819,
  17. 0.275637, 0.292372, 0.309017, 0.325568, 0.342020, 0.358368, 0.374607, 0.390731, 0.406737, 0.422618, 0.438371, 0.453990, 0.469472, 0.484810, 0.500000, 0.515038,
  18. 0.529919, 0.544639, 0.559193, 0.573576, 0.587785, 0.601815, 0.615661, 0.629320, 0.642788, 0.656059, 0.669131, 0.681998, 0.694658, 0.707107, 0.719340, 0.731354,
  19. 0.743145, 0.754710, 0.766044, 0.777146, 0.788011, 0.798635, 0.809017, 0.819152, 0.829038, 0.838671, 0.848048, 0.857167, 0.866025, 0.874620, 0.882948, 0.891007,
  20. 0.898794, 0.906308, 0.913545, 0.920505, 0.927184, 0.933580, 0.939693, 0.945519, 0.951056, 0.956305, 0.961262, 0.965926, 0.970296, 0.974370, 0.978148, 0.981627,
  21. 0.984808, 0.987688, 0.990268, 0.992546, 0.994522, 0.996195, 0.997564, 0.998630, 0.999391, 0.999848, 1.000000, 0.999848, 0.999391, 0.998630, 0.997564, 0.996195,
  22. 0.994522, 0.992546, 0.990268, 0.987688, 0.984808, 0.981627, 0.978148, 0.974370, 0.970296, 0.965926, 0.961262, 0.956305, 0.951057, 0.945519, 0.939693, 0.933580,
  23. 0.927184, 0.920505, 0.913545, 0.906308, 0.898794, 0.891007, 0.882948, 0.874620, 0.866025, 0.857167, 0.848048, 0.838671, 0.829038, 0.819152, 0.809017, 0.798636,
  24. 0.788011, 0.777146, 0.766044, 0.754710, 0.743145, 0.731354, 0.719340, 0.707107, 0.694658, 0.681998, 0.669131, 0.656059, 0.642788, 0.629320, 0.615662, 0.601815,
  25. 0.587785, 0.573576, 0.559193, 0.544639, 0.529919, 0.515038, 0.500000, 0.484810, 0.469472, 0.453991, 0.438371, 0.422618, 0.406737, 0.390731, 0.374607, 0.358368,
  26. 0.342020, 0.325568, 0.309017, 0.292372, 0.275637, 0.258819, 0.241922, 0.224951, 0.207912, 0.190809, 0.173648, 0.156435, 0.139173, 0.121869, 0.104529, 0.087156,
  27. 0.069757, 0.052336, 0.034900, 0.017452, 0.000000
  28. };

旋转RGB图像的主要函数:

image: 图像数据

iRotateAngle: 要旋转的角度

width, height:原始图像的宽度,高度

lwidth,lheight:旋转后图像的宽度,高度

[cpp] view plaincopy
  1. unsigned char *RotateRGB(unsigned char *image, float iRotateAngle,int width,int height,int &lwidth,int &lheight)
  2. {
  3. int i,j,k,m,n;
  4. long    lNewWidth;
  5. long    lNewHeight;
  6. float gray;
  7. long    i0;
  8. long    j0;
  9. float   fRotateAngle;
  10. float   fSina, fCosa;
  11. float   fSrcX1,fSrcY1,fSrcX2,fSrcY2,fSrcX3,fSrcY3,fSrcX4,fSrcY4;
  12. float   fDstX1,fDstY1,fDstX2,fDstY2,fDstX3,fDstY3,fDstX4,fDstY4;
  13. float   f1,f2;
  14. if(iRotateAngle >= 0)
  15. {
  16. fSina = (float)carSin[(int)iRotateAngle];
  17. fCosa = (float)carCos[(int)iRotateAngle];
  18. }
  19. else
  20. {
  21. fSina = 0 - (float)carSin[0 -(int)iRotateAngle];
  22. fCosa = (float)carCos[0 - (int)iRotateAngle];
  23. }
  24. fSrcX1 = (float) (- (width  - 1) / 2);
  25. fSrcY1 = (float) (  (height - 1) / 2);
  26. fSrcX2 = (float) (  (width  - 1) / 2);
  27. fSrcY2 = (float) (  (height - 1) / 2);
  28. fSrcX3 = (float) (- (width  - 1) / 2);
  29. fSrcY3 = (float) (- (height - 1) / 2);
  30. fSrcX4 = (float) (  (width  - 1) / 2);
  31. fSrcY4 = (float) (- (height - 1) / 2);
  32. fDstX1 =  fCosa * fSrcX1 + fSina * fSrcY1;
  33. fDstY1 = -fSina * fSrcX1 + fCosa * fSrcY1;
  34. fDstX2 =  fCosa * fSrcX2 + fSina * fSrcY2;
  35. fDstY2 = -fSina * fSrcX2 + fCosa * fSrcY2;
  36. fDstX3 =  fCosa * fSrcX3 + fSina * fSrcY3;
  37. fDstY3 = -fSina * fSrcX3 + fCosa * fSrcY3;
  38. fDstX4 =  fCosa * fSrcX4 + fSina * fSrcY4;
  39. fDstY4 = -fSina * fSrcX4 + fCosa * fSrcY4;
  40. lNewWidth  = (long) ( max( fabs(fDstX4 - fDstX1), fabs(fDstX3 - fDstX2) ) + 0.5);
  41. lNewHeight = (long) ( max( fabs(fDstY4 - fDstY1), fabs(fDstY3 - fDstY2) )  + 0.5);
  42. unsigned char *temp=myMalloc(lNewHeight*lNewWidth*3,0,0);
  43. f1 = (float) (-0.5 * (lNewWidth - 1) * fCosa - 0.5 * (lNewHeight - 1) * fSina
  44. + 0.5 * (width  - 1));
  45. f2 = (float) ( 0.5 * (lNewWidth - 1) * fSina - 0.5 * (lNewHeight - 1) * fCosa
  46. + 0.5 * (height - 1));
  47. for(i = 0; i < lNewHeight; i++)
  48. {
  49. for(m=0,j = 0;j < lNewWidth,m<lNewWidth*3;m+=3,j++)
  50. {
  51. i0 = (long) (-((float) j) * fSina + ((float) i) * fCosa + f2 + 0.5);
  52. j0 = (long) ( ((float) j) * fCosa + ((float) i) * fSina + f1 + 0.5);
  53. if( (j0 >= 0) && (j0 < width) && (i0 >= 0) && (i0 < height))
  54. {
  55. n=i0 * width * 3 + j0 * 3;
  56. *(temp + lNewWidth * i * 3 + m + 1) = *(image + n + 1);
  57. *(temp + lNewWidth * i * 3 + m + 2) = *(image + n + 2);
  58. *(temp + lNewWidth * i * 3 + m) = *(image + n);
  59. }
  60. else
  61. {
  62. *(temp + lNewWidth * i*3+ m+1)=0;
  63. *(temp + lNewWidth * i*3+ m+2)=0;
  64. *(temp + lNewWidth * i*3+ m)=0;
  65. }
  66. }
  67. }
  68. lwidth = lNewWidth;
  69. lheight = lNewHeight;
  70. return temp;
  71. }

Hough变化的主要函数

返回值Kmax,就是检测到最长直线的角度,就是车牌的倾斜角度。

[cpp] view plaincopy
  1. int hough(unsigned char *srcBmp,int width,int height)
  2. {
  3. int kmax=0;
  4. int pmax=0;
  5. int yuzhi=0;
  6. int i,j,k,m,n,p;
  7. int mp = (int) (sqrt(width*width + height*height)+1);
  8. int ma = 180;//180
  9. int ap;
  10. int npp[180][1000];
  11. for(i=0;i<180;i++)
  12. for(j=0;j<1000;j++)
  13. npp[i][j]=0;
  14. for(i = 0;i < height;i++)
  15. for(j = 0; j < width;j++)
  16. {
  17. if(srcBmp[i * width + j]==255)
  18. {
  19. for(k = 0; k < ma; k++)
  20. {
  21. p=(int)(i * carCos[k] + j * carSin[k]);
  22. p=(int)(p/2 + mp/2);
  23. npp[k][p]=npp[k][p]++;
  24. }
  25. }
  26. }
  27. kmax=0;
  28. pmax=0;
  29. n=0;
  30. for(i = 0; i < ma; i++)
  31. for(j = 0; j < mp; j++)
  32. {
  33. if(npp[i][j] > yuzhi)
  34. {
  35. yuzhi=npp[i][j];
  36. kmax=i;
  37. pmax=j;
  38. }
  39. }
  40. for(i = 0; i < height;i++)
  41. for(j = 0; j < width;j++)
  42. {
  43. if(srcBmp[i*width+j]==255)
  44. {
  45. p=(int)(i*carCos[kmax] + j *carSin[kmax]);
  46. p=(int)(p/2+mp/2);
  47. #if defined(DISPLAYDEBUG)
  48. if(p==pmax)
  49. putpixel(j,i,RGB(255,0,0));
  50. #endif
  51. }
  52. }
  53. return kmax;
  54. }

图像处理交流QQ群:

105060236

车牌识别--倾斜矫正相关推荐

  1. python车牌矫正_radon变换用于车牌图像倾斜矫正[水平倾斜和垂直倾斜]

    Radon变换定义:下图显示了在指定的旋转角度的单一投影.间距为1个像素的平行光穿过图像,则radon变换计算穿过图像长度上的积分,即  式中  旋转角度为θ的平行束投影 f(x,y) 在垂直方向的线 ...

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

    defimg_Transform(car_contours,oldimg,pic_width,pic_hight): car_imgs=[]for car_rect incar_contours:if ...

  3. 汽车车牌识别系统实现(三)-- 车牌矫正+字符分割+代码实现

    车牌矫正 一.前言 汽车车牌识别设备往往都是固定于红绿灯的支架或者是小区.学校入口的一侧来采集获取车牌图像,由于采集图像设备的安装位置不固定以及不同车辆车牌悬挂的高度也不确定等因素,这些外部因素都有可 ...

  4. matlab 倾斜矫正,matlab图像倾斜校正

    4 图像颜色畸变校正介绍图像颜色畸变现象可以是由摄像器材导致,也可以是由于真实环境本身就偏 色导致,还有的是由于图像放置过久氧化.老化导致.无论其产生的原因如何, 其校正方法都是类似的.如果用 Mat ...

  5. 数字图像处理_Matlab——车牌识别分析

    目录 一.导入图片 1. 从文件导入 1.1 原理: 1.2 代码: 2. 摄像头拍照识别 2.1 了解 2.1 代码: 二.预处理 1. 预处理-- 原图->灰度图 2. 预处理-- 边缘检测 ...

  6. 智能驾驶 车牌检测和识别(三)《CRNN和LPRNet实现车牌识别(含车牌识别数据集和训练代码)》

    智能驾驶 车牌检测和识别(三)<CRNN和LPRNet实现车牌识别(含车牌识别数据集和训练代码)> 目录 智能驾驶 车牌检测和识别(三)<CRNN和LPRNet实现车牌识别(含车牌识 ...

  7. 基于matlab的蓝色车牌识别(车牌倾斜矫正)

    目录 一 处理流程 二 结果展示 三 核心要点解读 四 matlab代码实现 整套方案好包括以下博客: (1)基于matlab的蓝色车牌识别(绪论) (2)基于matlab的蓝色车牌识别(车牌定位) ...

  8. 基于u-net,cv2以及cnn的中文车牌定位,矫正和端到端识别软件

    本文链接:https://blog.csdn.net/qq_32194791/article/details/106748685,转载请注明出处 完整项目已上传至github: https://git ...

  9. 【Python4】字符分割识别,车牌识别矫正,移动物检测,Caffe_SSD三字码识别,ckpt文件转pb文件,人脸检测与识别

    文章目录 1.字符分割识别 2.车牌识别矫正 2.1 车牌识别项目安装 2.2 车牌矫正的方法 3.移动物检测 3.1 帧间差分法 3.2 相机捕捉照片 3.3 MindVision品牌的相机 3.4 ...

最新文章

  1. WPF入门(三)-几何图形之不规则图形(PathGeometry) (2)
  2. 十大流行AI框架和库的优缺点对比
  3. .net程序中资源文件的保护办法探讨
  4. 2022年全球及中国户外电源产品行业容量前景与运营动态分析报告
  5. take the bull by the horns blow one's own horn
  6. CDK上安装kube-dashboard
  7. J2EE的经常使用十三规范——java菜鸟成长记
  8. android 7.1 apk的systemuid相同导致问题[2]
  9. mysql中用完即删用什么_MySQL使用和操作总结(《MySQL必知必会》读书笔记)
  10. LYNC文件传输功能开关
  11. excel函数与公式实战技巧精粹_excel函数技巧:两个查询函数的用法比较 下
  12. opencv-api matchTemplate
  13. oracle的序列为什么会出错,Oracle系列:(24)序列
  14. 【php】使用phpdbg来调试php程序
  15. 问题二十九:测试ray tracing中camera几个主要参数
  16. 解决navicat在未联网的情况下访问不了MySQL数据库的现象
  17. iOS 人脸识别Demo
  18. 数据库三范式简单理解
  19. FIL到底是什么?IPFS是什么?IPFS和FIL是什么关系?FIL参与方式
  20. echarts框架下大数据量展示的解决方案

热门文章

  1. 获取手机设备的IMSI / IMEI 信息
  2. mpg123源码详解
  3. UNIX痛恨者手册[转贴自 FreeBSDChina]
  4. android VideoView 获取当前播放时间、获取视频长度。
  5. Ucinet三天写论文!C刊科研网络精写
  6. 【转】30岁程序员的转型思考
  7. cpc卡内计费信息异常包括_CPC卡精确计费方案
  8. 搭建自己的云存储空间|FastDFS分布式文件系统考虑一下?
  9. windows 重新获取ip
  10. java波斯王子武者之心,波斯王子武者之心