Title: Using Tesseract OCR with Python - PyTesseract - PyImageSearch

URL Source: https://pyimagesearch.com/2017/07/10/using-tesseract-ocr-python/

Published Time: 2017-07-10T14:00:25+00:00

Markdown Content:
Last updated on Feb 13, 2024.

![Image 1: Noisy Image to Test Tesseract OCR](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20381'%3E%3C/svg%3E)

In last week’s blog post we learned [how to install the Tesseract binary](https://pyimagesearch.com/2017/07/03/installing-tesseract-for-ocr/) for Optical Character Recognition (OCR).

We then applied the Tesseract program to test and evaluate the performance of the OCR engine on a very small set of example images.

A dataset is instrumental for Optical Character Recognition (OCR) tasks because it enables the model to learn and understand various fonts, sizes, and orientations of text. This in turn leads to improved OCR accuracy in real-world applications.

[Roboflow](https://roboflow.com/?ref=pyimagesearch) has free tools for each stage of the computer vision pipeline that will streamline your workflows and supercharge your productivity.

Sign up or Log in to your [Roboflow account](https://roboflow.com/?ref=pyimagesearch) to access state of the art dataset libaries and revolutionize your computer vision pipeline.

You can start by choosing your own datasets or using our [PyimageSearch’s assorted library of useful datasets](https://universe.roboflow.com/pyimagesearch?ref=pyimagesearch).

Bring data in any of 40+ formats to [Roboflow](https://roboflow.com/?ref=pyimagesearch), train using any state-of-the-art model architectures, deploy across multiple platforms (API, NVIDIA, browser, iOS, etc), and connect to applications or 3rd party tools.

As our results demonstrated, Tesseract works best when there is a (very) clean segmentation of the foreground text from the background. In practice, it can be extremely challenging to guarantee these types of segmentations. Hence, we tend to train domain-specific image classifiers and detectors.

Nevertheless, it’s important that we understand how to access Tesseract OCR via the Python programming language in the case that we need to apply OCR to our own projects (provided we can obtain the nice, clean segmentations required by Tesseract).

Example projects involving OCR may include [building a mobile document scanner](https://pyimagesearch.com/2014/09/01/build-kick-ass-mobile-document-scanner-just-5-minutes/) that you wish to extract textual information from or perhaps you’re running a service that scans paper medical records and you’re looking to put the information into a HIPA-Compliant database.

In the remainder of this blog post, we’ll learn how to install the Tesseract OCR + Python “bindings” followed by writing a simple Python script to call these bindings. By the end of the tutorial, you’ll be able to convert text in an image to a Python string data type.

**To learn more about using Tesseract and Python together with OCR, _just keep reading._**

*   **Update Feb 2024:** Added section detailing how Tesseract version can have huge impacts on OCR accuracy.

![Image 2](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20128%20128'%3E%3C/svg%3E)

#### Looking for the source code to this post?

[Jump Right To The Downloads Section](#download-the-code)

This blog post is divided into three parts.

First, we’ll learn how to install the [pytesseract package](https://github.com/madmaze/pytesseract) so that we can access Tesseract via the Python programming language.

Next, we’ll develop a simple Python script to load an image, binarize it, and pass it through the Tesseract OCR system.

Finally, we’ll test our OCR pipeline on some example images and review the results.

To download the source code + example images to this blog post, be sure to use the _**“Downloads”**_ section below.

### Installing the Tesseract + Python “bindings”

Let’s begin by getting `pytesseract` installed. To install `pytesseract` we’ll take advantage of `pip` .

If you’re using a virtual environment (which I highly recommend so that you can separate different projects), use the `workon` command followed by the appropriate virtual environment name. In this case, our virtualenv is named `cv`.

$ workon cv

Next let’s install [Pillow](https://python-pillow.org/), a more Python-friendly port of PIL (a dependency) followed by `pytesseract`.

$ pip install pillow
$ pip install pytesseract

_**Note**: `pytesseract` does not provide true Python bindings. Rather, it simply provides an interface to the `tesseract` binary. If you [take a look at the project on GitHub](https://github.com/madmaze/pytesseract) you’ll see that the library is writing the image to a temporary file on disk followed by calling the `tesseract` binary on the file and capturing the resulting output. This is definitely a bit hackish, but it gets the job done for us._

Let’s move forward by reviewing some code that segments the foreground text from the background and then makes use of our freshly installed `pytesseract`.

### Applying OCR with Tesseract and Python

Let’s begin by creating a new file named `ocr.py`:

\# import the necessary packages
from PIL import Image
import pytesseract
import argparse
import cv2
import os

# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add\_argument("-i", "--image", required=True,
	help="path to input image to be OCR'd")
ap.add\_argument("-p", "--preprocess", type=str, default="thresh",
	help="type of preprocessing to be done")
args = vars(ap.parse\_args())

**Lines 2-6** handle our imports. The `Image` class is required so that we can load our input image from disk in PIL format, a requirement when using `pytesseract`.

Our command line arguments are parsed on **Lines 9-14**. We have two command line arguments:

*   `--image`: The path to the image we’re sending through the OCR system.
*   `--preprocess`: The preprocessing method. This switch is optional and for this tutorial and can accept two values: `thresh` (threshold) or `blur`.

Next we’ll load the image, binarize it, and write it to disk.

\# load the example image and convert it to grayscale
image = cv2.imread(args\["image"\])
gray = cv2.cvtColor(image, cv2.COLOR\_BGR2GRAY)

# check to see if we should apply thresholding to preprocess the
# image
if args\["preprocess"\] == "thresh":
	gray = cv2.threshold(gray, 0, 255,
		cv2.THRESH\_BINARY | cv2.THRESH\_OTSU)\[1\]

# make a check to see if median blurring should be done to remove
# noise
elif args\["preprocess"\] == "blur":
	gray = cv2.medianBlur(gray, 3)

# write the grayscale image to disk as a temporary file so we can
# apply OCR to it
filename = "{}.png".format(os.getpid())
cv2.imwrite(filename, gray)

First, we load `--image` from disk into memory (**Line 17**) followed by converting it to grayscale (**Line 18**).

Next, depending on the pre-processing method specified by our command line argument, we will either threshold or blur the image. This is where you would want to add more advanced pre-processing methods (depending on your specific application of OCR) which are beyond the scope of this blog post.

The `if` statement and body on **Lines 22-24** perform a threshold in order to segment the foreground from the background. We do this using both `cv2.THRESH_BINARY` and `cv2.THRESH_OTSU` flags. For details on Otsu’s method, see _“Otsu’s Binarization”_ in the [official OpenCV documentation](http://docs.opencv.org/trunk/d7/d4d/tutorial_py_thresholding.html).

We will see later in the results section that this thresholding method can be useful to read dark text that is overlaid upon gray shapes.

Alternatively, a blurring method may be applied. **Lines 28-29** perform a median blur when the `--preprocess` flag is set to `blur`. Applying a median blur can help reduce salt and pepper noise, again making it easier for Tesseract to correctly OCR the image.

After pre-processing the image, we use `os.getpid` to derive a temporary image `filename` based on the process ID of our Python script (**Line 33**).

The final step before using `pytesseract` for OCR is to write the pre-processed image, `gray`, to disk saving it with the `filename` from above (**Line 34**).

We can finally apply OCR to our image using the Tesseract Python “bindings”:

\# load the image as a PIL/Pillow image, apply OCR, and then delete
# the temporary file
text = pytesseract.image\_to\_string(Image.open(filename))
os.remove(filename)
print(text)

# show the output images
cv2.imshow("Image", image)
cv2.imshow("Output", gray)
cv2.waitKey(0)

Using `pytesseract.image_to_string` on **Line 38** we convert the contents of the image into our desired string, `text`. Notice that we passed a reference to the temporary image file residing on disk.

This is followed by some cleanup on **Line 39** where we delete the temporary file.

**Line 40** is where we print text to the terminal. In your own applications, you may wish to do some additional processing here such as spellchecking for OCR errors or Natural Language Processing rather than simply printing it to the console as we’ve done in this tutorial.

Finally, **Lines 43 and 44** handle displaying the original image and pre-processed image on the screen in separate windows. The `cv2.waitKey(0)` on **Line 34** indicates that we should wait until a key on the keyboard is pressed before exiting the script.

Let’s see our handywork in action.

### Tesseract OCR and Python results

Now that `ocr.py` has been created, it’s time to apply Python + Tesseract to perform OCR on some example input images.

In this section, we will try OCR’ing three sample images using the following process:

*   First, we will run each image through the Tesseract binary as-is.
*   Then we will run each image through `ocr.py` (which performs pre-processing before sending through Tesseract).
*   Finally, we will compare the results of both of these methods and note any errors.

Our first example is a “noisy” image. This image contains our desired foreground black text on a background that is partly white and partly scattered with artificially generated circular blobs. The blobs act as “distractors” to our simple algorithm.

![Image 3: Example image for testing a noisy image with tesseract binary](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20500%20250'%3E%3C/svg%3E)

**Figure 1:** Our first example input for Optical Character Recognition using Python.

Using the Tesseract binary, [as we learned last week](https://pyimagesearch.com/2017/07/03/installing-tesseract-for-ocr/), we can apply OCR to the raw, unprocessed image:

$ tesseract images/example\_01.png stdout
Noisy image
to test
Tesseract OCR

Tesseract performed well with no errors in this case.

Now let’s confirm that our newly made script, `ocr.py`, also works:

$ python ocr.py --image images/example\_01.png
Noisy image
to test
Tesseract OCR

![Image 4: Example image for testing a noisy image with pytesseract](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20395'%3E%3C/svg%3E)

**Figure 2:** Applying image preprocessing for OCR with Python.

As you can see in this screenshot, the thresholded image is very clear and the background has been removed. Our script correctly prints the contents of the image to the console.

Next, let’s test Tesseract and our pre-processing script on an image with “salt and pepper” noise in the background:

![Image 5: Example image where Tesseract will fail with noisy background.](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20500%20250'%3E%3C/svg%3E)

**Figure 3:** An example input image containing noise. This image will “confuse” our OCR algorithm, leading to incorrect OCR results.

We can see the output of the `tesseract` binary below:

$ tesseract images/example\_02.png stdout
Detected 32 diacritics
" Tesséra‘c't Will
Fail With Noisy
Backgrounds

Unfortunately, Tesseract did not successfully OCR the text in the image.

However, by using the `blur` pre-processing method in `ocr.py` we can obtain better results:

$ python ocr.py --image images/example\_02.png --preprocess blur
Tesseract Will
Fail With Noisy
Backgrounds

![Image 6: Noisy image preprocessing with Pytesseract and OpenCV to improve OCR results](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20326'%3E%3C/svg%3E)

**Figure 4:** Applying image preprocessing with Python and OpenCV to improve OCR results.

Success! Our blur pre-processing step enabled Tesseract to correctly OCR and output our desired text.

Finally, let’s try another image, this one with more text:

![Image 7: 2 paragraph example to test Tesseract + Python OCR system](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20468%20365'%3E%3C/svg%3E)

**Figure 5:** Another example input to our Tesseract + Python OCR system.

The above image is a screenshot from the _“Prerequisites”_ section of my book, _[Practical Python and OpenCV](https://pyimagesearch.com/practical-python-opencv/)_ — let’s see how the Tesseract binary handles this image:

$ tesseract images/example\_03.png stdout
PREREQUISITES

In order In make the rnosi of this, you will need (a have
a little bit of pregrarrmung experience. All examples in this
book are in the Python programming language. Familiarity
with Pyihon or other scriphng languages is suggesied, but
mm required.

You'll also need (a know some basic mathematics. This
book is handson and example driven: leis of examples and
lots of code, so even if your math skills are noi up to par.
do noi worry! The examples are very damned and heavily
documented (a help yuu follaw along.

Followed by testing the image with `ocr.py`:

$ python ocr.py --image images/example\_03.png
PREREQUISITES

Lu order to make the most ol this, you will need to have
a little bit ol programming experience. All examples in this
book are in the Python programming language. Familiarity
with Python or other scripting languages is suggested, but
not requixed.

You’ll also need to know some basic mathematics. This
book is handson and example driven: lots of examples and
lots ol code, so even ii your math skills are not up to par,
do not worry! The examples are very detailed and heavily
documented to help you tollow along.

![Image 8](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20302'%3E%3C/svg%3E)

**Figure 6:** Applying Optical Character Recognition (OCR) using Python, OpenCV, and Tesseract.

Notice misspellings in both outputs including, but not limited to, _“In”_, _“of”_, _“required”_, _“programming”_, and _“follow”_.

The output for both of these do not match; however, interestingly the pre-processed version has only 8 word errors whereas the non-pre-processed image has 17 word errors **(over twice as many errors)**. _Our pre-processing helps even on a clean background!_

Python + Tesseract did a reasonable job here, but once again we have demonstrated the limitations of the library as an off-the-shelf classifier.

We may obtain _good or acceptable_ results with Tesseract for OCR, but the _best accuracy_ will come from training custom character classifiers on _specific_ sets of fonts that appear in actual real-world images.

Don’t let the results of Tesseract OCR discourage you — simply manage your expectations and be realistic on Tesseract’s performance. There is no such thing as a true “off-the-shelf” OCR system that will give you perfect results (there are bound to be some errors).

_**Note:** If your text is rotated, you may wish to do additional pre-processing as is performed in [this previous blog post on correcting text skew](https://pyimagesearch.com/2017/02/20/text-skew-correction-opencv-python/). Otherwise, if you’re interested in building a [mobile document scanner](https://pyimagesearch.com/2014/09/01/build-kick-ass-mobile-document-scanner-just-5-minutes/), you now have a reasonably good OCR system to integrate into it._

### **Tip: Improve OCR accuracy by upgrading your Tesseract version**

Be sure to check the Tesseract version you have installed on your machine by using the `tesseract -v` command:

$ tesseract -v
tesseract 5.3.4

If you see Tesseract v5 or greater in your output, congrats, you are using the Long Short-Term Memory (LSTM) OCR model which is _far more accurate_ than the previous versions of Tesseract!

If you see any version _less_ than v5, then you should upgrade your Tesseract install — using the Tesseract v5 LSTM engine will lead to more accurate OCR results.

### What's next? We recommend [PyImageSearch University](https://pyimagesearch.com/pyimagesearch-university/?utm_source=blogPost&utm_medium=bottomBanner&utm_campaign=What%27s%20next%3F%20I%20recommend).

**Course information:**  
84 total classes • 114+ hours of on-demand code walkthrough videos • Last updated: February 2024  
★★★★★ 4.84 (128 Ratings) • 16,000+ Students Enrolled

**I strongly believe that if you had the right teacher you could _master_ computer vision and deep learning.**

Do you think learning computer vision and deep learning has to be time-consuming, overwhelming, and complicated? Or has to involve complex mathematics and equations? Or requires a degree in computer science?

That’s _not_ the case.

All you need to master computer vision and deep learning is for someone to explain things to you in _simple, intuitive_ terms. _And that’s exactly what I do_. My mission is to change education and how complex Artificial Intelligence topics are taught.

If you're serious about learning computer vision, your next stop should be PyImageSearch University, the most comprehensive computer vision, deep learning, and OpenCV course online today. Here you’ll learn how to _successfully_ and _confidently_ apply computer vision to your work, research, and projects. Join me in computer vision mastery.

**Inside PyImageSearch University you'll find:**

*   ✓ **84 courses** on essential computer vision, deep learning, and OpenCV topics
*   ✓ **84 Certificates** of Completion
*   ✓ **114+ hours** of on-demand video
*   ✓ **Brand new courses released _regularly_**, ensuring you can keep up with state-of-the-art techniques
*   ✓ **Pre-configured Jupyter Notebooks in Google Colab**
*   ✓ Run all code examples in your web browser — works on Windows, macOS, and Linux (no dev environment configuration required!)
*   ✓ Access to **centralized code repos for _all_ 536+ tutorials** on PyImageSearch
*   ✓ **Easy one-click downloads** for code, datasets, pre-trained models, etc.
*   ✓ **Access** on mobile, laptop, desktop, etc.

[Click here to join PyImageSearch University](https://pyimagesearch.com/pyimagesearch-university/?utm_source=blogPost&utm_medium=bottomBanner&utm_campaign=What%27s%20next%3F%20I%20recommend)

Summary
-------

In today’s blog post we learned how to apply the Tesseract OCR engine with the Python programming language. This enabled us to apply OCR algorithms from _within_ our Python script.

The biggest downside is with the limitations of Tesseract itself. Tesseract works best when there are _extremely_ _clean_ segmentations of the foreground text from the background.

Furthermore these segmentations need to be as high resolution (DPI) as possible _and_ the characters in the input image cannot appear “pixelated” after segmentation. If characters do appear pixelated then Tesseract will struggle to correctly recognize the text — we found this out even when applying images captured under ideal conditions (a PDF screenshot).

OCR, while no longer a new technology, is still an active area of research in the computer vision literature _especially_ when applying OCR to real-world, unconstrained images. Deep learning and Convolutional Neural Networks (CNNs) are certainly enabling us to obtain higher accuracy, but we are still a long way from seeing “near perfect” OCR systems. Furthermore, as OCR has many applications across many domains, some of the best algorithms used for OCR are commercial and require licensing to be used in your own projects.

My primary suggestion to readers when applying OCR to their own projects is to first try Tesseract and if results are undesirable move on to the [Google Vision API](https://cloud.google.com/vision/).

_If neither **Tesseract** nor the **Google Vision API** obtain reasonable accuracy_, you might want to reassess your dataset and decide if it’s worth it to train your own custom character classifier — this is _especially_ true if your dataset is noisy and/or contains very specific fonts you wish to detect and recognize. Examples of specific fonts include the digits on a credit card, the account and routing numbers found at the bottom of checks, or stylized text used in graphic design.

I hope you are enjoying this series of blog posts on Optical Character Recognition (OCR) with Python and OpenCV!

_**To be notified when new blog posts are published here on PyImageSearch, be sure to enter your email address in the form below!**_

![Image 9](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20410%20567'%3E%3C/svg%3E)

#### Download the Source Code and FREE 17-page Resource Guide

Enter your email address below to get a .zip of the code and a **FREE 17-page Resource Guide on Computer Vision, OpenCV, and Deep Learning.** Inside you'll find my hand-picked tutorials, books, courses, and libraries to help you master CV and DL!