This repository has been archived by the owner on Mar 30, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
/
ocr.py
123 lines (92 loc) · 3.72 KB
/
ocr.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
from passporteye import read_mrz
from passporteye.mrz.text import MRZCheckDigit
from PIL import Image
import cv2
import os, time, io, re, logging
import threading
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO)
class OCR:
def __init__(self):
self.cap = cv2.VideoCapture(0)
self.tmp_file = 'tmp_capture.png'
self.mrz_list = None
self.sleep_time = .5
self.finished = False
def get_mrz(self):
tmp_file = self.tmp_file
mrz_list = self.mrz_list
_, frame = self.cap.read()
cv2.imwrite(tmp_file, frame)
try:
mrz = read_mrz(tmp_file)
logging.info(mrz)
except ValueError as e:
logging.warning("Something went wrong...")
return None
print("Trying...")
if mrz != None:
mrz_list = [mrz.number, mrz.date_of_birth, mrz.expiration_date]
# print("OCR: checking string [{}]".format(mrz_list))
logging.info("OCR: checking string [{}]".format(mrz_list))
valid_number = self.validate_doc_number(mrz.number, mrz.check_number)
if (valid_number != None) & mrz.valid_date_of_birth & mrz.valid_expiration_date:
mrz_list = [valid_number, mrz.date_of_birth, mrz.expiration_date]
# print(mrz_list)
os.remove(tmp_file)
return mrz_list
return None
def end_capture(self):
self.cap.release()
cv2.destroyAllWindows()
def validate_doc_number(self, number, check_number):
for number in self.permutations(number):
computed_check_number = MRZCheckDigit.compute(number)
if check_number == computed_check_number:
return number
return None
def permutations(self, s, before="", replace="O", replace_by="0"):
"""
This function will replace every occurance of a character or string with another character or string.
In every possible setup, e.g. 'xxx' as input, where 'y' replaces 'x' will be return ['yxx', 'xyx', 'xxy', 'yyx', 'yxy', ... ]
Written by Jurien Vegter in order to fix an issue where the passporteye ocr mistakes '0's for 'O's
"""
if len(s) == len(before):
result = []
elif replace in s[len(before):]:
pattern = r'(^{before}[^{replace}]*)({replace})(.*$)'.format(before=before, replace=replace)
replaced = re.sub(pattern, r'\1[]\3', s).replace("[]", replace_by)
result = [s, replaced]
before = re.sub(pattern, r'\1', s)
result.extend(self.permutations(s, before + replace, replace, replace_by))
result.extend(self.permutations(replaced, before + replace_by, replace, replace_by))
else:
result = [s]
return result
def find_mrz(self):
time.sleep(3)
while True:
res = self.get_mrz()
if res:
self.finished = True
logging.info("Result: {}".format(res))
break
time.sleep(self.sleep_time)
self.end_capture()
def webcam(self):
while True:
if self.finished:
break
ret, frame = self.cap.read()
cv2.imshow('webcam', frame)
c = cv2.waitKey(1)
if c == 27:
break
self.end_capture()
# print(permutations(""))
# print(permutations("aObOcOd", "", "b", "XYZ"))
# print(permutations("NOHFO7F71"))
ocr = OCR()
webcam_thread = threading.Thread(name='webcam', target=ocr.webcam)
mrz_thread = threading.Thread(name='mrz', target=ocr.find_mrz)
webcam_thread.start()
mrz_thread.start()