I am using following code to draw rectangle on an image text for matching date pattern and its working fine.
import re
import cv2
import pytesseract
from PIL import Image
from pytesseract import Output
img = cv2.imread('invoice-sample.jpg')
d = pytesseract.image_to_data(img, output_type=Output.DICT)
keys = list(d.keys())
date_pattern = '^(0[1-9]|[12][0-9]|3[01])/(0[1-9]|1[012])/(19|20)\d\d$'
n_boxes = len(d['text'])
for i in range(n_boxes):
if int(d['conf'][i]) > 60:
if re.match(date_pattern, d['text'][i]):
(x, y, w, h) = (d['left'][i], d['top'][i], d['width'][i], d['height'][i])
img = cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.imshow('img', img)
cv2.waitKey(0)
img.save("sample.pdf")
Now, at the end I am getting a PDF with rectangle on matched date pattern.
I want to give this program scanned PDF as input instead of image above.
It should first convert PDF into image format readable by opencv for same processing as above.
Please help.
(Any workaround is fine. I need a solution in which I can convert PDF to image and use it directly instead of saving on disk and read them again from there. As I have lot of PDFs to process.)
There is a library named pdf2image. You can install it with pip install pdf2image. Then, you can use the following to convert pages of the pdf to images of the required format:
from pdf2image import convert_from_path
pages = convert_from_path("pdf_file_to_convert")
for page in pages:
page.save("page_image.jpg", "jpg")
Now you can use this image to apply opencv functions.
You can use BytesIO to do your work without saving the file:
from io import BytesIO
from PIL import Image
with BytesIO() as f:
page.save(f, format="jpg")
f.seek(0)
img_page = Image.open(f)
From PDF to opencv ready array in two lines of code. I have also added the code to resize and view the opencv image. No saving to disk.
# imports
from pdf2image import convert_from_path
import cv2
import numpy as np
# convert PDF to image then to array ready for opencv
pages = convert_from_path('sample.pdf')
img = np.array(pages[0])
# opencv code to view image
img = cv2.resize(img, None, fx=0.5, fy=0.5)
cv2.imshow("img", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Remember if you do not have poppler in your Windows PATH variable you can provide the path to convert_form_path
poppler_path = r'C:\path_to_poppler'
pages = convert_from_path('sample.pdf', poppler_path=poppler_path)
You can use the library pdf2image. Install with this command: pip install pdf2image. You can then convert the file into one or multiple images readable by cv2. The next sample of code will convert the PIL Image into something readable by cv2:
Note: The following code requires numpy pip install numpy.
from pdf2image import convert_from_path
import numpy as np
images_of_pdf = convert_from_path('source2.pdf') # Convert PDF to List of PIL Images
readable_images_of_pdf = [] # Create a list for thr for loop to put the images into
for PIL_Image in images_of_pdf:
readable_images_of_pdf.append(np.array(PIL_Image)) # Add items to list
The next bit of code can convert the pdf into one big image readable by cv2:
import cv2
import numpy as np
from pdf2image import convert_from_path
image_of_pdf = np.concatenate(tuple(convert_from_path('/path/to/pdf/source.pdf')), axis=0)
The pdf2image library's convert_from_path() function returns a list containing each pdf page in the PIL image format. We convert the list into a tuple for the numpy concatenate function to stack the images on top of each other. If you want them side by side you could change the axis integer to 1 signifying you want to concatenate the images along the y-axis. This next bit of code will show the image on the screen:
cv2.imshow("Image of PDF", image_of_pdf)
cv2.waitKey(0)
This will probably create a window on the screen that is too big. To resize the image for the screen you'll use the following code that uses cv2's built-in resize function:
import cv2
from pdf2image import convert_from_path
import numpy as np
image_of_pdf = np.concatenate(tuple(convert_from_path('source2.pdf')), axis=0)
size = 0.15 # 0.15 is equal to 15% of the original size.
resized = cv2.resize(image_of_pdf, (int(image_of_pdf.shape[:2][1] * size), int(image_of_pdf.shape[:2][0] * size)))
cv2.imshow("Image of PDF", resized)
cv2.waitKey(0)
On a 1920x1080 monitor, a size of 0.15 can comfortably display a 3-page document. The downside is that the quality is reduced dramatically. If you want to have the pages separated you can just use the original convert_from_path() function. The following code shows each page individually, to go to the next page press any key:
import cv2
from pdf2image import convert_from_path
import numpy
images_of_pdf = convert_from_path('source2.pdf') # Convert PDF to List of PIL Images
count = 0 # Start counting which page we're on
while True:
cv2.imshow(f"Image of PDF Page {count + 1}", numpy.array(images_of_pdf[count])) # Display the page with it's number
cv2.waitKey(0) # Wait until key is pressed
cv2.destroyWindow(f"Image of PDF Page {count + 1}") # Destroy the following window
count += 1 # Add to the counter by 1
if count == len(images_of_pdf):
break # Break out of the while loop before you get an "IndexError: list index out of range"
I am trying to resize all images in my samples folder and then save all the images back in the test folder. The code below resize the images but it doesn't save them into the destination folder "test". I fail to understand what is the problem and I have referred to all documentation and nothing can help me understand what goes wrong here.
import cv2
import glob
import os
from tqdm import tqdm
imgs = glob.glob('samples/*.jpg')
print('Images files:', imgs)
width = 100
height = 100
folder = 'test'
if not os.path.exists(folder):
os.makedirs(folder)
#Resizing & Saving
for img in tqdm(imgs):
pic = cv2.imread(img, cv2.IMREAD_UNCHANGED)
pic = cv2.resize(pic, (width, height))
cv2.imwrite(os.path.join(folder,img), pic)
print(img)
The script can read the images and resize them successfully, the only part is imwrite doesn't function as expected.
May be the special character. Try to change the name of the image.
I don't have reputation to add this idea as comment. I'm Sorry.
I wanted read a image using PIL.Image.open().But I've image in different path.
The following is the path I've the python script
"D:\YY_Aadhi\holy-edge-master\hed\test.py"
The following is the path I've the image file.
"D:\YY_Aadhi\HED-BSDS\test\2018.jpg"
from PIL import Image
'''some code here'''
image = Image.open(????)
How should I fill the question mark to access the image file.
you can simply do
from PIL import Image
image = Image.open("D:\\YY_Aadhi\\HED-BSDS\\test\\2018.jpg")
or
from PIL import Image
directory = "D:\\YY_Aadhi\\HED-BSDS\\test\\2018.jpg"
image = Image.open(directory)
like this.
you have to write escape sequence twice in windows, when you want to define as directory. and It will be great if you try some stupid code. It helps you a lot.
Does this image = Image.open("D:\YY_Aadhi\HED-BSDS\test\2018.jpg") not do the trick?
You can use this to read an online image
from urllib.request import urlopen
url = 'https://somewebsite/images/logo.png'
msg_image = urlopen(url).read()
I'm working on a project where two imported librairies are not working well with each other, I know it is possible to get the size of an image using :
from PIL import Image
img = Image.open(logo)
width, height = img.size
But I'd like to know if it is also possible to do that usin io ? I couldn't find anything on that
logo = request.FILES.get('logo')
img = io.BytesIO(logo.read())
... ?
Is there anyway to get image width and height without downloading from original location in PYTHON. I have an idea how to get image info when it is in our server. Buy no idea this can do with online resource image in PYTHON.
Finally done this as follow in python. Anyway have to download and get image info
import cStringIO
import urllib
import Image
file = urllib.urlopen('http://static.php.net/www.php.net/images/php.gif')
im = cStringIO.StringIO(file.read())
img = Image.open(im)
print img.format, img.size, img.mode
GIF (120, 67) P
width, height = img.size
print width, height
You can't. You must download a certain amount of the file before you get to the metadata that contains the dimensions of the image.