Vous êtes sur la page 1sur 9

Lampiran 1.

Listing Kode Program Form Utama


using
using
using
using
using
using
using
using
using
using
using
using

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

Point startPoint = new Point(10, 10);


for (int i = 0; i < words.Count; i++)
{
if (words[i].Length >= 5)
{
int nilai = words[i].Length - 1;
if (nilai >= 11) nilai = 10;
words[i] = words[i].Substring(0, nilai);
AddLabelAndImage(
ref startPoint,
String.Format("{0}", words[i]),
licensePlateImagesList[i].ConcateVertical(filteredLicensePlateImag
esList[i]));
image.Draw(licenseBoxList[i], new
Bgr(Color.Blue), 2);
}
}
imageBox1.Image = image;
}
private void AddLabelAndImage(ref Point startPoint, String
labelText, IImage image)
{
Label label = new Label();
panel1.Controls.Add(label);
label.Text = labelText;
label.Width = 100;
label.Height = 30;
label.Location = startPoint;
startPoint.Y += label.Height;
ImageBox box = new ImageBox();
panel1.Controls.Add(box);
box.ClientSize = image.Size;
box.Image = image;
box.Location = startPoint;
startPoint.Y += box.Height + 10;
}
Image<Bgr, Byte> img_global;
private void button1_Click(object sender, EventArgs e)
{
DialogResult result = openFileDialog1.ShowDialog();
if (result == DialogResult.OK)
{
Image<Bgr, Byte> img;
try
{

76

img = new Image<Bgr,


byte>(openFileDialog1.FileName);
}
catch
{
MessageBox.Show(String.Format("File Tidak Valid:
{0}", openFileDialog1.FileName));
return;
}
img_global = img;
}
}
private void button2_Click(object sender, EventArgs e)
{
Ttutorial ttut1 = new Ttutorial();
ttut1.Show();
}
private void button3_Click(object sender, EventArgs e)
{
float th1, th2;
th1 = (float)Convert.ToDouble(th1txt.Text);
th2 = (float)Convert.ToDouble(th2txt.Text);
_licensePlateDetector = new LicensePlateDetector("",
th1, th2);
ProcessImage(img_global);
}
}
}

77

Lampiran 2. Kode Program Class LicensePlateDetector


using
using
using
using
using
using
using
using
using

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;
}

// mencari piksel putih pada gambar


private static Image<Gray, Byte>
GetWhitePixelMask(Image<Bgr, byte> image)
{
// mengkonversi gambar dengan nilai hue dan saturation
tertentu
using (Image<Hsv, Byte> hsv = image.Convert<Hsv,
Byte>())
{
// memecah gambar grayscale menjagi array gambar
biner
Image<Gray, Byte>[] channels = hsv.Split();
try
{
// channel 1 untuk saturasi kurang dari 40. mask
untuk hitam ataupun putih

78

channels[1]._ThresholdBinaryInv(new Gray(40), new


Gray(255));
// channels 2 untuk piksel terang.
channels[2]._ThresholdBinary(new Gray(150), new
Gray(255));
CvInvoke.cvAnd(channels[1], channels[2],
channels[0], IntPtr.Zero);
}
finally
{
channels[1].Dispose();
channels[2].Dispose();
}
return channels[0];
}
}
public List<String> Deteksi(
Image<Bgr, byte> img,
List<Image<Gray, Byte>> licensePlateImagesList,
List<Image<Gray, Byte>> filteredLicensePlateImagesList,
List<MCvBox2D> detectedLicensePlateRegionList)
{
// mengubah gambar img menjadi grayscale
List<String> licenses = new List<String>();
using (Image<Gray, byte> gray = img.Convert<Gray,
Byte>())
//using (Image<Gray, byte> gray = GetWhitePixelMask(img))
using (Image<Gray, Byte> canny = new Image<Gray,
byte>(gray.Size))
using (MemStorage stor = new MemStorage())
{
// cvcanny digunakan untuk menemukan tepi gambar dan
menandainya sebagai gambar keluaran
CvInvoke.cvCanny(gray, canny, 100, 50, 3);
// menemukan kontur dengan memstorage
Contour<Point> kontur = canny.FindContours(
Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE,
Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_TREE,
stor);
FindLicensePlate(kontur, gray, canny,
licensePlateImagesList, filteredLicensePlateImagesList,
detectedLicensePlateRegionList, licenses);
}
return licenses;
}
// mendapatkan karakter dalam area plat nomor
// membaca karakter dari kiri ke kanan
private static int GetNumberOfChildren(Contour<Point>
contours)

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

float tmp = box.size.Width;


box.size.Width = box.size.Height;
box.size.Height = tmp;
box.angle -= 90.0f;
}
// Menentukan ukuran rasio plat nomor
double whRatio = (double)box.size.Width /
box.size.Height;
if (!(2.0 < whRatio && whRatio < 4.0))
{
Contour<Point> child = contours.VNext;
if (child != null)
FindLicensePlate(child, gray, canny,
licensePlateImagesList, filteredLicensePlateImagesList,
detectedLicensePlateRegionList, licenses);
continue;
}
using (Image<Gray, Byte> tmp1 = gray.Copy(box))
using (Image<Gray, Byte> tmp2 = tmp1.Resize(240,
180, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC, true))
{
//roi = region of interest
int edgePixelSize = 2;
tmp2.ROI = new Rectangle(new
Point(edgePixelSize, edgePixelSize), tmp2.Size - new Size(2 *
edgePixelSize, 2 * edgePixelSize));
Image<Gray, Byte> plate = tmp2.Copy();
Image<Gray, Byte> filteredPlate =
FilterPlate(plate, gray_thresh, gray_max);
// words adalah array untuk membaca karakter
Tesseract.Charactor[] words;
// strbuilder digunakan untuk mengubah array karakter yang didapat
StringBuilder strBuilder = new StringBuilder();
using (Image<Gray, Byte> tmp =
filteredPlate.Clone())
{
_ocr.Recognize(tmp);
words = _ocr.GetCharactors();
if (words.Length == 0) continue;
for (int i = 0; i < words.Length; i++)
{
strBuilder.Append(words[i].Text);
}
}
// menghasilkan copy output sebelah kiri
licenses.Add(strBuilder.ToString());
licensePlateImagesList.Add(plate);

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

Vous aimerez peut-être aussi