Showing posts with label vb. Show all posts
Showing posts with label vb. Show all posts

Monday 12 October 2015

VB :: Optical Character Recognition (OCR) Untuk Pembacaan kWh PLN Menggunakan VB dan EmguCV


Untuk proses pertama saya akan memperkenalkan apa itu OCR.
Optical Character Recognition adalah teknologi yang dapat mengekstrak teks dari sebuah gambar dengan cara men-scan dokumen sehingga bisa diedit, diformat, dicari, diindeks, atau diterjemahkan secara otomatis. Saya mengambil contoh kasus disini pada penggunaan kWh meter PLN, yang bertujuan dengan sistem tersebut data hasil pemotretan meteran listrik. dapat dengan cepat dibaca dan dihasilkan nomor meteran kWh listrik dan nomor pelanggannya
Berikut ini metode yang saya gunakan untuk dapat membaca character imagenya. Dan Tahapan-tahapan yang dipakai yaitu capture, prepare image, localize, connected component analysis, segmentation, dan character recognition seperti pada Gambar 2. Sistem ini dibuat agar bisa mendeteksi 2 plat tersebut dan membedakan angka Kwh dan angka nomor pelanggan.
 
Gambar 2
A.    Capture
Pada tahap ini, gambar dari kWh meter PLN diambil dengan kamera yang beresolusi tinggi untuk meningkatkan rasio keberhasilan yaitu kWh meter pada Gambar 3.
B.    Prepare Image
Pada tahap ini dilakukan pendeteksian label merah pada nomor pelanggan dan menghilangkan label merah tersebut. Label merah akan mempengaruhi hasil dari tahapan localize sehingga karakter yang ingin dideteksi tidak terbaca dikarenakan gradasi warna antara angka dan label merah.  Kita akan menggunakan histogramchannel merah pada label merah yang sudah ditandai posisinya dengan menentukan rentang warna merah yang lebih terang. Setelah itu, bandingkan gambar berlabel merah dengan rentang yang telah ditentukan dan cocokkan lalu ganti pixel-nya menjadi warna putih.
C.    Localize
Gambar hasil preprocess diubah ke dalam bentuk binarisasi gambar, gambar dikonverter ke hitam dan putih untuk menyorot karakter dan memperjelasbackground. Tahapan ini dilakukan dengan menggunakan teknik tharesholding, dapat dilihat pada Gambar 4.
D.    Connected component analysis
Pada tahap ini, karakter pada gambar diidentifikasi dengan mencari pixel yang terhubung. Apabila telah ditemukan maka kumpulan karakter diberi label.
E.    Segmentation
Pada tahap ini dilakukan proses pemotongan gambar yang telah diberi label dengan menggunakan algoritma Image Scissoring. Gambar ditelusuri secara vertikal dan horizontal, dan akan memotong daerah yang tidak terdapat warna putih lalu disimpan secara terpisah.
F.    Character Recognition
Kumpulan karakter yang telah dipisah diterjemahkan oleh mesin OCR dan menghasilkan kode ASCII, dapat dilihat pada Gambar 5.  
Gambar 3

Gambar 4

Gambar 5
Dan berikut ini adalah code untuk pembacaan karakter yang ada dalam image, dan saya batasi hanya untuk angka saja.
1
2
3
4
5
6
7
8
9
10
public partial class OCRForm : Form
    {
        private Tesseract _ocr;
        public OCRForm()
        {
            InitializeComponent();
            _ocr = new Tesseract("tessdata", "eng", Tesseract.OcrEngineMode.OEM_TESSERACT_CUBE_COMBINED);
            _ocr.SetVariable("tessedit_char_whitelist", "1234567890");
            //languageNameLabel.Text = "eng : tesseract + cube";
        }
Lalu berikut ini code untuk menghilangkan label merah yang terdapat angka.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
private Image<Bgr, Byte> replaceRedLabel(Image<Bgr, Byte> mimage)
        {
            Image<Bgr, Byte> image = mimage.Clone();
     
            double mhRs = 130;
            double mhRe = 170;
 
            double mhGs = 40;
            double mhGe = 70;
 
            double mhBs = 50;
            double mhBe = 80;
 
            // % ---------------------------- %
 
            double mpRs = mhRe + 1;
            double mpRe = 230;
 
            double mpGs = 40;
            double mpGe = 80;
 
            double mpBs = 60;
            double mpBe = 100;
 
            // % ---------------------------- %
 
            int r = image.Size.Height;
            int c = image.Size.Width;
 
            Debug.WriteLine("Start digging");
 
            int blue = 0;
            int green = 1;
            int red = 2;
 
            for (int i = 0; i < r; i++)
            {
                for (int j = 0; j < c; j++)
                    //% merah putih.
                    if ((image.Data[i, j, red] >= mpRs && image.Data[i, j, red] <= mpRe) && (image.Data[i, j, green] >= mpGs && image.Data[i, j, green] <= mpGe) && (image.Data[i, j, blue] >= mpBs && image.Data[i, j, blue] <= mpBe))
                    {
                        //Debug.WriteLine("Going in red-white");
                        //Debug.WriteLine("RW: "+image2.Data[i,j,0]);
                        image.Data[i, j, blue] = 255;
                        image.Data[i, j, green] = 255;
                        image.Data[i, j, red] = 255;
                    }
                    else if ((image.Data[i, j, red] >= mhRs && image.Data[i, j, red] <= mhRe) && (image.Data[i, j, green] >= mhGs && image.Data[i, j, green] <= mhGe) && (image.Data[i, j, blue] >= mhBs && image.Data[i, j, blue] <= mhBe))
                    {
                        //Debug.WriteLine("Going in red-black");
                        //Debug.WriteLine("RB: " + image2.Data[i, j, 0]);
                        image.Data[i, j, blue] = 0;
                        image.Data[i, j, green] = 0;
                        image.Data[i, j, red] = 0;
                    }
            }
 
            return image;
        }
 
        private Image<Hsv, Byte> replaceRedLabelHSV(Image<Bgr, Byte> mimage)
        {
            Image<Hsv, Byte> image = mimage.Convert<Hsv, Byte>().Clone();
            int hue = 0;
            int saturation = 1;
            int value = 2;
 
            int w = image.Width;
            int h = image.Height;
 
            for (int i = 0; i < h; i++)
            {
                for (int j = 0; j < w; j++)
                {
                    //Debug.WriteLine(image.Data[i, j, hue]);
                    if (image.Data[i, j, hue] > (170))
                    {
                        //image.Data[i, j, saturation] = 0;
                        image.Data[i, j, value] = 255;
                    }
                }
            }
 
            return image;
        }
dan berikut ini hasil keseluruhannya.