1
0
mirror of https://gitlab.os-k.eu/neox/CNIRevelator.git synced 2023-08-25 14:03:10 +02:00

Finished OCR detection

This commit is contained in:
Adrien Bourmault 2019-08-11 16:26:06 +02:00
parent 9a7ab2e8ee
commit 576ad52a2d
2 changed files with 260 additions and 213 deletions

BIN
src/OCR.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 512 B

View File

@ -36,6 +36,7 @@ import traceback
import cv2 import cv2
import PIL.Image, PIL.ImageTk import PIL.Image, PIL.ImageTk
import os, shutil import os, shutil
import webbrowser
import ihm # ihm.py import ihm # ihm.py
import logger # logger.py import logger # logger.py
@ -179,6 +180,8 @@ class mainWindow(Tk):
self.toolbar.grid_columnconfigure(12, weight=1) self.toolbar.grid_columnconfigure(12, weight=1)
self.toolbar.grid_columnconfigure(13, weight=1, minsize=10) self.toolbar.grid_columnconfigure(13, weight=1, minsize=10)
self.toolbar.grid_columnconfigure(14, weight=1) self.toolbar.grid_columnconfigure(14, weight=1)
self.toolbar.grid_columnconfigure(15, weight=1, minsize=10)
self.toolbar.grid_columnconfigure(16, weight=1)
self.toolbar.grid_rowconfigure(0, weight=1) self.toolbar.grid_rowconfigure(0, weight=1)
self.toolbar.zoomIn50Img = ImageTk.PhotoImage(PIL.Image.open("zoomIn50.png")) self.toolbar.zoomIn50Img = ImageTk.PhotoImage(PIL.Image.open("zoomIn50.png"))
@ -225,9 +228,17 @@ class mainWindow(Tk):
self.toolbar.rotateRight = ttk.Button(self.toolbar, image=self.toolbar.rotateRightImg, command=self.rotateRight) self.toolbar.rotateRight = ttk.Button(self.toolbar, image=self.toolbar.rotateRightImg, command=self.rotateRight)
self.toolbar.rotateRight.grid(column=12, row=0) self.toolbar.rotateRight.grid(column=12, row=0)
self.toolbar.goOCR = ttk.Button(self.toolbar, text="OCR", command=self.goOCRDetection) self.toolbar.goOCRImg = ImageTk.PhotoImage(PIL.Image.open("OCR.png"))
self.toolbar.goOCR = ttk.Button(self.toolbar, image=self.toolbar.goOCRImg, command=self.goOCRDetection)
self.toolbar.goOCR.grid(column=14, row=0) self.toolbar.goOCR.grid(column=14, row=0)
self.toolbar.pagenumber = StringVar()
self.toolbar.pageChooser = ttk.Combobox(self.toolbar, textvariable=self.toolbar.pagenumber)
self.toolbar.pageChooser.bind("<<ComboboxSelected>>", self.goPageChoice)
self.toolbar.pageChooser['values'] = ('1')
self.toolbar.pageChooser.current(0)
self.toolbar.pageChooser.grid(column=16, row=0)
self.toolbar.grid(column=0, row=2, padx=0, pady=0) self.toolbar.grid(column=0, row=2, padx=0, pady=0)
# + image with scrollbars # + image with scrollbars
@ -309,6 +320,8 @@ class mainWindow(Tk):
menubar.add_cascade(label='Fichier', menu=menu1) menubar.add_cascade(label='Fichier', menu=menu1)
menu3 = Menu(menubar, tearoff=0) menu3 = Menu(menubar, tearoff=0)
menu3.add_command(label='Commandes au clavier', command=(self.helpbox)) menu3.add_command(label='Commandes au clavier', command=(self.helpbox))
menu3.add_command(label='Signaler un problème', command=(self.openIssuePage))
menu3.add_separator()
menu3.add_command(label='A propos de CNIRevelator', command=(self.infobox)) menu3.add_command(label='A propos de CNIRevelator', command=(self.infobox))
menubar.add_cascade(label='Aide', menu=menu3) menubar.add_cascade(label='Aide', menu=menu3)
self.config(menu=menubar) self.config(menu=menubar)
@ -336,21 +349,13 @@ class mainWindow(Tk):
self.deiconify() self.deiconify()
self.minsize(self.winfo_width(), self.winfo_height()) self.minsize(self.winfo_width(), self.winfo_height())
# Load an image using OpenCV # Set image
cv_img = cv2.imread("background.png") self.imageViewer.image = None
cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2GRAY) self.imageViewer.imagePath = None
cv_img = cv2.blur(cv_img, (15, 15))
# Get the image dimensions (OpenCV stores image data as NumPy ndarray)
height, width = cv_img.shape
# Get the image dimensions (OpenCV stores image data as NumPy ndarray)
height, width = cv_img.shape
# Use PIL (Pillow) to convert the NumPy ndarray to a PhotoImage
photo = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(cv_img))
self.statusUpdate(photo, setplace=True)
self.imageViewer.imagePath = "background.png"
self.imageViewer.imgZoom = 1 self.imageViewer.imgZoom = 1
self.imageViewer.rotateCount = 0 self.imageViewer.rotateCount = 0
self.imageViewer.blackhat = False self.imageViewer.blackhat = False
self.imageViewer.pagenumber = 0
# Some bindings # Some bindings
self.termtext.bind('<Key>', self.entryValidation) self.termtext.bind('<Key>', self.entryValidation)
@ -367,6 +372,7 @@ class mainWindow(Tk):
self.imageViewer.ZONE.configure(scrollregion=self.imageViewer.ZONE.bbox("all")) self.imageViewer.ZONE.configure(scrollregion=self.imageViewer.ZONE.bbox("all"))
def rectangleSelectScan(self, event): def rectangleSelectScan(self, event):
if self.imageViewer.image:
canvas = event.widget canvas = event.widget
print("Get coordinates : [{}, {}], for [{}, {}]".format(canvas.canvasx(event.x), canvas.canvasy(event.y), event.x, event.y)) print("Get coordinates : [{}, {}], for [{}, {}]".format(canvas.canvasx(event.x), canvas.canvasy(event.y), event.x, event.y))
@ -379,18 +385,19 @@ class mainWindow(Tk):
self.imageViewer.ZONE.delete(self.select) self.imageViewer.ZONE.delete(self.select)
def goOCRDetection(self): def goOCRDetection(self):
cv_img = cv2.imread(self.imageViewer.imagePath) if self.imageViewer.image:
cv_img = cv2.imreadmulti(self.imageViewer.imagePath)[1][self.imageViewer.pagenumber]
cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB) cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)
if self.imageViewer.blackhat: if self.imageViewer.blackhat:
cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2GRAY) cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2GRAY)
cv_img = cv2.GaussianBlur(cv_img, (3, 3), 0) cv_img = cv2.GaussianBlur(cv_img, (3, 3), 0)
cv_img = cv2.bitwise_not(cv_img) cv_img = cv2.bitwise_not(cv_img)
if not self.imageViewer.blackhat: try:
# Get the image dimensions (OpenCV stores image data as NumPy ndarray) # Get the image dimensions (OpenCV stores image data as NumPy ndarray)
height, width, channels_no = cv_img.shape height, width, channels_no = cv_img.shape
# Get the image dimensions (OpenCV stores image data as NumPy ndarray) # Get the image dimensions (OpenCV stores image data as NumPy ndarray)
height, width, channels_no = cv_img.shape height, width, channels_no = cv_img.shape
else: except ValueError:
# Get the image dimensions (OpenCV stores image data as NumPy ndarray) # Get the image dimensions (OpenCV stores image data as NumPy ndarray)
height, width = cv_img.shape height, width = cv_img.shape
# Get the image dimensions (OpenCV stores image data as NumPy ndarray) # Get the image dimensions (OpenCV stores image data as NumPy ndarray)
@ -639,6 +646,9 @@ class mainWindow(Tk):
self.speedResult.insert('end', text) self.speedResult.insert('end', text)
self.speedResult['state'] = 'disabled' self.speedResult['state'] = 'disabled'
def goPageChoice(self, event):
self.imageViewer.pagenumber = int(self.toolbar.pageChooser.get()) - 1
self.resizeScan()
def openingScan(self): def openingScan(self):
path = '' path = ''
@ -651,67 +661,96 @@ class mainWindow(Tk):
self.imageViewer.imgZoom = 1 self.imageViewer.imgZoom = 1
self.imageViewer.blackhat = False self.imageViewer.blackhat = False
self.imageViewer.rotateCount = 0 self.imageViewer.rotateCount = 0
cv_img = cv2.imread(path) self.imageViewer.pagenumber = 0
# Determine how many pages
self.toolbar.pageChooser['values'] = ('1')
total = len(cv2.imreadmulti(self.imageViewer.imagePath)[1])
for i in range(2, total + 1):
self.toolbar.pageChooser['values'] += tuple(str(i))
# Open the first page
cv_img = cv2.imreadmulti(self.imageViewer.imagePath)[1][self.imageViewer.pagenumber]
cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB) cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)
try:
# Get the image dimensions (OpenCV stores image data as NumPy ndarray) # Get the image dimensions (OpenCV stores image data as NumPy ndarray)
height, width, channels_no = cv_img.shape height, width, channels_no = cv_img.shape
# Get the image dimensions (OpenCV stores image data as NumPy ndarray) # Get the image dimensions (OpenCV stores image data as NumPy ndarray)
height, width, channels_no = cv_img.shape height, width, channels_no = cv_img.shape
except ValueError:
# Get the image dimensions (OpenCV stores image data as NumPy ndarray)
height, width = cv_img.shape
# Get the image dimensions (OpenCV stores image data as NumPy ndarray)
height, width = cv_img.shape
# Use PIL (Pillow) to convert the NumPy ndarray to a PhotoImage # Use PIL (Pillow) to convert the NumPy ndarray to a PhotoImage
photo = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(cv_img)) photo = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(cv_img))
self.statusUpdate(photo) self.statusUpdate(photo)
def zoomInScan50(self, quantity = 50): def zoomInScan50(self, quantity = 50):
if self.imageViewer.image:
self.imageViewer.imgZoom += quantity self.imageViewer.imgZoom += quantity
self.resizeScan() self.resizeScan()
def zoomOutScan50(self, quantity = 50): def zoomOutScan50(self, quantity = 50):
if self.imageViewer.image:
self.imageViewer.imgZoom -= quantity self.imageViewer.imgZoom -= quantity
self.resizeScan() self.resizeScan()
def zoomInScan20(self, quantity = 20): def zoomInScan20(self, quantity = 20):
if self.imageViewer.image:
self.imageViewer.imgZoom += quantity self.imageViewer.imgZoom += quantity
self.resizeScan() self.resizeScan()
def zoomOutScan20(self, quantity = 20): def zoomOutScan20(self, quantity = 20):
if self.imageViewer.image:
self.imageViewer.imgZoom -= quantity self.imageViewer.imgZoom -= quantity
self.resizeScan() self.resizeScan()
def zoomInScan(self, quantity = 1): def zoomInScan(self, quantity = 1):
if self.imageViewer.image:
self.imageViewer.imgZoom += quantity self.imageViewer.imgZoom += quantity
self.resizeScan() self.resizeScan()
def zoomOutScan(self, quantity = 1): def zoomOutScan(self, quantity = 1):
if self.imageViewer.image:
self.imageViewer.imgZoom -= quantity self.imageViewer.imgZoom -= quantity
self.resizeScan() self.resizeScan()
def rotateRight(self): def rotateRight(self):
if self.imageViewer.image:
self.imageViewer.rotateCount -= 1 self.imageViewer.rotateCount -= 1
if self.imageViewer.rotateCount < 0: if self.imageViewer.rotateCount < 0:
self.imageViewer.rotateCount = 4 self.imageViewer.rotateCount = 4
self.resizeScan() self.resizeScan()
def rotateLeft(self): def rotateLeft(self):
if self.imageViewer.image:
self.imageViewer.rotateCount += 1 self.imageViewer.rotateCount += 1
if self.imageViewer.rotateCount > 4: if self.imageViewer.rotateCount > 4:
self.imageViewer.rotateCount = 0 self.imageViewer.rotateCount = 0
self.resizeScan() self.resizeScan()
def rotateLeft1(self): def rotateLeft1(self):
if self.imageViewer.image:
self.imageViewer.rotateCount += 0.01 self.imageViewer.rotateCount += 0.01
if self.imageViewer.rotateCount > 4: if self.imageViewer.rotateCount > 4:
self.imageViewer.rotateCount = 0 self.imageViewer.rotateCount = 0
self.resizeScan() self.resizeScan()
def rotateRight1(self): def rotateRight1(self):
if self.imageViewer.image:
self.imageViewer.rotateCount -= 0.01 self.imageViewer.rotateCount -= 0.01
if self.imageViewer.rotateCount < 0: if self.imageViewer.rotateCount < 0:
self.imageViewer.rotateCount = 4 self.imageViewer.rotateCount = 4
self.resizeScan() self.resizeScan()
def negativeScan(self): def negativeScan(self):
if self.imageViewer.image:
# Load an image using OpenCV # Load an image using OpenCV
cv_img = cv2.imread(self.imageViewer.imagePath) cv_img = cv2.imreadmulti(self.imageViewer.imagePath)[1][self.imageViewer.pagenumber]
cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB) cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)
if not self.imageViewer.blackhat: if not self.imageViewer.blackhat:
self.imageViewer.blackhat = True self.imageViewer.blackhat = True
@ -723,22 +762,23 @@ class mainWindow(Tk):
self.resizeScan(cv_img) self.resizeScan(cv_img)
def resizeScan(self, cv_img = None): def resizeScan(self, cv_img = None):
if self.imageViewer.image:
try: try:
if not hasattr(cv_img, 'shape'): if not hasattr(cv_img, 'shape'):
# Load an image using OpenCV # Load an image using OpenCV
cv_img = cv2.imread(self.imageViewer.imagePath) cv_img = cv2.imreadmulti(self.imageViewer.imagePath)[1][self.imageViewer.pagenumber]
cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB) cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)
if self.imageViewer.blackhat: if self.imageViewer.blackhat:
cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2GRAY) cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2GRAY)
cv_img = cv2.GaussianBlur(cv_img, (3, 3), 0) cv_img = cv2.GaussianBlur(cv_img, (3, 3), 0)
cv_img = cv2.bitwise_not(cv_img) cv_img = cv2.bitwise_not(cv_img)
if not self.imageViewer.blackhat: try:
# Get the image dimensions (OpenCV stores image data as NumPy ndarray) # Get the image dimensions (OpenCV stores image data as NumPy ndarray)
height, width, channels_no = cv_img.shape height, width, channels_no = cv_img.shape
# Get the image dimensions (OpenCV stores image data as NumPy ndarray) # Get the image dimensions (OpenCV stores image data as NumPy ndarray)
height, width, channels_no = cv_img.shape height, width, channels_no = cv_img.shape
else: except ValueError:
# Get the image dimensions (OpenCV stores image data as NumPy ndarray) # Get the image dimensions (OpenCV stores image data as NumPy ndarray)
height, width = cv_img.shape height, width = cv_img.shape
# Get the image dimensions (OpenCV stores image data as NumPy ndarray) # Get the image dimensions (OpenCV stores image data as NumPy ndarray)
@ -761,7 +801,7 @@ class mainWindow(Tk):
self.imageViewer.imgZoom = 1 self.imageViewer.imgZoom = 1
self.imageViewer.blackhat = False self.imageViewer.blackhat = False
self.imageViewer.rotateCount = 0 self.imageViewer.rotateCount = 0
cv_img = cv2.imread(path) cv_img = cv2.imreadmulti(path)
cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB) cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)
# Get the image dimensions (OpenCV stores image data as NumPy ndarray) # Get the image dimensions (OpenCV stores image data as NumPy ndarray)
height, width, channels_no = cv_img.shape height, width, channels_no = cv_img.shape
@ -784,24 +824,25 @@ class mainWindow(Tk):
Tk().withdraw() Tk().withdraw()
showinfo('A propos de CNIRevelator', showinfo('A propos de CNIRevelator',
( 'Version du logiciel : CNIRevelator ' + globs.verstring_full + '\n\n' + ( 'Version du logiciel : CNIRevelator ' + globs.verstring_full + '\n\n'
"CNIRevelator est un logiciel libre : vous avez le droit de le modifier et/ou le distribuer " + "Le fonctionnement de ce logiciel est conforme aux normes du document 9303 de l'OACI régissant les documents de voyages et d'identité" + '\n\n'
"dans les termes de la GNU General Public License telle que publiée par " + "CNIRevelator est un logiciel libre : vous avez le droit de le modifier et/ou le distribuer "
"la Free Software Foundation, dans sa version 3 ou " + "dans les termes de la GNU General Public License telle que publiée par "
"ultérieure. " + "\n\n" + "la Free Software Foundation, dans sa version 3 ou "
"CNIRevelator est distribué dans l'espoir d'être utile, sans toutefois " + "ultérieure. " + "\n\n"
"impliquer une quelconque garantie de " + "CNIRevelator est distribué dans l'espoir d'être utile, sans toutefois "
"QUALITÉ MARCHANDE ou APTITUDE À UN USAGE PARTICULIER. Référez vous à la " + "impliquer une quelconque garantie de "
"GNU General Public License pour plus de détails à ce sujet. " + "QUALITÉ MARCHANDE ou APTITUDE À UN USAGE PARTICULIER. Référez vous à la "
"\n\n" + "GNU General Public License pour plus de détails à ce sujet. "
"Vous devriez avoir reçu une copie de la GNU General Public License " + "\n\n"
"avec CNIRevelator. Si cela n'est pas le cas, jetez un oeil à '<https://www.gnu.org/licenses/>. " + "Vous devriez avoir reçu une copie de la GNU General Public License "
"\n\n" + "avec CNIRevelator. Si cela n'est pas le cas, jetez un oeil à '<https://www.gnu.org/licenses/>. "
"Le module d'OCR Tesseract 4.0 est soumis à l'Apache License 2004" + "\n\n"
"\n\n" + "Le module d'OCR Tesseract 4.0 est soumis à l'Apache License 2004"
"Les bibliothèques python et l'environnement Anaconda 3 sont soumis à la licence BSD 2018-2019" + "\n\n"
"\n\n" + "Les bibliothèques python et l'environnement Anaconda 3 sont soumis à la licence BSD 2018-2019"
"Le code source de ce programme est disponible sur Github à l'adresse <https://github.com/neox95/CNIRevelator>.\n" + "\n\n"
"Le code source de ce programme est disponible sur Github à l'adresse <https://github.com/neox95/CNIRevelator>.\n"
" En cas de problèmes ou demande particulière, ouvrez-y une issue ou bien envoyez un mail à neox@os-k.eu !" " En cas de problèmes ou demande particulière, ouvrez-y une issue ou bien envoyez un mail à neox@os-k.eu !"
), ),
@ -828,6 +869,12 @@ class mainWindow(Tk):
parent=self) parent=self)
def openIssuePage(self):
self.openBrowser("https://github.com/neox95/CNIRevelator/issues")
def openBrowser(self, url):
webbrowser.open_new(url)
def computeSigma(self): def computeSigma(self):
""" """
Launch the checksum computation, infos validation and display the results Launch the checksum computation, infos validation and display the results