OpenCV下车牌定位算法实现代码(一)

2018-12-04 21:44

车牌定位算法在车牌识别技术中占有很重要地位,一个车牌识别系统的识别率往往取决于车牌定位的成功率及准确度。

车牌定位有很多种算法,从最简单的来,车牌在图像中一般被认为是长方形,由于图像摄取角度不同也可能是四边形。我们可以使用OpenCV中的实例: C:\\Program Files\\OpenCV\\samples\\c.squares.c 这是一个搜索图片中矩形的一个算法。我们只要稍微修改一下就可以实现定位车牌。

在这个实例中使用了canny算法进行边缘检测,然后二值化,接着用

cvFindContours搜索轮廓,最后从找到的轮廓中根据角点的个数,角的度数和轮廓大小确定,矩形位置。以下是效果图:

这个算法可以找到一些车牌位置,但在复杂噪声背景下,或者车牌图像灰度与背景相差不大就很难定位车牌

所以我们需要寻找更好的定位算法。下面是squares的代码: 1. 2.

#ifdef _CH_

#pragma package

3. #endif 4.

5. #ifndef _EiC 6. #include \

7. #include \8. #include 9. #include 10. #include 11. #endif 12.

13. int thresh = 50; 14. IplImage* img = 0; 15. IplImage* img0 = 0;

16. CvMemStorage* storage = 0; 17. CvPoint pt[4];

18. const char* wndname = \19.

20. // helper function:

21. // finds a cosine of angle between vectors 22. // from pt0->pt1 and from pt0->pt2

23. double angle( CvPoint* pt1, CvPoint* pt2, CvPoint* pt0 ) 24. {

25. double dx1 = pt1->x - pt0->x; 26. double dy1 = pt1->y - pt0->y; 27. double dx2 = pt2->x - pt0->x; 28. double dy2 = pt2->y - pt0->y;

29. return (dx1*dx2 + dy1*dy2)/sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10); 30. } 31.

32. // returns sequence of squares detected on the image.

33. // the sequence is stored in the specified memory storage 34. CvSeq* findSquares4( IplImage* img, CvMemStorage* storage ) 35. {

36. CvSeq* contours; 37. int i, c, l, N = 11;

38. CvSize sz = cvSize( img->width & -2, img->height & -2 );

39. IplImage* timg = cvCloneImage( img ); // make a copy of input image

40. IplImage* gray = cvCreateImage( sz, 8, 1 );

41. IplImage* pyr = cvCreateImage( cvSize(sz.width/2, sz.height/2), 8, 3 );

42. IplImage* tgray;

43. CvSeq* result; 44. double s, t;

45. // create empty sequence that will contain points - 46. // 4 points per square (the square's vertices)

47. CvSeq* squares = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvPoint), storage ); 48.

49. // select the maximum ROI in the image

50. // with the width and height divisible by 2

51. cvSetImageROI( timg, cvRect( 0, 0, sz.width, sz.height )); 52.

53. // down-scale and upscale the image to filter out the noise

54. cvPyrDown( timg, pyr, 7 ); 55. cvPyrUp( pyr, timg, 7 );

56. tgray = cvCreateImage( sz, 8, 1 ); 57.

58. // find squares in every color plane of the image 59. for( c = 0; c < 3; c++ ) 60. {

61. // extract the c-th color plane 62. cvSetImageCOI( timg, c+1 ); 63. cvCopy( timg, tgray, 0 ); 64.

65. // try several threshold levels 66. for( l = 0; l < N; l++ ) 67. {

68. // hack: use Canny instead of zero threshold level.

69. // Canny helps to catch squares with gradient shading 70. if( l == 0 ) 71. {

72. // apply Canny. Take the upper threshold from slider 73. // and set the lower to 0 (which forces edges merging) 74. cvCanny( tgray, gray,60, 180, 3 );

75. // dilate canny output to remove potential 76. // holes between edge segments 77. cvDilate( gray, gray, 0, 1 ); 78. } 79. else 80. {

81. //apply threshold if l!=0:

82. //tgray(x,y) = gray(x,y) < (l+1)*255/N ? 255 : 0

83. //cvThreshold( tgray, gray, (l+1)*255/N, 255, CV_THRESH_BINARY );

84. cvThreshold( tgray, gray, 50, 255, CV_THRESH_BINARY ); 85. } 86.

87. // find contours and store them all as a list

88. cvFindContours( gray, storage, &contours, sizeof(CvContour),

89. CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0) ); 90. 91.

92. // test each contour 93. while( contours ) 94. {

95. // approximate contour with accuracy proportional 96. // to the contour perimeter 97.

result = cvApproxPoly( contours, sizeof(CvContour), storage, 98. CV_POLY_APPROX_DP, cvContourPerimeter(contours)*0.02, 0 );

99. // square contours should have 4 vertices after approximation

100. // relatively large area (to filter out noisy contours) 101. // and be convex.

102. // Note: absolute value of an area is used because

103. // area may be positive or negative - in accordance with the

104. // contour orientation 105. if( result->total == 4 &&

106. fabs(cvContourArea(result,CV_WHOLE_SEQ)) > 1000 && 107. cvCheckContourConvexity(result) ) 108. {

109. s = 0; 110.

111. for( i = 0; i < 5; i++ ) 112. {

113. // find minimum angle between joint 114. // edges (maximum of cosine) 115. if( i >= 2 ) 116. {

117. t = fabs(angle(

118. (CvPoint*)cvGetSeqElem( result, i ), 119. (CvPoint*)cvGetSeqElem( result, i-2 ), 120. (CvPoint*)cvGetSeqElem( result, i-1 )));

121. s = s > t ? s : t; 122. } 123. } 124. 125.

126. // if cosines of all angles are small 127. // (all angles are ~90 degree) then write quandrange

128. // vertices to resultant sequence 129. if( s < 0.3 )

130. for( i = 0; i < 4; i++ ) 131. cvSeqPush( squares,

132. (CvPoint*)cvGetSeqElem( result, i ));

133. } 134.

135. // take the next contour 136. contours = contours->h_next; 137. } 138. } 139. } 140.

141. // release all the temporary images 142. cvReleaseImage( &gray ); 143. cvReleaseImage( &pyr ); 144. cvReleaseImage( &tgray ); 145. cvReleaseImage( &timg ); 146.

147. return squares; 148. } 149. 150.

151. // the function draws all the squares in the image 152. void drawSquares( IplImage* img, CvSeq* squares ) 153. {

154. CvSeqReader reader;

155. IplImage* cpy = cvCloneImage( img ); 156. int i; 157.

158. // initialize reader of the sequence 159. cvStartReadSeq( squares, &reader, 0 ); 160.

161. // read 4 sequence elements at a time (all vertices of a square)


OpenCV下车牌定位算法实现代码(一).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:马克思《数学手稿》

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: