[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Automatic number plate recognition

Posted on 2011-05-03
6
Medium Priority
?
1,031 Views
Last Modified: 2013-11-19
is there any sample C# or VB or any language that make an Automatic number plate recognition?
0
Comment
Question by:caznova
  • 2
  • 2
5 Comments
 
LVL 8

Accepted Solution

by:
hello_everybody earned 2000 total points
ID: 35694317
Check this out: http://www.emgu.com/wiki/index.php/License_Plate_Recognition_in_CSharp:

 
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using Emgu.Util;
using Emgu.CV;
using Emgu.CV.Structure;
using tessnet2;
using System.Diagnostics;
 
namespace LicensePlateRecognition
{
   /// <summary>
   /// A license plate detector
   /// </summary>
   public class LicensePlateDetector : DisposableObject
   {
      private Tesseract _ocr;
 
      /// <summary>
      /// Create a license plate detector
      /// </summary>
      public LicensePlateDetector()
      {
         //create OCR
         _ocr = new Tesseract();
 
         //You can download more language definition data from
         //http://code.google.com/p/tesseract-ocr/downloads/list
         //Languages supported includes:
         //Dutch, Spanish, German, Italian, French and English
         _ocr.Init("eng", false);
      }
 
      /// <summary>
      /// Detect license plate from the given image
      /// </summary>
      /// <param name="img">The image to search license plate from</param>
      /// <param name="licensePlateList">A list of images where the detected license plate region is stored</param>
      /// <param name="filteredLicensePlateList">A list of images where the detected license plate region with noise removed is stored</param>
      /// <param name="boxList">A list where the region of license plate, defined by an MCvBox2D is stored</param>
      /// <returns>The list of words for each license plate</returns>
      public List<List<Word>> DetectLicensePlate(Image<Bgr, byte> img, List<Image<Gray, Byte>> licensePlateList, List<Image<Gray, Byte>> filteredLicensePlateList, List<MCvBox2D> boxList)
      {
         //Stopwatch w = Stopwatch.StartNew();
         List<List<Word>> licenses = new List<List<Word>>();
         using (Image<Gray, byte> gray = img.Convert<Gray, Byte>())
         using (Image<Gray, Byte> canny = new Image<Gray, byte>(gray.Size))
         using (MemStorage stor = new MemStorage())
         {
            CvInvoke.cvCanny(gray, canny, 100, 50, 3);
 
            Contour<Point> contours = canny.FindContours(
                 Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE,
                 Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_TREE,
                 stor);
            FindLicensePlate(contours, gray, canny, licensePlateList, filteredLicensePlateList, boxList, licenses);
         }
         //w.Stop();
         return licenses;
      }
 
      private void FindLicensePlate(
         Contour<Point> contours, Image<Gray, Byte> gray, Image<Gray, Byte> canny,
         List<Image<Gray, Byte>> licensePlateList, List<Image<Gray, Byte>> filteredLicensePlateList, List<MCvBox2D> boxList,
         List<List<Word>> licenses)
      {
         for (; contours != null; contours = contours.HNext)
         {
            Contour<Point> approxContour = contours.ApproxPoly(contours.Perimeter * 0.05, contours.Storage);
 
            if (approxContour.Area > 100 && approxContour.Total == 4)
            {
               //img.Draw(contours, new Bgr(Color.Red), 1);
               if (!IsParallelogram(approxContour.ToArray()))
               {
                  Contour<Point> child = contours.VNext;
                  if (child != null)
                     FindLicensePlate(child, gray, canny, licensePlateList, filteredLicensePlateList, boxList, licenses);
                  continue;
               }
 
               MCvBox2D box = approxContour.GetMinAreaRect();
 
               double whRatio = (double)box.size.Width / box.size.Height;
               if (!(3.0 < whRatio && whRatio < 8.0))
               {
                  Contour<Point> child = contours.VNext;
                  if (child != null)
                     FindLicensePlate(child, gray, canny, licensePlateList, filteredLicensePlateList, boxList, licenses);
                  continue;
               }
 
               Image<Gray, Byte> plate = gray.Copy(box);
               Image<Gray, Byte> filteredPlate = FilterPlate(plate);
 
               List<Word> words;
               using (Bitmap bmp = filteredPlate.Bitmap)
                  words = _ocr.DoOCR(bmp, filteredPlate.ROI);
 
               licenses.Add(words);
               licensePlateList.Add(plate);
               filteredLicensePlateList.Add(filteredPlate);
               boxList.Add(box);
            }
         }
      }
 
      /// <summary>
      /// Check if the four points forms a parallelogram
      /// </summary>
      /// <param name="pts">The four points that defines a polygon</param>
      /// <returns>True if the four points defines a parallelogram</returns>
      private static bool IsParallelogram(Point[] pts)
      {
         LineSegment2D[] edges = PointCollection.PolyLine(pts, true);
 
         double diff1 = Math.Abs(edges[0].Length - edges[2].Length);
         double diff2 = Math.Abs(edges[1].Length - edges[3].Length);
         if (diff1 / edges[0].Length <= 0.05 && diff1 / edges[2].Length <= 0.05
            && diff2 / edges[1].Length <= 0.05 && diff2 / edges[3].Length <= 0.05)
         {
            return true;
         }
         return false;
      }
 
      /// <summary>
      /// Filter the license plate to remove noise
      /// </summary>
      /// <param name="plate">The license plate image</param>
      /// <returns>License plate image without the noise</returns>
      private static Image<Gray, Byte> FilterPlate(Image<Gray, Byte> plate)
      {
         Image<Gray, Byte> thresh = plate.ThresholdBinaryInv(new Gray(120), new Gray(255));
 
         using (Image<Gray, Byte> plateMask = new Image<Gray, byte>(plate.Size))
         using (Image<Gray, Byte> plateCanny = plate.Canny(new Gray(100), new Gray(50)))
         using (MemStorage stor = new MemStorage())
         {
            plateMask.SetValue(255.0);
            for (
               Contour<Point> contours = plateCanny.FindContours(
                  Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE,
                  Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_EXTERNAL,
                  stor);
               contours != null; contours = contours.HNext)
            {
               Rectangle rect = contours.BoundingRectangle;
               if (rect.Height > (plate.Height >> 1))
               {
                  rect.X -= 1; rect.Y -= 1; rect.Width += 2; rect.Height += 2;
                  rect.Intersect(plate.ROI);
 
                  plateMask.Draw(rect, new Gray(0.0), -1);
               }
            }
 
            thresh.SetValue(0, plateMask);
         }
 
         thresh._Erode(1);
         thresh._Dilate(1);
 
         return thresh;
      }
 
      protected override void DisposeObject()
      {
         _ocr.Dispose();
      }
   }
}

Open in new window


Definitely not the best but it's somewhere to start.

Good Luck!

p.s.

You can also try the DTK ANPR SDK shareware from http://www.softpedia.com/get/Programming/SDK-DDK/DTK-ANPR-SDK.shtml or many other software sites.
0
 

Author Comment

by:caznova
ID: 35714620
thanks sire for helping me ,but wen i run this code it have several errors so, if you could help me to find a sample form ready to testing and i will be thankful
0
 

Author Comment

by:caznova
ID: 35714628
0
 
LVL 8

Expert Comment

by:hello_everybody
ID: 35719740
The errors you have are caused by the fact that you're missing the prerequisites, see System requirements on quoted website for more info.
0
 
LVL 31

Expert Comment

by:James Murrell
ID: 36515739
This question has been classified as abandoned and is closed as part of the Cleanup Program. See the recommendation for more details.
0

Featured Post

Fill in the form and get your FREE NFR key NOW!

Veeam is happy to provide a FREE NFR server license to certified engineers, trainers, and bloggers.  It allows for the non‑production use of Veeam Agent for Microsoft Windows. This license is valid for five workstations and two servers.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Following on from our article on "The Murky World of Consent and opt in", we thought we would issue some helpful guidance, not only on consent itself but knowing what information you are capturing, what you are doing with this data and how you can p…
Strategic internal linking is often considered an SEO power technique, especially for content marketing. Do you need to hire an SEO agency to optimize you internal linking? No, this article will help you understand the basics of internal linking and…
The viewer will learn how to count occurrences of each item in an array.
Google currently has a new report that is in beta and coming soon to Webmaster Tool accounts. This Micro Tutorial will highlight new features for Google Webmaster Tools.
Suggested Courses
Course of the Month19 days, 16 hours left to enroll

872 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question