File size: 3,343 Bytes
c634917
 
 
 
 
 
 
 
 
 
 
b6d125e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c634917
b6d125e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c634917
 
b6d125e
 
 
 
 
 
 
 
 
 
c634917
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# -*- coding: utf-8 -*-
"""api

Automatically generated by Colab.

Original file is located at
    https://colab.research.google.com/drive/1zg-G3yXyLeOMsGYaU19_7DAivaOyAoF3
"""

import cv2
import numpy as np
import asyncio
import base64
import io
from fastanpr import FastANPR
from fastapi import FastAPI
from pydantic import BaseModel

# --- 1. INITIALIZE THE APP AND MODELS ---

# Create the FastAPI app instance
app = FastAPI(title="FastANPR API")

# Load the FastANPR model ONCE on startup.
# This is crucial for performance.
print("Loading FastANPR (YOLOv8 + PaddleOCR) model...")
fast_anpr = FastANPR()
print("Model loaded successfully.")

# --- 2. DEFINE THE REQUEST DATA SHAPE ---

# This Pydantic model defines what our API expects in the request body.
# We'll expect a JSON object with one key: "image"
# The value will be a base64-encoded string of the image.
class ImageRequest(BaseModel):
    image: str # Base64 encoded image string

# --- 3. CREATE THE API ENDPOINT ---

# @app.post("/recognise") defines a POST endpoint at the URL /recognise
# This is what your mobile app will call.
@app.post("/recognise")
async def recognise_plate(request: ImageRequest):
    """
    Receives a base64 encoded image, decodes it, runs ANPR,
    and returns any found license plates.
    """
    try:
        # --- A. DECODE THE IMAGE ---
        
        # Get the base64 string from the request
        base64_image_str = request.image
        
        # Decode the base64 string into raw image bytes
        image_data = base64.b64decode(base64_image_str)
        
        # Convert the raw bytes into a numpy array
        nparr = np.frombuffer(image_data, np.uint8)
        
        # Decode the numpy array into an OpenCV image (BGR format)
        img_bgr = cv2.imdecode(nparr, cv2.IMREAD_COLOR)

        if img_bgr is None:
            return {"error": "Could not decode image."}

        # fastanpr expects images in RGB format
        img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)

        # --- B. RUN ANPR ---
        
        # Run ANPR (it expects a list of images)
        # We await it because fast_anpr.run is an async function
        all_results = await fast_anpr.run([img_rgb])
        
        # Get the results for our single image (it's the first item)
        plates_in_image = all_results[0]
        
        # --- C. FORMAT THE RESPONSE ---
        
        # Create a list to hold plate data
        formatted_plates = []
        
        if plates_in_image:
            for plate in plates_in_image:
                formatted_plates.append({
                    "text": plate.rec_text,
                    "detection_confidence": plate.det_conf,
                    "recognition_confidence": plate.rec_conf,
                    "box": plate.det_box
                })

        # Return the list of found plates
        return {"plates": formatted_plates}

    except Exception as e:
        print(f"An error occurred: {e}")
        return {"error": str(e)}

# --- 4. (Optional) RUN THE SERVER ---
# This part allows you to run the script directly with `python api.py`
# For production, you'd use: uvicorn api:app --host 0.0.0.0 --port 8000
if __name__ == "__main__":
    import uvicorn
    print("Starting Uvicorn server... Go to http://127.0.0.1:8000/docs")
    uvicorn.run(app, host="127.0.0.1", port=8000)