1
\$\begingroup\$

I have a python script, that is performing OCR on PDF pages.

I am trying to do so I can provide coordinates to the script - so it will only select the text within the provided coordinates (x, y, h, w).

This task in itself should be easy enough, however there is a caveat.

I am trying to do this on PDF files that are:

  • Scanned - just an image.
  • Not scanned - contains searchable text.

Imagine below coordinates are being provided:

{"h": "800", "w": "395", "x": "0","y": "0"}

If the PDF contains text, I will use the pdftotext command. The pdftotext command accepts a set of coordinates (x, y, H, W) - so selecting text from a specific area is straightforward.

Example - text.pdf

Width: 595px
Height: 842px
Output: My text on the PDF file.

However, if the exact same PDF file gets scanned, I will have to convert the PDF page to an image so I can perform OCR on the page. It's recommended to use 300 DPI when performing OCR on images [See link].

This means, that the same PDF file with the same coordinates as above will no longer output the same result. This is because, ultimately, when converting the PDF to an image with 300 DPI, the width/height will be changed accordingly.

Let's say I am cropping the image using Python, according to above coordinates:

area(0, 0, 395, 800)
pdf_image = Image.open(my_image_file)
output_image = pdf_image.crop(area)

Let's use the PDF file from above as an example:

Example - textscanned.pdf

Width: 2479
Height: 3508
Output: My t

As you can see, the output is different - because 395px on above page is not the same as 395px on my original PDF.

How to solve this?

As far as I see, I have one thing I can use to solve this in my script: the 300 DPI.

  1. Get the scanned PDF files width/height.
  2. Convert the scanned PDF to an image (resolution = 300 DPI).
  3. Divide the original PDFs dimensions with the dimensions of the converted image.
  4. Multiply the coordinates with above result.
# Get the scanned PDFs dimensions:

dimensions = PdfFileReader(open(pdf_file, 'rb'))
dimensions = dimensions.getPage(0).mediaBox

original_width = dimensions[2]
original_height = dimensions[3]

# Get the dimensions of the converted PDF file => image:

cropped_image = Image.open(converted_Image)
size = (cropped_image.size)
width, height = size

# Divide the original width & height width the converted:

width_factor = width / original_width # Outputs: 4,166386555
height_factor = height / original_height # Outputs: 4,166270784

# Multiply the factor with the coordinates:

width = int(coordinates['w'] * width_factor)
height = int(coordinates['h'] * height_factor)

This will result in a new width, height set:

width = 1645
height = 3333

When cropping the image using above width/height coordinates, the output is identical to the first text PDF file.

Am I on to something? Is my math correct using above?

I imagine I have to do something similar for the x, y coordinates - but not sure if the same math can be applied to these two?

\$\endgroup\$
  • \$\begingroup\$ Could you present the code with the proper context? What is converted_Image? What are your imports? \$\endgroup\$ – 200_success May 25 at 19:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.