from fastapi import FastAPI, HTTPException from pydantic import BaseModel from process import FaceHelper, FileError, ErrorMsg import threading import time # 创建 FastAPI 实例 app = FastAPI() # 创建线程锁,确保在多线程环境中对共享资源的访问是线程安全的 lock = threading.Lock() # 全局变量 facehelper,稍后将用于管理人脸识别相关操作 facehelper = None def get_facehelper(): """ 懒加载模式初始化 facehelper 对象。 只有在第一次调用时才会创建 FaceHelper 实例。 使用线程锁以确保 facehelper 实例在多线程环境下的安全初始化。 """ global facehelper if facehelper is None: with lock: if facehelper is None: facehelper = FaceHelper(db_dir="./dbface") return facehelper # 定义请求模型,用于接收前端传递的图像数据 class FaceRequest(BaseModel): img: str # 定义请求模型,用于接收前端传递的数据库操作数据 class DBFaceRequest(BaseModel): img: str optMode: str uniqueKey: str # 接两图片对比的参数 class ImageComparison(BaseModel): firstImage: str secondImage: str @app.post("/refreshdb") def refresh(): """ 刷新人脸数据库的接口。 该接口将调用 facehelper 的 updateDB 方法,刷新数据库内容。 """ facehelper = get_facehelper() try: # 加锁确保数据库更新操作的线程安全性 with lock: facehelper.updateDB(None, None, None, Onlyrefresh=True) except FileError as e: # 处理文件错误,返回相应的错误代码和信息 return {'code': e.code, 'msg': str(e), 'data': None} else: # 成功刷新数据库后返回相应的状态码和消息 return {'code': "30002", 'msg': ErrorMsg['30002'], 'data': None} @app.post("/facerecognition") def faceRecognition(input: FaceRequest): """ 进行人脸识别的接口。 接收前端传递的图像数据,并使用 facehelper 进行人脸识别。 返回识别结果和运行时间。 """ facehelper = get_facehelper() start = time.time() # 记录开始时间 try: # 调用 facehelper 的 faceRecognition 方法进行人脸识别 ret_data = facehelper.faceRecognition(input.img) except Exception as e: # 处理异常,返回相应的错误代码和信息 raise HTTPException(status_code=400, detail={'code': e.code, 'msg': str(e), 'data': None}) finally: end = time.time() # 记录结束时间 # 打印运行时间 print(f"Recognition finished. Runtime: {end - start:.2f} seconds") # 返回识别结果 return ret_data @app.post("/featuredetect") def featureDetect(input: FaceRequest): """ 特征检测接口。 接收前端传递的图像数据,并使用 facehelper 进行特征检测。 返回检测结果和运行时间。 """ facehelper = get_facehelper() start = time.time() # 记录开始时间 try: # 调用 facehelper 的 featureDetect 方法进行特征检测 ret_data = facehelper.featureDetect(input.img) except Exception as e: # 处理异常,返回相应的错误代码和信息 raise HTTPException(status_code=400, detail={'code': e.code, 'msg': str(e), 'data': None}) finally: end = time.time() # 记录结束时间 # 打印运行时间 print(f"Feature detection finished. Runtime: {end - start:.2f} seconds") # 返回检测结果 return ret_data @app.post("/updatedb") def updateDB(input: DBFaceRequest): """ 更新人脸数据库的接口。 接收前端传递的数据库操作数据,并使用 facehelper 更新数据库。 """ facehelper = get_facehelper() try: # 加锁确保数据库更新操作的线程安全性 with lock: facehelper.updateDB(input.img, input.optMode, input.uniqueKey) except Exception as e: # 处理异常,返回相应的错误代码和信息 raise HTTPException(status_code=400, detail={'code': e.code, 'msg': str(e), 'data': None}) else: # 成功更新数据库后返回相应的状态码和消息 return {'code': "30002", 'msg': ErrorMsg['30002'], 'data': None} @app.post("/imageComparison") def imageComparison(input: ImageComparison): """ 更新人脸数据库的接口。 接收前端传递的数据库操作数据,并使用 facehelper 更新数据库。 """ facehelper = get_facehelper() try: # 加锁确保数据库更新操作的线程安全性 with lock: state = facehelper.imageComparison(input.firstImage, input.secondImage) except Exception as e: # 处理异常,返回相应的错误代码和信息 raise HTTPException(status_code=400, detail={'code': e.code, 'msg': str(e), 'data': None}) else: # 成功更新数据库后返回相应的状态码和消息 return {'code': "30002", 'msg': ErrorMsg['30002'], 'data': bool(state)}