from typing import Optional import uuid from fastapi import FastAPI, File, UploadFile, HTTPException from fastapi.responses import HTMLResponse, JSONResponse import os from fastapi.middleware.cors import CORSMiddleware from utils import crop_images_from_detections, detect_licensePlate, upload_to_s3 # from pinecone import Pinecone # from deepface import DeepFace app = FastAPI() app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"] ) # Directory to save the uploaded images # Create the upload directory if it doesn't exist os.makedirs('uploads', exist_ok=True) os.makedirs('license', exist_ok=True) @app.get("/", response_class=HTMLResponse) async def read_items(): html_content = """ API Documentation

API Documentation

Welcome to VVIMS AI App! 😊

Explore the wonders of our OCR and ANPR APIs! These powerful tools utilize AI to effortlessly decipher and recognize elements within Cameroonian ID cards, extracting valuable information with just a simple call to the "/idextract" endpoint. With our technology, you'll gain the ability to see beyond the surface and effortlessly identify vehicle license plates using the "/carplate" endpoint. The power is now yours to wield. Unleash the full potential of these tools and revolutionize your workflow..

Let this app be the beginning of your journey towards greatness!

/idextract Endpoint

The /idextract endpoint extracts information from ID cards.

Request Body

The request body should contain the following:

Response

The endpoint returns a data object with the following attributes:

/license Endpoint

The /license endpoint extracts text from a license image.

Request Body

The request body should contain the following:

Response

The endpoint returns a list of tuples containing the extracted text and model confidence.

Extracted Text Confidence
Text 1 Confidence 1
Text 2 Confidence 2
""" return HTMLResponse(content=html_content, status_code=200) @app.post("/idextract", description="This endpoint expects two files one named front and the other back which corresponds to the front and back of the id card, and returns a list of with entity_back and entity_front being the extracted infomation from the image") async def upload_files( front: UploadFile = File(...), back: UploadFile = File(...), face: Optional[UploadFile]= None ): """ Endpoint to receive front and back image uploads and save them to disk. Args: - front: The uploaded front image file. - back: The uploaded back image file. Returns: - dict: A dictionary containing information about the uploaded files. """ try: # Check if either front or back image is missing if not front or not back: raise HTTPException(status_code=400, detail="Both front and back images are required.") # Save the front image to disk front_path = os.path.join("uploads", 'front.jpg') with open(front_path, "wb") as front_file: front_file.write(await front.read()) # Save the back image to disk back_path = os.path.join("uploads", 'back.jpg') with open(back_path, "wb") as back_file: back_file.write(await back.read()) front_id = crop_images_from_detections(front_path) back_id = crop_images_from_detections(back_path) print(f"[*] ---- Text front ----> {front_id}") print(f"[*] ---- Text back ----> {back_id}") front_url = upload_to_s3(front_path) back_url = upload_to_s3(back_path) # front_text = read_text_img(front_path) # back_text = read_text_img(back_path) # ent_front = ner_recog(front_text) # ent_back = ner_recog(back_text) # print(f"[*] ---- Entity front ----> {ent_front}") # print(f"[*] ---- Entity back ----> {ent_back}") if face is not None: # Save the face image to disk face_path = os.path.join("uploads", 'face.jpg') with open(face_path, "wb") as face_file: face_file.write(await face.read()) face_url = upload_to_s3(face_path) serial_number = '' print(f"[*] --- Serial ---> {serial_number}") # embedding = DeepFace.represent(img_path=face_path, model_name='DeepFace') # embedding_vector = embedding[0]['embedding'] # existing_user = lookup_user_metadata(index, embedding_vector, serial_number) # print(f"[*] --- Existing user ---> {existing_user}") # if (len(existing_user["matches"]) <= 0): # print(f"[*] --- No match found --->") # await index.upsert( # vectors=[ # { # "id": str(uuid.uuid4()), # "values" : embedding_vector, # "metadata" : {"name": serial_number} # } # ], # namespace="ns1" # ) # elif(len(existing_user["matches"]) > 0): # if (existing_user["matches"][0]["score"] >= 0.79): # pass # # return JSONResponse(content={"message": "This user and id card already exist"}, status_code=200) # elif(existing_user["matches"][0]["score"]): # return HTTPException(content={"message" : "This card belongs to someone else"}, status_code=404) return JSONResponse(content = {"message": "Upload successful", "data":{'front_url': front_url , 'entity_front': front_id, 'back_url': back_url, 'entity_back': back_id}}, status_code=200) except Exception as e: return HTTPException(status_code=500, detail=f"Internal server error {str(e)}") @app.post("/carplate", description="This endpoint expects a file named license and return a list of turple having the detected number plates and the extracted text") async def carplate(license: UploadFile = File(...)): try: if not license: raise HTTPException(status_code=500, detail=f"Internal server error {str(e)}") # Save the back image to disk car_path = os.path.join("uploads", 'cars.jpg') with open(car_path, "wb") as face_file: face_file.write(await license.read()) car_url = upload_to_s3(car_path) print(f"[*] --- Image URL --> {car_url}") print(" [*] --- This is the license path --> :", car_path) result = detect_licensePlate(car_path) return JSONResponse( content = {"message" : "Upload successful", "data" : result, "car_url": car_url}, status_code = 200 ) except Exception as e: return HTTPException(status_code=400, detail=f"Internal server error {str(e)}") if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=7860)