anh-khoa-nguyen commited on
Commit
87b7701
·
1 Parent(s): 7ff4e74

last update

Browse files
Files changed (4) hide show
  1. .idea/.name +1 -0
  2. .idea/vcs.xml +6 -0
  3. app.py +36 -45
  4. core/extractor.py +1 -34
.idea/.name ADDED
@@ -0,0 +1 @@
 
 
1
+ app.py
.idea/vcs.xml ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="" vcs="Git" />
5
+ </component>
6
+ </project>
app.py CHANGED
@@ -13,6 +13,7 @@ import numpy as np
13
  from fastapi import FastAPI, File, UploadFile, HTTPException
14
  from fastapi.responses import RedirectResponse
15
  from pydantic import BaseModel
 
16
 
17
  # --- KHỞI TẠO ỨNG DỤNG VÀ CÁC BIẾN TOÀN CỤC ---
18
  description_md = """
@@ -27,56 +28,47 @@ API này sử dụng các thư viện `vietocr` và `paddleocr` để thực hi
27
  _API được xây dựng với FastAPI._
28
  """
29
 
 
 
30
  app = FastAPI(
31
  title="Vietnamese Citizen ID OCR API",
32
  description=description_md,
33
- version="1.4.0"
34
  )
35
 
36
- # Khởi tạo các biến model toàn cục là None. Chúng sẽ được tải sau.
37
- idcard_extractor = None
38
- face_cascade = None
39
- model_lock = threading.Lock() # Lock để đảm bảo model chỉ được tải 1 lần trong môi trường đa luồng
40
-
41
-
42
- # --- HÀM TẢI MODEL (LAZY LOADING) ---
43
-
44
- def load_models():
45
  """
46
- Hàm này chỉ được gọi một lần duy nhất khi có request đầu tiên.
47
- tải tất cả các model AI nặng vào bộ nhớ.
48
  """
49
- global idcard_extractor, face_cascade
50
-
51
- # Sử dụng lock để ngăn chặn nhiều request cùng lúc cố gắng tải model (race condition)
52
- with model_lock:
53
- # Kiểm tra lại một lần nữa bên trong lock, nếu một luồng khác đã tải xong thì bỏ qua.
54
- if idcard_extractor is None:
55
- print("--- LAZY LOADING MODELS (FIRST REQUEST) ---")
56
- try:
57
- # Import Extractor ngay tại đây, không import ở đầu file
58
- from core.extractor import Extractor
59
-
60
- # 1. Tải model OCR (sẽ đọc từ các file cục bộ trong thư mục /models)
61
- print("Loading OCR models...")
62
- idcard_extractor = Extractor()
63
- print("CCCD Text Extractor loaded successfully.")
64
-
65
- # 2. Tải model nhận diện khuôn mặt
66
- print("Loading face detection model...")
67
- face_cascade_path = os.path.join(cv2.data.haarcascades, 'haarcascade_frontalface_default.xml')
68
- if not os.path.exists(face_cascade_path):
69
- raise FileNotFoundError("Không tìm thấy file haarcascade.")
70
- face_cascade = cv2.CascadeClassifier(face_cascade_path)
71
- print("Face cascade classifier loaded successfully.")
72
-
73
- except Exception as e:
74
- print(f"FATAL: Error during model loading: {e}")
75
- # Đặt lại thành None để các request sau biết rằng model đã tải thất bại
76
- idcard_extractor = None
77
- face_cascade = None
78
- print("--- MODEL LOADING COMPLETE ---")
79
 
 
 
 
 
 
 
 
 
80
 
81
  # --- ĐỊNH NGHĨA MODEL CHO RESPONSE ---
82
 
@@ -91,9 +83,7 @@ class ExtractionResponse(BaseModel):
91
  portrait_image_base64: Optional[str] = None
92
  elapsed: float
93
 
94
-
95
  # --- API ENDPOINT ---
96
-
97
  @app.get("/", include_in_schema=False)
98
  async def root():
99
  """
@@ -110,7 +100,8 @@ async def extract_id_card_info(file: UploadFile = File(...)):
110
  """
111
  # Bước 1: Tải model nếu chưa có
112
  # Nếu model đã được tải, hàm này sẽ bỏ qua rất nhanh.
113
- load_models()
 
114
 
115
  # Kiểm tra xem model đã được tải thành công chưa
116
  if not idcard_extractor or not face_cascade:
 
13
  from fastapi import FastAPI, File, UploadFile, HTTPException
14
  from fastapi.responses import RedirectResponse
15
  from pydantic import BaseModel
16
+ from core.extractor import Extractor
17
 
18
  # --- KHỞI TẠO ỨNG DỤNG VÀ CÁC BIẾN TOÀN CỤC ---
19
  description_md = """
 
28
  _API được xây dựng với FastAPI._
29
  """
30
 
31
+ ml_models = {}
32
+
33
  app = FastAPI(
34
  title="Vietnamese Citizen ID OCR API",
35
  description=description_md,
36
+ version="1.4.0",
37
  )
38
 
39
+ @app.on_event("startup")
40
+ async def startup_event():
 
 
 
 
 
 
 
41
  """
42
+ Code này sẽ chạy KHI server khởi động.
43
+ Thực hiện tải các model AI (Eager Loading).
44
  """
45
+ print("--- EAGER LOADING MODELS (ON STARTUP) ---")
46
+ try:
47
+ print("Loading OCR models...")
48
+ ml_models["idcard_extractor"] = Extractor()
49
+ print("CCCD Text Extractor loaded successfully.")
50
+
51
+ print("Loading face detection model...")
52
+ face_cascade_path = os.path.join(cv2.data.haarcascades, 'haarcascade_frontalface_default.xml')
53
+ if not os.path.exists(face_cascade_path):
54
+ raise FileNotFoundError("Không tìm thấy file haarcascade.")
55
+ ml_models["face_cascade"] = cv2.CascadeClassifier(face_cascade_path)
56
+ print("Face cascade classifier loaded successfully.")
57
+
58
+ print("--- MODEL LOADING COMPLETE ---")
59
+ except Exception as e:
60
+ print(f"FATAL: Error during model loading on startup: {e}")
61
+ # Nếu lỗi, re-raise exception để ngăn server khởi động
62
+ raise
 
 
 
 
 
 
 
 
 
 
 
 
63
 
64
+ @app.on_event("shutdown")
65
+ async def shutdown_event():
66
+ """
67
+ Code này sẽ chạy KHI server tắt (shutdown).
68
+ Dọn dẹp các model.
69
+ """
70
+ print("--- Cleaning up models ---")
71
+ ml_models.clear()
72
 
73
  # --- ĐỊNH NGHĨA MODEL CHO RESPONSE ---
74
 
 
83
  portrait_image_base64: Optional[str] = None
84
  elapsed: float
85
 
 
86
  # --- API ENDPOINT ---
 
87
  @app.get("/", include_in_schema=False)
88
  async def root():
89
  """
 
100
  """
101
  # Bước 1: Tải model nếu chưa có
102
  # Nếu model đã được tải, hàm này sẽ bỏ qua rất nhanh.
103
+ idcard_extractor = ml_models.get("idcard_extractor")
104
+ face_cascade = ml_models.get("face_cascade")
105
 
106
  # Kiểm tra xem model đã được tải thành công chưa
107
  if not idcard_extractor or not face_cascade:
core/extractor.py CHANGED
@@ -299,37 +299,4 @@ class Extractor:
299
  # f.write(json.dumps(result, indent=4, ensure_ascii=False))
300
  # f.close()
301
 
302
- return result
303
-
304
-
305
- ####################################################################################################
306
-
307
- idcard_extractor = Extractor()
308
- # info = idcard_extractor.GetInformationAndSave("extracted_result")
309
- # print(info)
310
-
311
- if __name__ == '__main__':
312
- img_path = './20211019_090832.jpg'
313
- frame = cv2.imread(img_path)
314
- # annotations = idcard_extractor.Detection(img_path)
315
- # extracted_result=[]
316
-
317
- # threads = []
318
- # for i, box in enumerate(annotations):
319
-
320
- # top_left = (int(box[0][0]), int(box[0][1]))
321
- # top_right = (int(box[1][0]), int(box[1][1]))
322
- # bottom_right = (int(box[2][0]), int(box[2][1]))
323
- # bottom_left = (int(box[3][0]), int(box[3][1]))
324
-
325
- # t = ThreadWithReturnValue(target=idcard_extractor.WarpAndRec, args=(frame,top_left, top_right, bottom_right, bottom_left))
326
- # threads.append(t)
327
-
328
- # for t in threads:
329
- # t.start()
330
-
331
- # for t in threads:
332
- # extracted_result.append(t.join())
333
-
334
- info = idcard_extractor.GetInformationAndSave("extracted_result")
335
- print(info)
 
299
  # f.write(json.dumps(result, indent=4, ensure_ascii=False))
300
  # f.close()
301
 
302
+ return result