Académique Documents
Professionnel Documents
Culture Documents
System;
System.Collections.Generic;
System.ComponentModel;
System.Data;
System.Drawing;
System.Text;
System.Windows.Forms;
Emgu.CV;
Emgu.CV.Structure;
Emgu.CV.UI;
Emgu.CV.OCR;
System.Diagnostics;
namespace LicensePlateRecognition
{
public partial class LicensePlateRecognitionForm : Form
{
private LicensePlateDetector _licensePlateDetector;
public LicensePlateRecognitionForm()
{
InitializeComponent();
_licensePlateDetector = new LicensePlateDetector("", 170,
255);
ProcessImage(new Image<Bgr, byte>("license-plate.jpg"));
}
private void ProcessImage(Image<Bgr, byte> image)
{
Stopwatch watch = Stopwatch.StartNew(); // time the
detection process
List<Image<Gray, Byte>> licensePlateImagesList = new
List<Image<Gray, byte>>();
List<Image<Gray, Byte>> filteredLicensePlateImagesList =
new List<Image<Gray, byte>>();
List<MCvBox2D> licenseBoxList = new List<MCvBox2D>();
List<string> words = _licensePlateDetector.Deteksi(
image,
licensePlateImagesList,
filteredLicensePlateImagesList,
licenseBoxList);
watch.Stop(); //stop the timer
processTimeLabel.Text = String.Format("Waktu Deteksi: {0}
milli-seconds", watch.Elapsed.TotalMilliseconds);
panel1.Controls.Clear();
75
76
77
System;
System.Collections.Generic;
System.Diagnostics;
System.Drawing;
System.Text;
Emgu.CV;
Emgu.CV.OCR;
Emgu.CV.Structure;
Emgu.Util;
namespace LicensePlateRecognition
{
public class LicensePlateDetector : DisposableObject
{
private Tesseract _ocr;
private float gray_thresh;
private float gray_max;
public LicensePlateDetector(String dataPath, float th1, float
th2){
// membuat OCR engine
_ocr = new Tesseract("tessdata", "eng",
Tesseract.OcrEngineMode.OEM_TESSERACT_CUBE_COMBINED);
_ocr.SetVariable("tessedit_char_whitelist",
"ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890");
this.gray_thresh = th1;
this.gray_max = th2;
}
78
79
{
Contour<Point> child = contours.VNext;
if (child == null) return 0;
int count = 0;
while (child != null)
{
count++;
child = child.HNext;
}
return count;
}
private void FindLicensePlate(
Contour<Point> contours, Image<Gray, Byte> gray,
Image<Gray, Byte> canny,
List<Image<Gray, Byte>> licensePlateImagesList,
List<Image<Gray, Byte>>
filteredLicensePlateImagesList, List<MCvBox2D>
detectedLicensePlateRegionList,
List<String> licenses)
{
for (; contours != null; contours = contours.HNext)
{
int numberOfChildren = GetNumberOfChildren(contours);
//jika tidak mengandung karakter dianggap bukan area
plat nomor.
if (numberOfChildren == 0) continue;
//jika area kontur lebih dari 100 piksel dianggap
karakter
if (contours.Area > 100)
{
// minimal karakter dalam plat nomor
if (numberOfChildren < 4)
{
FindLicensePlate(contours.VNext, gray, canny,
licensePlateImagesList, filteredLicensePlateImagesList,
detectedLicensePlateRegionList, licenses);
continue;
}
//Perbaikan sudut area
// getminrect = u/ mendapatkan area minimum persegi panjang
MCvBox2D box = contours.GetMinAreaRect();
if (box.angle < -45.0)
{
float tmp = box.size.Width;
box.size.Width = box.size.Height;
box.size.Height = tmp;
box.angle += 90.0f;
}
else if (box.angle > 45.0)
{
80
81
filteredLicensePlateImagesList.Add(filteredPlate);
detectedLicensePlateRegionList.Add(box);
}
}
}
}
//penyaring / filter plat nomor
private static Image<Gray, Byte> FilterPlate(Image<Gray,
Byte> plate, float gray_threshx, float gray_maxx)
{
/*>>>>*/
float nilai1, nilai2;
nilai1 = gray_threshx;
nilai2 = gray_maxx;
nilai1 = (float)Convert.ToInt32(nilai1);
nilai2 = (float)Convert.ToInt32(nilai2);
Image<Gray, Byte> thresh = plate.ThresholdBinaryInv(new
Gray(nilai1), new Gray(nilai2));
using (Image<Gray, Byte> plateMask = new Image<Gray,
byte>(plate.Size))
using (Image<Gray, Byte> plateCanny = plate.Canny(120,
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);
}
// erosi dan dilasi menggunakan struktur elemen persegi 3x3
thresh._Erode(1);
thresh._Dilate(1);
return thresh;
82
}
protected override void DisposeObject()
{
_ocr.Dispose();
}
}
}
83