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.