zombee11 commited on
Commit
d541639
·
verified ·
1 Parent(s): 3783efb

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +55 -61
main.py CHANGED
@@ -1,10 +1,12 @@
1
  import os
 
2
  os.environ['FLAGS_enable_pir_api'] = '0'
3
  os.environ['FLAGS_use_mkldnn'] = '0'
4
 
5
  import re
6
  import cv2
7
  import json
 
8
  import numpy as np
9
  from fastapi import FastAPI, File, UploadFile, HTTPException
10
  from fastapi.responses import Response
@@ -21,28 +23,26 @@ app.add_middleware(
21
  allow_headers=["*"],
22
  )
23
 
24
- # LAZY LOAD OCR (IMPORTANT)
25
- ocr = None
26
 
27
- def get_ocr():
28
- global ocr
29
- if ocr is None:
30
- ocr = PaddleOCR(use_angle_cls=True, lang='en', use_gpu=False)
31
- return ocr
32
 
33
  def clean_digits(text):
34
- if not text:
35
- return ""
36
- s = str(text).upper()
37
- s = s.replace('O','0').replace('D','0').replace('I','1').replace('L','1').replace('S','5').replace('B','8')
38
  return re.sub(r'[^0-9]', '', s)
39
 
40
- def mask_region(img, bbox):
41
  try:
 
42
  x1, y1 = int(bbox[0][0]), int(bbox[0][1])
43
  x2, y2 = int(bbox[2][0]), int(bbox[2][1])
44
  width = x2 - x1
45
- mask_w = int(width * 0.68)
46
  cv2.rectangle(img, (x1, y1), (x1 + mask_w, y2), (0, 0, 0), -1)
47
  except:
48
  pass
@@ -54,59 +54,53 @@ async def process(file: UploadFile = File(...)):
54
  contents = await file.read()
55
  nparr = np.frombuffer(contents, np.uint8)
56
  img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
 
57
 
58
- if img is None:
59
- raise HTTPException(status_code=400, detail="Invalid image")
60
-
61
- # Resize
62
  h, w = img.shape[:2]
63
  img = cv2.resize(img, (1200, int(h * (1200 / w))))
64
-
65
- # OCR
66
- ocr_engine = get_ocr()
67
- result = ocr_engine.ocr(img)
68
-
69
- if not result:
70
- raise HTTPException(status_code=400, detail="No text detected")
71
-
72
- extracted_data = {"aadhaar": None, "vid": None}
73
-
74
- for line in result:
75
- if not isinstance(line, list):
76
- continue
77
-
78
- for word_info in line:
79
- try:
80
- bbox = word_info[0]
81
- text = word_info[1][0]
82
- conf = word_info[1][1]
83
-
84
- if conf < 0.5:
85
- continue
86
-
87
- clean = clean_digits(text)
88
-
89
- if len(clean) == 12 and not clean.startswith(('0', '1')):
90
- extracted_data["aadhaar"] = clean
91
- img = mask_region(img, bbox)
92
-
93
- elif len(clean) == 16:
94
- extracted_data["vid"] = clean
95
- img = mask_region(img, bbox)
96
-
97
- except:
98
- continue
99
-
100
- _, buffer = cv2.imencode('.jpg', img)
101
-
102
  return Response(
103
  content=buffer.tobytes(),
104
  media_type="image/jpeg",
105
- headers={
106
- "x-data": json.dumps(extracted_data),
107
- "Access-Control-Expose-Headers": "x-data"
108
- }
109
  )
110
-
111
  except Exception as e:
112
- raise HTTPException(status_code=500, detail=str(e))
 
 
 
 
1
  import os
2
+ # Force stable engine to prevent PIR/DoubleAttribute crashes on CPU
3
  os.environ['FLAGS_enable_pir_api'] = '0'
4
  os.environ['FLAGS_use_mkldnn'] = '0'
5
 
6
  import re
7
  import cv2
8
  import json
9
+ import uvicorn
10
  import numpy as np
11
  from fastapi import FastAPI, File, UploadFile, HTTPException
12
  from fastapi.responses import Response
 
23
  allow_headers=["*"],
24
  )
25
 
26
+ # Initialize PaddleOCR (More accurate for IDs than EasyOCR)
27
+ ocr = PaddleOCR(use_angle_cls=True, lang='en', use_gpu=False, show_log=False)
28
 
29
+ def enhance(img):
30
+ gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
31
+ clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
32
+ return clahe.apply(gray)
 
33
 
34
  def clean_digits(text):
35
+ if not text: return ""
36
+ s = str(text).upper().replace('O','0').replace('D','0').replace('I','1').replace('L','1').replace('S','5').replace('B','8')
 
 
37
  return re.sub(r'[^0-9]', '', s)
38
 
39
+ def mask_region(img, bbox, ratio=0.68):
40
  try:
41
+ # PaddleOCR bboxes: [[x1,y1], [x2,y1], [x2,y2], [x1,y2]]
42
  x1, y1 = int(bbox[0][0]), int(bbox[0][1])
43
  x2, y2 = int(bbox[2][0]), int(bbox[2][1])
44
  width = x2 - x1
45
+ mask_w = int(width * ratio)
46
  cv2.rectangle(img, (x1, y1), (x1 + mask_w, y2), (0, 0, 0), -1)
47
  except:
48
  pass
 
54
  contents = await file.read()
55
  nparr = np.frombuffer(contents, np.uint8)
56
  img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
57
+ if img is None: return Response(content=json.dumps({"error": "Invalid image"}), status_code=400)
58
 
59
+ # Standardize size
 
 
 
60
  h, w = img.shape[:2]
61
  img = cv2.resize(img, (1200, int(h * (1200 / w))))
62
+
63
+ # OCR Inference
64
+ result = ocr.ocr(img)
65
+ extracted = {"aadhaar": None, "vid": None}
66
+
67
+ if result and isinstance(result, list):
68
+ flat_list = []
69
+ for line in result:
70
+ if not line: continue
71
+ for res in line:
72
+ flat_list.append({"bbox": res[0], "text": res[1][0], "conf": res[1][1]})
73
+
74
+ for i, item in enumerate(flat_list):
75
+ if item["conf"] < 0.45: continue
76
+ clean = clean_digits(item["text"])
77
+
78
+ # 12-digit Aadhaar
79
+ if len(clean) == 12 and not clean.startswith(('0', '1')):
80
+ extracted["aadhaar"] = clean
81
+ img = mask_region(img, item["bbox"], 0.68)
82
+
83
+ # 16-digit VID
84
+ elif len(clean) == 16:
85
+ extracted["vid"] = clean
86
+ img = mask_region(img, item["bbox"], 0.75)
87
+
88
+ # Split Aadhaar logic (e.g., 4444 5555 6666 across two boxes)
89
+ elif i + 1 < len(flat_list):
90
+ combined = clean + clean_digits(flat_list[i+1]["text"])
91
+ if len(combined) == 12:
92
+ extracted["aadhaar"] = combined
93
+ img = mask_region(img, item["bbox"], 1.0)
94
+ img = mask_region(img, flat_list[i+1]["bbox"], 1.0)
95
+
96
+ _, buffer = cv2.imencode('.jpg', img, [int(cv2.IMWRITE_JPEG_QUALITY), 95])
 
 
 
97
  return Response(
98
  content=buffer.tobytes(),
99
  media_type="image/jpeg",
100
+ headers={"x-data": json.dumps(extracted), "Access-Control-Expose-Headers": "x-data"}
 
 
 
101
  )
 
102
  except Exception as e:
103
+ raise HTTPException(status_code=500, detail=str(e))
104
+
105
+ if __name__ == "__main__":
106
+ uvicorn.run(app, host="0.0.0.0", port=7860)