License Plate Recognition: License Plate positioning [practice]

Source: Internet
Author: User

As mentioned in the previous article, license plate locating is based on an example in the opencv sample. I think it is theoretically feasible, but I have never performed any operations. Today I am free. I modified the code and tried several images. I found that the effect is good. The code is specially pasted to communicate with opencv learners and hope to give some guidance with high fingers. O (partition _ partition) O

The Code is as follows:

 

//////////////////////////////////////// //////////////////////////////////
//////////////////////////////////////// //////////////////////////////////
// Locate the license plate
// Modified by sing
// 2010-10-14

//
// The full "square detector" program.
// It loads several images subsequentally and tries to find squares in
// Each image
//
# Ifdef _ CH _
# Pragma package <opencv>
# Endif

# Define cv_no_backward_compatibility

# Include "cv. H"
# Include "highgui. H"
# Include <stdio. h>
# Include <math. h>
# Include <string. h>

Int thresh = 50;
Iplimage * IMG = 0;
Iplimage * img0 = 0;
Cvmemstorage * storage = 0;
Const char * wndname = "square detection Demo ";

// Helper function:
// Finds a cosine of angle between vectors
// From pt0-> pt1 and from pt0-> pt2
Double angle (cvpoint * pt1, cvpoint * pt2, cvpoint * pt0)
{
Double dx1 = pt1-> X-pt0-> X;
Double dy1 = pt1-> Y-pt0-> Y;
Double dx2 = pt2-> X-pt0-> X;
Double dy2 = pt2-> Y-pt0-> Y;
Return (dx1 * dx2 + dy1 * dy2)/SQRT (dx1 * dx1 + dy1 * dy1) * (dx2 * dx2 + dy2 * dy2) + 1e-10 );
}

// Returns sequence of squares detected on the image.
// The sequence is stored in the specified memory storage
Cvseq * findsquares4 (iplimage * IMG, cvmemstorage * storage)
{
Cvseq * contours;
Int I, C, L, n = 1;
Cvsize SZ = cvsize (IMG-> width &-2, IMG-> Height &-2); // ensure that the last digit is an even number, by sing
Iplimage * timg = cvcloneimage (IMG); // make a copy of input image
Iplimage * gray = cvcreateimage (SZ, 8, 1 );
Iplimage * Pyr = cvcreateimage (cvsize (SZ. width/2, Sz. Height/2), 8, 3 );
Iplimage * tgray;
Cvseq * result;
Double S, T;
// Create empty sequence that will contain points-
// 4 points per square (the square's vertices)
Cvseq * squares = cvcreateseq (0, sizeof (cvseq), sizeof (cvpoint), storage );

// Select the maximum ROI in the image
// With the width and height divisible by 2
Cvsetimageroi (timg, cvrect (0, 0, Sz. Width, Sz. Height ));

// Down-scale and upscale the image to filter out the noise
Cvpyrdown (timg, Pyr, 7 );
Cvpyrup (Pyr, timg, 7 );
Tgray = cvcreateimage (SZ, 8, 1 );

// Find squares in every color plane of the image
For (C = 0; C <3; C ++)
{
// Extract the C-th color plane
Cvsetimagecoi (timg, C + 1 );

Cvcopy (timg, tgray, 0 );

// Try several threshold levels
// For (L = 0; L <n; l ++)
{
// Hack: Use canny instead of zero threshold level.
// Canny helps to catch squares with gradient shading
// If (L = 0)
//{
/// Apply canny. Take the upper threshold from Slider
/// And set the lower to 0 (which forces edges merging)
// Cvmoderation (tgray, gray, 0, thresh, 5 );
/// Maid output to remove potential
/// Holes between edge segments
// Cvdilate (Gray, gray, 0, 1 );
//}
// Else
{
// Apply threshold if l! = 0:
// Tgray (x, y) = gray (x, y) <(L + 1) * 255/n? 255: 0
Cvthreshold (tgray, gray,/* (L + 1) x 255/N */100,255, cv_thresh_binary );
}

// Find every S and store them all as a list
Cvfindcontours (Gray, storage, & contours, sizeof (cvcontour ),
Cv_retr_list, cv_chain_approx_simple, cvpoint (0, 0 ));

// Test each Contour
While (contours)
{
// Approximate contour with accuracy proportional
// To the contour perimeter
Result = cvapproxpoly (contours, sizeof (cvcontour), storage,
Cv_poly_approx_dp, cv1_perimeter (contours) * 0.02, 0 );
// Square contours shocould have 4 vertices after Approximation
// Relatively large area (to filter out noisy contours)
// And be convex.
// Note: absolute value of an area is used because
// Area may be positive or negative-in accordance with
// Contour Orientation
If (result-> total = 4 &&
Cv1_area (result, cv_whole_seq, 0)> 1000 &&
Cv1_area (result, cv_whole_seq, 0) <(SZ. Width * Sz. Height/4 )&&
Cvcheck1_convexity (result ))
{
S = 0;

For (I = 0; I <5; I ++)
{
// Find minimum angle between joint
// Edges (maximum of cosine)
If (I> = 2)
{
T = FABS (angle (
(Cvpoint *) cvgetseqelem (result, I ),
(Cvpoint *) cvgetseqelem (result, I-2 ),
(Cvpoint *) cvgetseqelem (result, I-1 )));
S = s> T? S: T;
}
}

// If cosines of all angles are small
// (All angles are ~ 90 degree) then write quandrange
// Vertices to resultant Sequence
If (S <0.3)
For (I = 0; I <4; I ++)
Cvseqpush (squares,
(Cvpoint *) cvgetseqelem (result, I ));
}

// Take the next Contour
S = S-> h_next;
}
}
}

// Release all the temporary Images
Cvreleaseimage (& gray );
Cvreleaseimage (& Pyr );
Cvreleaseimage (& tgray );
Cvreleaseimage (& timg );

Return squares;
}

// Obtain the maximum rectangular area write by Sing 2010-10-14
Cvrect getboundingrect (cvpoint * points, int COUNT = 4)
{
Unsigned int Minx =-1, miny =-1;
Unsigned int Maxx = 0, Maxy = 0;

For (INT I = 0; I <count; I ++ ){
If (Minx> points [I]. X ){
Minx = points [I]. X;
}
If (miny> points [I]. Y ){
Miny = points [I]. Y;
}
If (Maxx <points [I]. X ){
Maxx = points [I]. X;
}
If (Maxy <points [I]. Y ){
Maxy = points [I]. Y;
}
}

Cvrect rc = cvrect (Minx, miny, Maxx-Minx, Maxy-miny );

Return RC;
}

// The function draws all the squares in the image
Void drawsquares (iplimage * IMG, cvseq * squares)
{
Cvseqreader reader;
Iplimage * CPY = cvcloneimage (IMG );
Int I;

// Initialize reader of the sequence
Cvstartreadseq (squares, & reader, 0 );

// Read 4 sequence elements at a time (all vertices of a square)
For (I = 0; I <squares-> total; I + = 4)
{
Cvpoint PT [4], * rect = pt;
Int COUNT = 4;

// Read 4 vertices
Cv_read_seq_elem (PT [0], Reader );
Cv_read_seq_elem (PT [1], Reader );
Cv_read_seq_elem (PT [2], Reader );
Cv_read_seq_elem (PT [3], Reader );

// Draw the square as a closed polyline
Cvpolyline (CPY, & rect, & count, 1, 1, cv_rgb (0,255, 0), 1, cv_aa, 0 );

// Capture the image and determine whether the image is a license plate
Cvrect rc = getboundingrect (PT, count );
// Printf ("[% d, % d]/n", RC. X, RC. Y, RC. Width, RC. Height );
Iplimage * img2 = cvcreateimage (cvsize (RC. Width, RC. Height), ipl_depth_8u, 3 );
Cvzero (img2 );
Cvsetimageroi (IMG, RC );
Cvcopyimage (IMG, img2 );
Cvresetimageroi (IMG );

Cvnamedwindow ("tmp", cv_window_autosize );
Cvshowimage ("tmp", img2 );
Cvreleaseimage (& img2 );
Cvwaitkey (0 );
}

// Show the resultant image
Cvshowimage (wndname, CPY );
Cvreleaseimage (& CPY );
}

Char * Names [] = {
"1.bmp", "2.bmp", "3.bmp ",
"4.bmp", "5.bmp", 0
};

Int main (INT argc, char ** argv)
{
Int I, C;
// Create memory storage that will contain in all the dynamic data
Storage = cvcreatememstorage (0 );

For (I = 0; names [I]! = 0; I ++)
{
// Load I-th Image
Img0 = cvloadimage (Names [I], 1 );
If (! Img0)
{
Printf ("couldn't load % s/n", Names [I]);
Continue;
}
IMG = cvcloneimage (img0 );

// Create window and a trackbar (slider) with parent "image" and set callback
// (The slider regulates upper threshold, passed to Canny edge detector)
Cvnamedwindow (wndname, 1 );

// Find and draw the squares
Drawsquares (IMG, findsquares4 (IMG, storage ));

// Wait for key.
// Also the function cvwaitkey takes care of Event Processing
C = cvwaitkey (0 );
// Release both images
Cvreleaseimage (& IMG );
Cvreleaseimage (& img0 );
// Clear memory storage-Reset free space position
Cvclearmemstorage (storage );
If (char) C = 27)
Break;
}

Cvdestroywindow (wndname );

Return 0;
}

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.