We're going to start experimenting with tesseract
using just a simple image of nice clean text.
Let's first import PIL from image and display the image
text.png from PIL will import image.
Image is equal to image.open,
and we'll get the text.png other than the read_only.
Then we'll display that image.
Great, we have a base image of some big clear text.
Let's import pytesseract and use the dir function to get
a sense of what might be
some interesting functions to play with.
So import pytesseract,
and we can use dir to see what's inside of it.
Okay. It looks like there is just a handful
of interesting functions,
and I think image_to_string is probably our best bet.
Let's use the help function to
interrogate this a bit more.
So help pytesseract image_to_string.
So this function takes an image as the first parameter,
and there is a bunch of optional parameters,
and it'll return the results of the OCR.
I think it's worth comparing
this documentation string with
the documentation we were
receiving from the pillow module.
Let's run the help command on the image resize function.
So help image, Image.resize.
Notice how the PILLOW function has
a bit more information in it.
First off, it's using
a specific format called reStructuredText,
which is similar in intent
to document markups such as HTML,
the language of the web.
The intent is to embed
semantics in the documentation itself.
For instance, in the resize function we see
the words param size with colon surrounding it.
This allows documentation engines which create docs for
the source code to link
the parameter to the extended docs about that parameter.
In this case, the extended docs tell us that
the size should be passed as a tuple of width and height.
Notice how the dogs for image_to_string, for instance,
indicate that there's a lang parameter
which we could use,
but then fail to say anything about what
that parameter is for or what its format is.
What this really means is that you need to dig deeper.
Here's a quick hack if you want to
look at the source code of a function.
You can use the inspect gets
source command and print the results.
So let's import inspect,
and remember this module comes from
our Python three standard library.
Then we'll create the source
inspect.getsource and we pass it a function pointer.
You note that we're not calling the function.
We're just passing a reference to the function,
and then let's print that source to the screen.
So it's interesting, you can actually look at
the source code behind a given function,
and that's one of the powers of
an interpreted language like Python.
There's actually another way in Jupyter,
and that's to append two question marks
to the end of a given function or module.
Other editors have similar features,
and this is actually a great reason that
you should be using a software development environment.
So pytesseract.image_to_string
just as if we were going to call
the function add two question marks
to the end and then run that.
We see that it pops up at the bottom of
the screen with a lot more information and it's
nice in syntax highlighted for us too.
We can see from the source code that there
really isn't much more information about
what the parameters are for or
what this image_to_string function is?
This is because underneath,
the pytesseract library is calling
a C++ library which does all of the hard work,
and the author just passes through all of
the calls to the underlying tesseract executable.
This is a common issue when
working with Python libraries,
and it means that we need to do some web sleuthing
in order to understand how we
can interact with tesseract.
In a case like this,
I just Googled tesseract command line parameters,
and the first hit was what I was looking for.
Here's the URL to the GitHub.
This goes to a wiki page which describes how to call
the tesseract executable, and as we read down,
we see that we can actually have tesseract use
multiple languages in its detection such as
English and Hindi by passing them in
as eng plus hin, that's very cool.
One last thing to mention,
the image_to_string function takes in an image,
but the docs don't really
describe what this image is underneath.
Is it a string to an image file?
A PILLOW image or something else?
Again we have to sleuth and or
experiment to understand what we should do.
If we look at the source code
for the pytesseract library,
we see there's a function called run_and_get_output.
Here's a link to that function on
the author's GitHub account.
When we look at this function we can actually
see what actually happens when we call this function.
In this function, we see that one of
the first things which happens as
the image is saved through the save_image function.
Here's that line of code.
We see that there's another function
called prepare image,
which actually loads the image as a PILLOW image file.
So, yes, sending a PIL image file
is appropriate for use for this function.
It sure would have been useful for
the author to have included this information and
reStructuredText to help us
not have to dig through the implementation itself.
But this is an open source project.
Maybe you would like to contribute
back some better documentation.
Just a hint, if you're interested in,
the doc line we need is param image,
and then we just say that it's a PIL
Image.Image file or an ndarray of bytes.
In the end, we often don't
do this full level of investigation,
and we just experiment and try things.
It seems pretty likely that a PIL Image.Image would work,
given how well known PIL is in the Python world.
But still, as you explore and use
different libraries you'll see a breadth
of different documentation norms.
So it's useful to know how to explore the source code,
and now that you're at the end of this course,
you've got the skills to do so.
Okay. Let's try and run tesseract on this image.
So texts is equal to
pytesseract.image_to_string and we pass in the image,
and then let's just print out the text. Looks great.
We can see that the output includes
new line characters and faithfully represents the text,
but it doesn't include any special formatting.
Let's go on and look at something
with a bit more nuance to it next.