[SLD] PDF OCR
Contents
“Quod licet iovi,non licet bovi.”
Bogovom je dovoljeno več kot govedu.
Publius Terentius Afer
Algoritem
- Skeniraj več PDF strani v en dokument (skener nima vgrajenega OCR).
- Včitaj shranjen PDF.
- Na vsaki strani je na določeni lokaciji shranjeno ime.
- Prečitaj to ime z OCR in shrani stran kot nov PDF s tem imenom.
retVal = fPdfOcr2(self.sFile, DatumF=DatumF, d1_w=0.8739, d1_h=0.2583, d2_w=0.9303, d2_h=0.3897, saveImg=False)
if (retVal == True):
#tk.messagebox.showinfo("Info", "Uspeno razstavljeno! ")
pass
else:
tk.messagebox.showinfo("Info", " NEUSPESNO! ")
Zahteve
Različni optični čitalci različno tvorijo PDF. Nekateri ustvarijo preprost PNG in ga povežejo v PDF, ostali pa malo “zakomplicirajo” in razbijejo stran na več elementov, jih različno komprimirajo in potem povežejo v PDF.
Zaradi tega so zahteve za čitanje različne in obdelava različno hitra.
Zahteve za “enostaven” PDF
Pogoj za enostaven PDF je, da je na eni strani en element (slika) in da je ta komprimirana tako, to komprimiranje knjižnica PIL prepozna. Če je stran sestavljena iz več elementov, ki jih PIL prepoznava, je postopek zelo podoben.
Potrebuješ:
- tesseract _(tesseract-ocr-w32-setup-v5.0.0-alpha.20190708.exe in potem še https://digi.bib.uni-mannheim.de/tesseract/)_
- pytesseract (pip install pytesseract)
- pillow (pip install pillow)
- minecart (pip install minecart)
- PyPDF2 (pip install PyPDF2)
Zahteve za “sestavljen” PDF
To deluje tudi na “enostavnih” PDFih, samo čas obdelave je nekaj daljši. Pri daljših dokumentih (nekaj 10 strani) se razlika že občuti. Dodatno k prej navedenemu potrebuješ še poppler (poppler-068.0) Le tega shraniš nekam v svojo pot.
Python koda
“Enostaven” PDF"
def fPdfOcr2(sFile, DatumF="2019-10", d1_w=0.8739, d1_h=0.2583, d2_w=0.9303, d2_h=0.3897, saveImg=False):
#Precitaj PDF, pretvori v sliko, obrezi sliko na podrocju, ki te zanimo, zavrti sliko sliko, izvedi ocr na mali sliki,
#shrani vsako stran iz PDF z imenom DatumF+_+precitano_ime+.pdf = 2019-10_RezultatOCR.pdf
#To je okvir za vzorčni printer, ki ga čitam, w = wide, h=height:
# d1_w = 2045/2340
# d1_h = 855/3310
# d2_w = 2177/2340
# d2_h = 1290/3310
#
# # za OCR moras namestiti tesseract-ocr-w32-setup-v5.0.0-alpha.20190708.exe in potem še https://digi.bib.uni-mannheim.de/tesseract/
# # pip install pytesseract
# # pip install pillow - mogoče bo treba namestiti verzijo 4.0
# # pip install minecart
# # pip install PyPDF2
#
#
#vrne True, ce je uspesno in False, ce ni
from PIL import Image
from PyPDF2 import PdfFileWriter, PdfFileReader
import minecart
import pytesseract
if os.path.exists(r'C:\... \AppData\Local\Tesseract-OCR\tesseract.exe'):
pytesseract.pytesseract.tesseract_cmd = r'C:\ ... \AppData\Local\Tesseract-OCR\tesseract.exe'
else:
# print("NO CORRECT PATH")
return("No Tesseract path found")
sPath = os.path.dirname(sFile) #samo pot do obstojece datoteke
try:
pdffile = open(sFile, 'rb')
doc = minecart.Document(pdffile)
page = doc.get_page(0) # getting a single page
#Izrezem samo male slikice in pridobim imena
i = 0
ime = []
#iterating through all pages
for page in doc.iter_pages():
i = i + 1
im = page.images[0].as_pil() # requires pillow
if (saveImg == True):
sFileNew = os.path.join(sPath, "PNG%s"%i + ".png")
im.save(sFileNew)
width, height = im.size
t1_w = d1_w * width
t1_h = d1_h * height
t2_w = d2_w * width
t2_h = d2_h * height
im = im.crop((t1_w, t1_h, t2_w, t2_h))
im = im.rotate(90, expand=True)
im = im.convert('L') #L<- grayscale
#im.save("test%s.png"%i + ".png")
text = pytesseract.image_to_string(im)
if text.split()[0:2] == ['Delovno', 'mesto:']: #ce sploh berem pravo podrocje
ime.append(text.split()[-1]) #zadnji element je ime
else:
ime.append("Napaka_stran%s " % i)
sFileNew = os.path.join(sPath, "test%s.png"%i + ".png")
im.save(sFileNew)
print(i, text)
inputpdf = PdfFileReader(open(sFile, "rb"))
i = 0
for i in range(inputpdf.numPages):
output = PdfFileWriter()
output.addPage(inputpdf.getPage(i))
sFileNew = os.path.join(sPath, DatumF +"_"+ime[i] + ".pdf")
with open(sFileNew, "wb") as outputStream:
output.write(outputStream)
i = i + 1
return True
except:
return False
“Sestavljen” PDF
# %% Common routines
import os
import sys
# Poppler mora biti v poti, če ni ga tukaj dodaj
if os.path.exists('C:\\ .... \\poppler-0.68.0\\bin'):
sys.path.append('C:\\ .... \\poppler-0.68.0\\bin')
else:
print("NO POPPLER !")
exit
import datetime
#%%FUNCIJA Precitaj PDF
def fPdfOcr2(sFile, DatumF="2019-10", d1_w=0.8739, d1_h=0.2583, d2_w=0.9303, d2_h=0.3897, saveImg=False):
#Precitaj PDF, pretvori v sliko, obrezi sliko na podrocju, ki te zanimo, zavrti sliko sliko, izvedi ocr na mali sliki,
#shrani vsako stran iz PDF z imenom DatumF+_+precitano_ime+.pdf = 2019-10_RezultatOCR.pdf
#To je okvir za vzorčni printer, ki ga čitam, w = wide, h=height:
# d1_w = 2045/2340
# d1_h = 855/3310
# d2_w = 2177/2340
# d2_h = 1290/3310
#
# # za OCR moras namestiti tesseract-ocr-w32-setup-v5.0.0-alpha.20190708.exe in potem še https://digi.bib.uni-mannheim.de/tesseract/
# # pip install pytesseract
# # pip install pillow - mogoče bo treba namestiti verzijo 4.0
# # pip install minecart
# # pip install PyPDF2
# # pip install pdf2Image
# #
#
# #Poppler for windows: http://blog.alivate.com.au/poppler-windows/
# #bin moraš imeti v poti, to narediš s sys.path.apend("pot do poppler-068.0/bin")
#
#vrne True, ce je uspesno in False, ce ni
import io
from PIL import Image
from PyPDF2 import PdfFileWriter, PdfFileReader
import minecart
from pdf2image import convert_from_path
import pytesseract
if os.path.exists(r'C:\... \AppData\Local\Tesseract-OCR\tesseract.exe'):
pytesseract.pytesseract.tesseract_cmd = r'C:\ ... \AppData\Local\Tesseract-OCR\tesseract.exe'
else:
# print("NO CORRECT PATH")
return("No Tesseract path found")
sPath = os.path.dirname(sFile) #samo pot do obstojece datoteke
try:
images = convert_from_path(sFile)
#Izrezem samo male slikice in pridobim imena
i = 0
ime = []
#iterating through all pages
for img in images:
i = i + 1
png_bytes = io.BytesIO() #shranjujem v pomnilnik
img.save(png_bytes,'PNG') #shanim sliko v PNG formatu v pomnilnik
im = Image.open(png_bytes) #iz pomnilnika nalozim v PIL format slike
if (saveImg == True):
sFileNew = os.path.join(sPath, "PNG%s"%i + ".png")
im.save(sFileNew)
width, height = im.size
t1_w = d1_w * width
t1_h = d1_h * height
t2_w = d2_w * width
t2_h = d2_h * height
im = im.crop((t1_w, t1_h, t2_w, t2_h))
im = im.rotate(90, expand=True)
im = im.convert('L') #L<- grayscale
text = pytesseract.image_to_string(im)
if text.split()[0:2] == ['Delovno', 'mesto:']: #ce sploh berem pravo podrocje
ime.append(text.split()[-1]) #zadnji element je ime
else:
ime.append("Napaka_stran%s " % i)
sFileNew = os.path.join(sPath, "test%s.png"%i + ".png")
im.save(sFileNew)
print(i, text)
inputpdf = PdfFileReader(open(sFile, "rb"))
i = 0
for i in range(inputpdf.numPages):
output = PdfFileWriter()
output.addPage(inputpdf.getPage(i))
sFileNew = os.path.join(sPath, DatumF +"_"+ime[i] + ".pdf")
with open(sFileNew, "wb") as outputStream:
output.write(outputStream)
i = i + 1
return True
except:
return False
Author SlanaD
LastMod 2019-10-27