Showing posts with label OCR. Show all posts
Showing posts with label OCR. Show all posts

Tuesday, 12 September 2023

Deciphering the Digital Frontier: A Developer's Guide to OCR Technology.

Optical Character Recognition (OCR) technology has come a long way since its inception. From being a niche tool for digitizing printed text, it has evolved into a powerful and versatile solution with applications spanning industries like healthcare, finance, education, and more. In this blog, we will explore OCR from a developer's perspective, delving into its significance, challenges, and the technologies that drive it.

Understanding OCR

OCR, in essence, is the process of converting scanned or photographed text into machine-readable text. This enables computers to interpret, search, and manipulate text just as humans do. Developers play a critical role in harnessing the capabilities of OCR to develop applications and solutions that automate data entry, improve accessibility, and enhance data analysis.

The Significance of OCR

Data Extraction: OCR is a game-changer for extracting information from paper documents, invoices, receipts, and forms. Developers can create applications that automate data entry, saving time and reducing errors.

Accessibility: OCR technology makes printed or handwritten text accessible to people with visual impairments. Developers can build applications that read aloud or convert text into Braille, enhancing accessibility.

Text Analytics: OCR enables developers to perform advanced text analytics, sentiment analysis, and data mining on large volumes of scanned documents. This is invaluable in industries like finance, legal, and healthcare.

Challenges Faced by Developers

Developing OCR solutions isn't without its challenges. Here are some of the key hurdles developers face:

  • Quality of Source Material: The quality of the source material, such as the clarity of the text, lighting conditions, and document orientation, can significantly affect OCR accuracy.
  • Handwriting Recognition: Recognizing handwritten text is considerably more challenging than printed text due to variations in handwriting styles.
  • Multilingual Support: Developers often need to design OCR systems that can handle multiple languages and scripts, each with its unique challenges.
  • Scalability: Building scalable OCR solutions that can process large volumes of documents efficiently requires careful planning and optimization.

Technologies Driving OCR

Machine Learning: Modern OCR systems heavily rely on machine learning algorithms, particularly deep learning models like Convolutional Neural Networks (CNNs) and Recurrent Neural Networks (RNNs). These models learn to recognize patterns in text and improve accuracy over time.

Preprocessing Techniques: Image preprocessing plays a crucial role in OCR. Techniques like image binarization, noise reduction, and text skew correction help improve OCR results.

Language Models: Language models like BERT and GPT have also found applications in OCR, particularly for contextual understanding and improving accuracy in complex documents.

Cloud Services: Many developers leverage cloud-based OCR services provided by companies like Google, Microsoft, and Amazon. These services offer scalable, highly accurate OCR capabilities without the need for extensive infrastructure.

Best Practices for OCR Development

To develop effective OCR solutions, developers should consider the following best practices:

  • Quality Data: Train OCR models with high-quality, diverse datasets to improve accuracy.
  • Continuous Learning: Implement mechanisms for model retraining and fine-tuning to adapt to changing data and improve performance over time.
  • Scalability: Design OCR systems that can handle varying workloads and scale dynamically as needed.
  • Error Handling: Develop robust error-handling mechanisms to deal with ambiguous or challenging text recognition scenarios.
  • User Interface: Ensure that the OCR solution provides a user-friendly interface for easy integration into applications and workflows.

Conclusion

From automating data entry to enhancing accessibility and enabling advanced text analytics, OCR technology is a powerful tool in the hands of developers. By understanding the significance, challenges, and technologies that drive OCR, developers can create innovative solutions that transform text from pixels into valuable, actionable data. The future of OCR holds even more promise, with ongoing advancements in artificial intelligence and machine learning set to further improve accuracy and expand its range of applications. 

Certainly, for more details on Android OCR (Optical Character Recognition), you can refer to the following blog post:

Android OCR (Optical Character Recognition)

This blog post delves into the world of Android OCR (Optical Character Recognition), offering insights into how developers can implement OCR technology on Android devices. It likely discusses various OCR libraries, tools, and techniques suitable for Android app development, making it a valuable resource for those interested in integrating text recognition capabilities into their Android applications.

Thursday, 15 September 2016

HB Blog 119: Android OCR - Optical Character Recognition.

Optical character recognition (optical character reader, OCR) is the mechanical or electronic conversion of images of typed, handwritten or printed text into machine-encoded text, whether from a scanned document, a photo of a document, a scene-photo (for example the text on signs and billboards in a landscape photo) or from subtitle text superimposed on an image (for example from a television broadcast). It is widely used as a form of information entry from printed paper data records, whether passport documents, invoices, bank statements, computerised receipts, business cards, mail, printouts of static-data, or any suitable documentation. It is a common method of digitising printed texts so that they can be electronically edited, searched, stored more compactly, displayed on-line, and used in machine processes such as cognitive computing, machine translation, (extracted) text-to-speech, key data and text mining. OCR is a field of research in pattern recognition, artificial intelligence and computer vision.
Android-OCR :-
An experimental app for Android that performs optical character recognition (OCR) on images captured using the device camera.
Runs the Tesseract OCR engine using tess-two, a fork of Tesseract Tools for Android.
Most of the code making up the core structure of this project has been adapted from the ZXing Barcode Scanner. Along with Tesseract-OCR and Tesseract Tools for Android (tesseract-android-tools), several open source projects have been used in this project, including leptonica, google-api-translate-java, microsoft-translator-java-api, and jtar.

Training data for OCR :-
A data file is required for every language you want to recognize. For English, this data file is included in the application assets and is automatically installed when the app is first run.
For other languages (Spanish, French, Chinese, etc.), the app will try to download the training data from an old Google Code repository that is no longer available, and the download fails. So if you want to use training data for other languages, you'll need to package the appropriate training data files in the app or change the code to point to your own download location.

Refer the below link for complete sample code:-

Download Sample Code

Have a look on few code snippets,

//build.gradle
 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
apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"

    defaultConfig {
        applicationId "com.example.harshalbenake.ocrtessarct"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:23.3.0'
    compile 'com.rmtheis:tess-two:5.4.1'
}
 
//activity_main.xml
 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
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.harshalbenake.ocrtessarct.MainActivity">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:text="Open Image" />

    <TextView
        android:id="@+id/textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:layout_below="@+id/button"
        android:textColor="@android:color/black"
        android:textSize="16sp" />

</RelativeLayout>
 
//MainActivity.java
 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
package com.example.harshalbenake.ocrtessarct;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {

    private static final int sRC_Document = 1000;
    private final String sdCardPath = Environment.getExternalStorageDirectory() + "/";
    private TessOCR mTessOCR;
    private TextView mTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTessOCR = new TessOCR(MainActivity.this);

        mTextView = (TextView) findViewById(R.id.textview);
        Button button = (Button) findViewById(R.id.button);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startCustomFileBrowserActivity();


               /* Bitmap bitmap = BitmapFactory.decodeFile(sdCardPath + "3.jpg");
                String strResult = tessOCR.getOCRResult(bitmap);
                System.out.println("strResult: " + strResult);
                textView.setText(strResult);*/
            }
        });
    }

    /**
     * Intent start CustomFileBrowserActivity.
     **/
    public void startCustomFileBrowserActivity() {
        Intent intent = new Intent(MainActivity.this, CustomFileBrowser.class);
        startActivityForResult(intent, sRC_Document);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
        switch (requestCode) {
            case sRC_Document:
                if (resultCode == RESULT_OK) {
                    try {
                        final String filePath = intent.getStringExtra("data");
                        if (filePath != null) {
                            Bitmap bitmap = BitmapFactory.decodeFile(filePath);
                            String strResult = mTessOCR.getOCRResult(bitmap);
                            mTextView.setText("Result Data: \n\n" + strResult);
                        } else {
                            //invalid file
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                break;
        }
        super.onActivityResult(requestCode, resultCode, intent);
    }
}

//TessOCR.java
  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
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package com.example.harshalbenake.ocrtessarct;

import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.os.Environment;
import android.util.Log;

import com.googlecode.tesseract.android.TessBaseAPI;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;


public class TessOCR {
    private TessBaseAPI mTess;
    Context mContext;

    public TessOCR(Context context) {
        // TODO Auto-generated constructor stub
        this.mContext=context;
        setupOCR();
        mTess = new TessBaseAPI();
        String datapath = Environment.getExternalStorageDirectory() + "/tesseract/";
        File dir = new File(datapath + "tessdata/");
        if (!dir.exists())
            dir.mkdirs();
        mTess.init(datapath, "eng");
    }


    public String getOCRResult(Bitmap bitmap) {
        mTess.setImage(bitmap);
        String result=mTess.getUTF8Text();
      //  mTess.end();
//        if(result!=null) {
            return result.replaceAll("[^A-Za-z0-9 ]", "");
//        }else{
//            return "";
//        }
    }

    public void onDestroy() {
        mTess.end();
    }

    public void setupOCR(){

        File folder = new File(Environment.getExternalStorageDirectory() + "/tesseract/tessdata");
        if (!folder.exists()) {
            folder.mkdirs();
        }

        File saving = new File(folder, "eng.traineddata");
        try {
            saving.createNewFile();
        } catch (Exception e) {
            e.printStackTrace();
        }

        InputStream stream = null;
        try {
            stream = mContext.getAssets().open("eng.traineddata", AssetManager.ACCESS_STREAMING);
        } catch (Exception e) {
            e.printStackTrace();
        }


        if (stream != null){
            copyInputStreamToFile(stream, saving);
        }
    }

    private void copyInputStreamToFile( InputStream in, File file ) {
        try {
            OutputStream out = new FileOutputStream(file);
            byte[] buf = new byte[1024];
            int len;
            while((len=in.read(buf))>0){
                out.write(buf,0,len);
            }
            out.close();
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void copyAssets() {
        AssetManager assetManager = mContext.getAssets();
        String[] files = null;
        try {
            files = assetManager.list("");
        } catch (Exception e) {
            Log.e("tag", "Failed to get asset file list.", e);
        }
        if (files != null) for (String filename : files) {
            InputStream in = null;
            OutputStream out = null;
            try {
                System.out.println("filename: "+filename);
                in = assetManager.open(filename);

                String datapath = Environment.getExternalStorageDirectory() + "/tesseract/";
                File dir = new File(datapath + "tessdata/");
                if (!dir.exists())
                    dir.mkdirs();

                File outFile = new File(dir+filename);
                out = new FileOutputStream(outFile);
                copyFile(in, out);
            } catch(Exception e) {
                Log.e("tag", "Failed to copy asset file: " + filename, e);
            }
            finally {
                if (in != null) {
                    try {
                        in.close();
                    } catch (Exception e) {
                        // NOOP
                    }
                }
                if (out != null) {
                    try {
                        out.close();
                    } catch (Exception e) {
                        // NOOP
                    }
                }
            }
        }
    }

    private void copyFile(InputStream in, OutputStream out) throws Exception {
        byte[] buffer = new byte[1024];
        int read;
        while((read = in.read(buffer)) != -1){
            out.write(buffer, 0, read);
        }
    }

}