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:
parent
9a7ab2e8ee
commit
576ad52a2d
BIN
src/OCR.png
Normal file
BIN
src/OCR.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 512 B |
473
src/main.py
473
src/main.py
@ -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"))
|
||||||
@ -224,9 +227,17 @@ class mainWindow(Tk):
|
|||||||
self.toolbar.rotateRightImg = ImageTk.PhotoImage(PIL.Image.open("rotateRight.png"))
|
self.toolbar.rotateRightImg = ImageTk.PhotoImage(PIL.Image.open("rotateRight.png"))
|
||||||
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)
|
||||||
|
|
||||||
@ -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)
|
||||||
@ -335,22 +348,14 @@ class mainWindow(Tk):
|
|||||||
self.update()
|
self.update()
|
||||||
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)
|
||||||
@ -363,98 +368,100 @@ class mainWindow(Tk):
|
|||||||
def statusUpdate(self, image=None, setplace=False):
|
def statusUpdate(self, image=None, setplace=False):
|
||||||
if image:
|
if image:
|
||||||
self.imageViewer.image = image
|
self.imageViewer.image = image
|
||||||
self.imageViewer.ZONE.itemconfigure(self.STATUSimg, image=(self.imageViewer.image))
|
self.imageViewer.ZONE.itemconfigure(self.STATUSimg, image=(self.imageViewer.image))
|
||||||
self.imageViewer.ZONE.configure(scrollregion=self.imageViewer.ZONE.bbox("all"))
|
self.imageViewer.ZONE.configure(scrollregion=self.imageViewer.ZONE.bbox("all"))
|
||||||
|
|
||||||
def rectangleSelectScan(self, event):
|
|
||||||
canvas = event.widget
|
|
||||||
print("Get coordinates : [{}, {}], for [{}, {}]".format(canvas.canvasx(event.x), canvas.canvasy(event.y), event.x, event.y))
|
|
||||||
|
|
||||||
self.corners.append([canvas.canvasx(event.x), canvas.canvasy(event.y)])
|
def rectangleSelectScan(self, event):
|
||||||
if len(self.corners) == 2:
|
if self.imageViewer.image:
|
||||||
self.select = self.imageViewer.ZONE.create_rectangle(self.corners[0][0], self.corners[0][1], self.corners[1][0], self.corners[1][1], outline ='cyan', width = 2)
|
canvas = event.widget
|
||||||
print("Get rectangle : [{}, {}], for [{}, {}]".format(self.corners[0][0], self.corners[0][1], self.corners[1][0], self.corners[1][1]))
|
print("Get coordinates : [{}, {}], for [{}, {}]".format(canvas.canvasx(event.x), canvas.canvasy(event.y), event.x, event.y))
|
||||||
if len(self.corners) > 2:
|
|
||||||
self.corners = []
|
self.corners.append([canvas.canvasx(event.x), canvas.canvasy(event.y)])
|
||||||
self.imageViewer.ZONE.delete(self.select)
|
if len(self.corners) == 2:
|
||||||
|
self.select = self.imageViewer.ZONE.create_rectangle(self.corners[0][0], self.corners[0][1], self.corners[1][0], self.corners[1][1], outline ='cyan', width = 2)
|
||||||
|
print("Get rectangle : [{}, {}], for [{}, {}]".format(self.corners[0][0], self.corners[0][1], self.corners[1][0], self.corners[1][1]))
|
||||||
|
if len(self.corners) > 2:
|
||||||
|
self.corners = []
|
||||||
|
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.cvtColor(cv_img, cv2.COLOR_BGR2RGB)
|
cv_img = cv2.imreadmulti(self.imageViewer.imagePath)[1][self.imageViewer.pagenumber]
|
||||||
if self.imageViewer.blackhat:
|
cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)
|
||||||
cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2GRAY)
|
if self.imageViewer.blackhat:
|
||||||
cv_img = cv2.GaussianBlur(cv_img, (3, 3), 0)
|
cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2GRAY)
|
||||||
cv_img = cv2.bitwise_not(cv_img)
|
cv_img = cv2.GaussianBlur(cv_img, (3, 3), 0)
|
||||||
if not self.imageViewer.blackhat:
|
cv_img = cv2.bitwise_not(cv_img)
|
||||||
# Get the image dimensions (OpenCV stores image data as NumPy ndarray)
|
|
||||||
height, width, channels_no = cv_img.shape
|
|
||||||
# Get the image dimensions (OpenCV stores image data as NumPy ndarray)
|
|
||||||
height, width, channels_no = cv_img.shape
|
|
||||||
else:
|
|
||||||
# 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
|
|
||||||
# Rotate
|
|
||||||
rotationMatrix=cv2.getRotationMatrix2D((width/2, height/2),int(self.imageViewer.rotateCount*90),1)
|
|
||||||
cv_img=cv2.warpAffine(cv_img,rotationMatrix,(width,height))
|
|
||||||
# Resize
|
|
||||||
dim = (int(width * (self.imageViewer.imgZoom + 100) / 100), int(height * (self.imageViewer.imgZoom + 100) / 100))
|
|
||||||
cv_img = cv2.resize(cv_img, dim, interpolation = cv2.INTER_AREA)
|
|
||||||
|
|
||||||
x0 = int(self.corners[0][0])
|
|
||||||
y0 = int(self.corners[0][1])
|
|
||||||
x1 = int(self.corners[1][0])
|
|
||||||
y1 = int(self.corners[1][1])
|
|
||||||
|
|
||||||
crop_img = cv_img[y0:y1, x0:x1]
|
|
||||||
|
|
||||||
cv2.imshow("image", crop_img)
|
|
||||||
|
|
||||||
# Get the text by OCR
|
|
||||||
try:
|
|
||||||
os.environ['PATH'] = globs.CNIRTesser
|
|
||||||
os.environ['TESSDATA_PREFIX'] = globs.CNIRTesser + '\\tessdata'
|
|
||||||
|
|
||||||
text = pytesseract.image_to_string(crop_img, lang='ocrb', boxes=False, config='--psm 6 --oem 0 -c tessedit_char_whitelist=ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890<')
|
|
||||||
|
|
||||||
# manual validation
|
|
||||||
# the regex
|
|
||||||
regex = re.compile("[^A-Z0-9<\n]")
|
|
||||||
text = re.sub(regex, '', text)
|
|
||||||
self.validatedtext = ''
|
|
||||||
invite = ihm.OpenScanDialog(self, text)
|
|
||||||
invite.transient(self)
|
|
||||||
invite.grab_set()
|
|
||||||
invite.focus_force()
|
|
||||||
self.wait_window(invite)
|
|
||||||
|
|
||||||
print("text : {}".format(self.validatedtext))
|
|
||||||
|
|
||||||
self.mrzChar = ""
|
|
||||||
|
|
||||||
# Get that
|
|
||||||
for char in self.validatedtext:
|
|
||||||
self.termtext.delete("1.0","end")
|
|
||||||
self.termtext.insert("1.0", self.mrzChar)
|
|
||||||
self.mrzChar = self.mrzChar + char
|
|
||||||
|
|
||||||
self.stringValidation("")
|
|
||||||
print(self.mrzChar)
|
|
||||||
|
|
||||||
# Reinstall tesseract
|
|
||||||
except pytesseract.TesseractNotFoundError as e:
|
|
||||||
try:
|
try:
|
||||||
shutil.rmtree(globs.CNIRTesser)
|
# Get the image dimensions (OpenCV stores image data as NumPy ndarray)
|
||||||
except Exception:
|
height, width, channels_no = cv_img.shape
|
||||||
pass
|
# Get the image dimensions (OpenCV stores image data as NumPy ndarray)
|
||||||
showerror('Erreur de module OCR', ('Le module OCR localisé en ' + str(os.environ['PATH']) + 'est introuvable ou corrompu. Il sera réinstallé à la prochaine exécution'), parent=self)
|
height, width, channels_no = cv_img.shape
|
||||||
logfile.printerr("Tesseract error : {}. Will be reinstallated".format(e))
|
except ValueError:
|
||||||
|
# Get the image dimensions (OpenCV stores image data as NumPy ndarray)
|
||||||
# Tesseract error
|
height, width = cv_img.shape
|
||||||
except pytesseract.TesseractError as e:
|
# Get the image dimensions (OpenCV stores image data as NumPy ndarray)
|
||||||
logfile.printerr("Tesseract error : {}".format(e))
|
height, width = cv_img.shape
|
||||||
showerror('Erreur de module OCR', ("Le module Tesseract a rencontré un problème : {}".format(e)), parent=self)
|
# Rotate
|
||||||
|
rotationMatrix=cv2.getRotationMatrix2D((width/2, height/2),int(self.imageViewer.rotateCount*90),1)
|
||||||
|
cv_img=cv2.warpAffine(cv_img,rotationMatrix,(width,height))
|
||||||
|
# Resize
|
||||||
|
dim = (int(width * (self.imageViewer.imgZoom + 100) / 100), int(height * (self.imageViewer.imgZoom + 100) / 100))
|
||||||
|
cv_img = cv2.resize(cv_img, dim, interpolation = cv2.INTER_AREA)
|
||||||
|
|
||||||
|
x0 = int(self.corners[0][0])
|
||||||
|
y0 = int(self.corners[0][1])
|
||||||
|
x1 = int(self.corners[1][0])
|
||||||
|
y1 = int(self.corners[1][1])
|
||||||
|
|
||||||
|
crop_img = cv_img[y0:y1, x0:x1]
|
||||||
|
|
||||||
|
cv2.imshow("image", crop_img)
|
||||||
|
|
||||||
|
# Get the text by OCR
|
||||||
|
try:
|
||||||
|
os.environ['PATH'] = globs.CNIRTesser
|
||||||
|
os.environ['TESSDATA_PREFIX'] = globs.CNIRTesser + '\\tessdata'
|
||||||
|
|
||||||
|
text = pytesseract.image_to_string(crop_img, lang='ocrb', boxes=False, config='--psm 6 --oem 0 -c tessedit_char_whitelist=ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890<')
|
||||||
|
|
||||||
|
# manual validation
|
||||||
|
# the regex
|
||||||
|
regex = re.compile("[^A-Z0-9<\n]")
|
||||||
|
text = re.sub(regex, '', text)
|
||||||
|
self.validatedtext = ''
|
||||||
|
invite = ihm.OpenScanDialog(self, text)
|
||||||
|
invite.transient(self)
|
||||||
|
invite.grab_set()
|
||||||
|
invite.focus_force()
|
||||||
|
self.wait_window(invite)
|
||||||
|
|
||||||
|
print("text : {}".format(self.validatedtext))
|
||||||
|
|
||||||
|
self.mrzChar = ""
|
||||||
|
|
||||||
|
# Get that
|
||||||
|
for char in self.validatedtext:
|
||||||
|
self.termtext.delete("1.0","end")
|
||||||
|
self.termtext.insert("1.0", self.mrzChar)
|
||||||
|
self.mrzChar = self.mrzChar + char
|
||||||
|
|
||||||
|
self.stringValidation("")
|
||||||
|
print(self.mrzChar)
|
||||||
|
|
||||||
|
# Reinstall tesseract
|
||||||
|
except pytesseract.TesseractNotFoundError as e:
|
||||||
|
try:
|
||||||
|
shutil.rmtree(globs.CNIRTesser)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
showerror('Erreur de module OCR', ('Le module OCR localisé en ' + str(os.environ['PATH']) + 'est introuvable ou corrompu. Il sera réinstallé à la prochaine exécution'), parent=self)
|
||||||
|
logfile.printerr("Tesseract error : {}. Will be reinstallated".format(e))
|
||||||
|
|
||||||
|
# Tesseract error
|
||||||
|
except pytesseract.TesseractError as e:
|
||||||
|
logfile.printerr("Tesseract error : {}".format(e))
|
||||||
|
showerror('Erreur de module OCR', ("Le module Tesseract a rencontré un problème : {}".format(e)), parent=self)
|
||||||
|
|
||||||
|
|
||||||
def stringValidation(self, keysym):
|
def stringValidation(self, keysym):
|
||||||
@ -639,7 +646,10 @@ 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 = ''
|
||||||
path = filedialog.askopenfilename(parent=self, title='Ouvrir un scan de CNI...', filetypes=(('TIF files', '*.tif'),
|
path = filedialog.askopenfilename(parent=self, title='Ouvrir un scan de CNI...', filetypes=(('TIF files', '*.tif'),
|
||||||
@ -651,130 +661,160 @@ 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)
|
||||||
# Get the image dimensions (OpenCV stores image data as NumPy ndarray)
|
|
||||||
height, width, channels_no = cv_img.shape
|
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)
|
||||||
|
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):
|
||||||
self.imageViewer.imgZoom += quantity
|
if self.imageViewer.image:
|
||||||
self.resizeScan()
|
self.imageViewer.imgZoom += quantity
|
||||||
|
self.resizeScan()
|
||||||
|
|
||||||
def zoomOutScan50(self, quantity = 50):
|
def zoomOutScan50(self, quantity = 50):
|
||||||
self.imageViewer.imgZoom -= quantity
|
if self.imageViewer.image:
|
||||||
self.resizeScan()
|
self.imageViewer.imgZoom -= quantity
|
||||||
|
self.resizeScan()
|
||||||
|
|
||||||
def zoomInScan20(self, quantity = 20):
|
def zoomInScan20(self, quantity = 20):
|
||||||
self.imageViewer.imgZoom += quantity
|
if self.imageViewer.image:
|
||||||
self.resizeScan()
|
self.imageViewer.imgZoom += quantity
|
||||||
|
self.resizeScan()
|
||||||
|
|
||||||
def zoomOutScan20(self, quantity = 20):
|
def zoomOutScan20(self, quantity = 20):
|
||||||
self.imageViewer.imgZoom -= quantity
|
if self.imageViewer.image:
|
||||||
self.resizeScan()
|
self.imageViewer.imgZoom -= quantity
|
||||||
|
self.resizeScan()
|
||||||
|
|
||||||
def zoomInScan(self, quantity = 1):
|
def zoomInScan(self, quantity = 1):
|
||||||
self.imageViewer.imgZoom += quantity
|
if self.imageViewer.image:
|
||||||
self.resizeScan()
|
self.imageViewer.imgZoom += quantity
|
||||||
|
self.resizeScan()
|
||||||
|
|
||||||
def zoomOutScan(self, quantity = 1):
|
def zoomOutScan(self, quantity = 1):
|
||||||
self.imageViewer.imgZoom -= quantity
|
if self.imageViewer.image:
|
||||||
self.resizeScan()
|
self.imageViewer.imgZoom -= quantity
|
||||||
|
self.resizeScan()
|
||||||
|
|
||||||
def rotateRight(self):
|
def rotateRight(self):
|
||||||
self.imageViewer.rotateCount -= 1
|
if self.imageViewer.image:
|
||||||
if self.imageViewer.rotateCount < 0:
|
self.imageViewer.rotateCount -= 1
|
||||||
self.imageViewer.rotateCount = 4
|
if self.imageViewer.rotateCount < 0:
|
||||||
self.resizeScan()
|
self.imageViewer.rotateCount = 4
|
||||||
|
self.resizeScan()
|
||||||
|
|
||||||
def rotateLeft(self):
|
def rotateLeft(self):
|
||||||
self.imageViewer.rotateCount += 1
|
if self.imageViewer.image:
|
||||||
if self.imageViewer.rotateCount > 4:
|
self.imageViewer.rotateCount += 1
|
||||||
self.imageViewer.rotateCount = 0
|
if self.imageViewer.rotateCount > 4:
|
||||||
self.resizeScan()
|
self.imageViewer.rotateCount = 0
|
||||||
|
self.resizeScan()
|
||||||
|
|
||||||
def rotateLeft1(self):
|
def rotateLeft1(self):
|
||||||
self.imageViewer.rotateCount += 0.01
|
if self.imageViewer.image:
|
||||||
if self.imageViewer.rotateCount > 4:
|
self.imageViewer.rotateCount += 0.01
|
||||||
self.imageViewer.rotateCount = 0
|
if self.imageViewer.rotateCount > 4:
|
||||||
self.resizeScan()
|
self.imageViewer.rotateCount = 0
|
||||||
|
self.resizeScan()
|
||||||
|
|
||||||
def rotateRight1(self):
|
def rotateRight1(self):
|
||||||
self.imageViewer.rotateCount -= 0.01
|
if self.imageViewer.image:
|
||||||
if self.imageViewer.rotateCount < 0:
|
self.imageViewer.rotateCount -= 0.01
|
||||||
self.imageViewer.rotateCount = 4
|
if self.imageViewer.rotateCount < 0:
|
||||||
self.resizeScan()
|
self.imageViewer.rotateCount = 4
|
||||||
|
self.resizeScan()
|
||||||
|
|
||||||
def negativeScan(self):
|
def negativeScan(self):
|
||||||
# Load an image using OpenCV
|
if self.imageViewer.image:
|
||||||
cv_img = cv2.imread(self.imageViewer.imagePath)
|
# Load an image using OpenCV
|
||||||
cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)
|
cv_img = cv2.imreadmulti(self.imageViewer.imagePath)[1][self.imageViewer.pagenumber]
|
||||||
if not self.imageViewer.blackhat:
|
cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)
|
||||||
self.imageViewer.blackhat = True
|
if not self.imageViewer.blackhat:
|
||||||
cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2GRAY)
|
self.imageViewer.blackhat = True
|
||||||
cv_img = cv2.GaussianBlur(cv_img, (3, 3), 0)
|
cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2GRAY)
|
||||||
cv_img = cv2.bitwise_not(cv_img)
|
cv_img = cv2.GaussianBlur(cv_img, (3, 3), 0)
|
||||||
else:
|
cv_img = cv2.bitwise_not(cv_img)
|
||||||
self.imageViewer.blackhat = False
|
else:
|
||||||
self.resizeScan(cv_img)
|
self.imageViewer.blackhat = False
|
||||||
|
self.resizeScan(cv_img)
|
||||||
|
|
||||||
def resizeScan(self, cv_img = None):
|
def resizeScan(self, cv_img = None):
|
||||||
try:
|
if self.imageViewer.image:
|
||||||
if not hasattr(cv_img, 'shape'):
|
|
||||||
# Load an image using OpenCV
|
|
||||||
cv_img = cv2.imread(self.imageViewer.imagePath)
|
|
||||||
cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)
|
|
||||||
if self.imageViewer.blackhat:
|
|
||||||
cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2GRAY)
|
|
||||||
cv_img = cv2.GaussianBlur(cv_img, (3, 3), 0)
|
|
||||||
cv_img = cv2.bitwise_not(cv_img)
|
|
||||||
|
|
||||||
if not self.imageViewer.blackhat:
|
|
||||||
# Get the image dimensions (OpenCV stores image data as NumPy ndarray)
|
|
||||||
height, width, channels_no = cv_img.shape
|
|
||||||
# Get the image dimensions (OpenCV stores image data as NumPy ndarray)
|
|
||||||
height, width, channels_no = cv_img.shape
|
|
||||||
else:
|
|
||||||
# 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
|
|
||||||
# Rotate
|
|
||||||
rotationMatrix=cv2.getRotationMatrix2D((width/2, height/2),int(self.imageViewer.rotateCount*90),1)
|
|
||||||
cv_img=cv2.warpAffine(cv_img,rotationMatrix,(width,height))
|
|
||||||
# Resize
|
|
||||||
dim = (int(width * (self.imageViewer.imgZoom + 100) / 100), int(height * (self.imageViewer.imgZoom + 100) / 100))
|
|
||||||
cv_img = cv2.resize(cv_img, dim, interpolation = cv2.INTER_AREA)
|
|
||||||
# Use PIL (Pillow) to convert the NumPy ndarray to a PhotoImage
|
|
||||||
photo = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(cv_img))
|
|
||||||
self.statusUpdate( photo)
|
|
||||||
except Exception as e:
|
|
||||||
logfile.printerr("Error with opencv : {}".format(e))
|
|
||||||
traceback.print_exc(file=sys.stdout)
|
|
||||||
try:
|
try:
|
||||||
# Reload an image using OpenCV
|
if not hasattr(cv_img, 'shape'):
|
||||||
path = self.imageViewer.imagePath
|
# Load an image using OpenCV
|
||||||
self.imageViewer.imgZoom = 1
|
cv_img = cv2.imreadmulti(self.imageViewer.imagePath)[1][self.imageViewer.pagenumber]
|
||||||
self.imageViewer.blackhat = False
|
cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)
|
||||||
self.imageViewer.rotateCount = 0
|
if self.imageViewer.blackhat:
|
||||||
cv_img = cv2.imread(path)
|
cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2GRAY)
|
||||||
cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)
|
cv_img = cv2.GaussianBlur(cv_img, (3, 3), 0)
|
||||||
# Get the image dimensions (OpenCV stores image data as NumPy ndarray)
|
cv_img = cv2.bitwise_not(cv_img)
|
||||||
height, width, channels_no = cv_img.shape
|
|
||||||
# Get the image dimensions (OpenCV stores image data as NumPy ndarray)
|
try:
|
||||||
height, width, channels_no = cv_img.shape
|
# Get the image dimensions (OpenCV stores image data as NumPy ndarray)
|
||||||
|
height, width, channels_no = cv_img.shape
|
||||||
|
# Get the image dimensions (OpenCV stores image data as NumPy ndarray)
|
||||||
|
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
|
||||||
|
# Rotate
|
||||||
|
rotationMatrix=cv2.getRotationMatrix2D((width/2, height/2),int(self.imageViewer.rotateCount*90),1)
|
||||||
|
cv_img=cv2.warpAffine(cv_img,rotationMatrix,(width,height))
|
||||||
|
# Resize
|
||||||
|
dim = (int(width * (self.imageViewer.imgZoom + 100) / 100), int(height * (self.imageViewer.imgZoom + 100) / 100))
|
||||||
|
cv_img = cv2.resize(cv_img, dim, interpolation = cv2.INTER_AREA)
|
||||||
# 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)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logfile.printerr("Critical error with opencv : ".format(e))
|
logfile.printerr("Error with opencv : {}".format(e))
|
||||||
traceback.print_exc(file=sys.stdout)
|
traceback.print_exc(file=sys.stdout)
|
||||||
showerror("Erreur OpenCV (traitement d'images)", "Une erreur critique s'est produite dans le gestionnaire de traitement d'images OpenCV utilisé par CNIRevelator. L'application va se réinitialiser")
|
try:
|
||||||
self.initialize()
|
# Reload an image using OpenCV
|
||||||
|
path = self.imageViewer.imagePath
|
||||||
|
self.imageViewer.imgZoom = 1
|
||||||
|
self.imageViewer.blackhat = False
|
||||||
|
self.imageViewer.rotateCount = 0
|
||||||
|
cv_img = cv2.imreadmulti(path)
|
||||||
|
cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)
|
||||||
|
# Get the image dimensions (OpenCV stores image data as NumPy ndarray)
|
||||||
|
height, width, channels_no = cv_img.shape
|
||||||
|
# Get the image dimensions (OpenCV stores image data as NumPy ndarray)
|
||||||
|
height, width, channels_no = 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)
|
||||||
|
except Exception as e:
|
||||||
|
logfile.printerr("Critical error with opencv : ".format(e))
|
||||||
|
traceback.print_exc(file=sys.stdout)
|
||||||
|
showerror("Erreur OpenCV (traitement d'images)", "Une erreur critique s'est produite dans le gestionnaire de traitement d'images OpenCV utilisé par CNIRevelator. L'application va se réinitialiser")
|
||||||
|
self.initialize()
|
||||||
|
|
||||||
def newEntry(self):
|
def newEntry(self):
|
||||||
self.initialize()
|
self.initialize()
|
||||||
@ -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 !"
|
||||||
),
|
),
|
||||||
|
|
||||||
@ -827,6 +868,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):
|
||||||
"""
|
"""
|
||||||
|
Loading…
Reference in New Issue
Block a user