Midnightar commited on
Commit
00f82b6
·
verified ·
1 Parent(s): 52facb0

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +193 -0
app.py ADDED
@@ -0,0 +1,193 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, UploadFile, File
2
+ from PIL import Image
3
+ import easyocr
4
+ import cv2
5
+ import numpy as np
6
+ import re
7
+ import os
8
+
9
+ app = FastAPI()
10
+
11
+ reader = easyocr.Reader(['en'])
12
+
13
+ # =========================
14
+ # IMAGE QUALITY CHECKS
15
+ # =========================
16
+
17
+ def is_blurry(image):
18
+ gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
19
+ variance = cv2.Laplacian(gray, cv2.CV_64F).var()
20
+
21
+ if variance < 100:
22
+ return True
23
+
24
+ return False
25
+
26
+
27
+ def is_too_dark(image):
28
+ brightness = np.mean(image)
29
+
30
+ if brightness < 50:
31
+ return True
32
+
33
+ return False
34
+
35
+
36
+ # =========================
37
+ # OCR EXTRACTION
38
+ # =========================
39
+
40
+ def extract_text(image_path):
41
+
42
+ results = reader.readtext(image_path)
43
+
44
+ text = " ".join([r[1] for r in results]).lower()
45
+
46
+ return text
47
+
48
+
49
+ # =========================
50
+ # DOCUMENT VALIDATION
51
+ # =========================
52
+
53
+ def detect_document(text):
54
+
55
+ # NIN
56
+ if (
57
+ "national identification number" in text
58
+ or "nin" in text
59
+ ):
60
+ return "nin"
61
+
62
+ # Passport
63
+ elif (
64
+ "passport" in text
65
+ or "federal republic of nigeria" in text
66
+ ):
67
+ return "passport"
68
+
69
+ # Driver License
70
+ elif (
71
+ "driver" in text
72
+ and "license" in text
73
+ ):
74
+ return "drivers_license"
75
+
76
+ # Voter Card
77
+ elif (
78
+ "voter" in text
79
+ or "inec" in text
80
+ ):
81
+ return "voters_card"
82
+
83
+ # Utility Bill
84
+ elif (
85
+ "electricity" in text
86
+ or "water bill" in text
87
+ or "eko electric" in text
88
+ or "ikeja electric" in text
89
+ ):
90
+ return "utility_bill"
91
+
92
+ # Bank Statement
93
+ elif (
94
+ "account statement" in text
95
+ or "transaction" in text
96
+ or "balance" in text
97
+ ):
98
+ return "bank_statement"
99
+
100
+ # Tenancy Agreement
101
+ elif (
102
+ "tenancy agreement" in text
103
+ or "landlord" in text
104
+ or "tenant" in text
105
+ ):
106
+ return "tenancy_agreement"
107
+
108
+ # Vehicle Plate Number
109
+ elif re.search(r"[A-Z]{3}-?\d{3}[A-Z]{2}", text.upper()):
110
+ return "vehicle_plate"
111
+
112
+ return None
113
+
114
+
115
+ # =========================
116
+ # MAIN API ENDPOINT
117
+ # =========================
118
+
119
+ @app.post("/validate")
120
+
121
+ async def validate_document(
122
+ file: UploadFile = File(...)
123
+ ):
124
+
125
+ try:
126
+
127
+ # SAVE IMAGE
128
+ temp_path = "temp.jpg"
129
+
130
+ with open(temp_path, "wb") as f:
131
+ f.write(await file.read())
132
+
133
+ # READ IMAGE
134
+ image = cv2.imread(temp_path)
135
+
136
+ if image is None:
137
+ return {
138
+ "success": False,
139
+ "message": "Invalid image"
140
+ }
141
+
142
+ # =========================
143
+ # IMAGE QUALITY CHECK
144
+ # =========================
145
+
146
+ if is_blurry(image):
147
+ return {
148
+ "success": False,
149
+ "message": "Image is blurry"
150
+ }
151
+
152
+ if is_too_dark(image):
153
+ return {
154
+ "success": False,
155
+ "message": "Image is too dark"
156
+ }
157
+
158
+ # =========================
159
+ # OCR
160
+ # =========================
161
+
162
+ text = extract_text(temp_path)
163
+
164
+ if len(text.strip()) == 0:
165
+ return {
166
+ "success": False,
167
+ "message": "No readable text found"
168
+ }
169
+
170
+ # =========================
171
+ # DOCUMENT DETECTION
172
+ # =========================
173
+
174
+ document_type = detect_document(text)
175
+
176
+ if document_type is None:
177
+ return {
178
+ "success": False,
179
+ "message": "Rejected: Unsupported document"
180
+ }
181
+
182
+ return {
183
+ "success": True,
184
+ "document_type": document_type,
185
+ "extracted_text": text[:300]
186
+ }
187
+
188
+ except Exception as e:
189
+
190
+ return {
191
+ "success": False,
192
+ "message": str(e)
193
+ }