What is ANPR System ๐ข๐
An Automatic Number Plate Recognition (ANPR) system is a technology that uses specialized cameras and software to automatically detect, read, and record vehicle license plates from images or video streams.
It works by capturing an image of the plate, processing it to isolate the plate area, and then applying optical character recognition (OCR) to convert the image of the plate characters into digital text data. This data is then typically used for applications like law enforcement (identifying stolen vehicles or traffic violations), toll collection, parking management, traffic monitoring, and access control to secured areas.
Vehicle License Plates Around the World ๐๐
Vehicle license plates vary widely across the world, reflecting differences in governmental regulations, purposes, and design aesthetics. Broadly, license plates can be categorized into several types based on function: private vehicle plates, commercial plates, diplomatic plates, military plates, and temporary or transit plates. In many countries, special plates are issued for taxis, rental vehicles, police, and public transport. These often differ in background color, alphanumeric format, and prefixes or symbols.
For instance, in India, private vehicles have white backgrounds with black letters, while commercial vehicles use yellow plates with black text. Similarly, in the UK, diplomatic plates have a distinct "D" or embassy code, and in the U.S., military plates often carry emblems of the respective armed forces.
Design-wise, plates vary in shape, size, and font. European Union countries generally use standardized plates with blue EU bands on the left, while North American plates are more diverse, often including state/province names and unique graphical elements. Some countries like Japan include kanji characters and color-coded plates to indicate vehicle class and engine size.
Additionally, with the rise of technology, several regions have started experimenting with digital license plates that are electronically updatable and can integrate tracking or anti-theft features. These global variations make license plate recognition systems especially challenging and fascinating in the field of computer vision.
Project Inspiration ๐
Have you ever wondered if a pocket-sized device could recognize car number plates and send the result to the cloud? With the boom in edge computing and AI APIs like Gemini, itโs now possible to build an ANPR system without a heavy GPU setup. I wanted to combine the power of Google's Gemini AI with the compact DFRobot's ESP32-S3 AI Camera Module to build a portable, low-cost, real-time number plate detection system.
Existing Technologies ๐ง
Before diving in, letโs look at how traditional ANPR systems work:
Our implementation of this project falls in the last category - Edge Camera + Cloud AI, giving a good balance of cost, portability, and performance.
Introduction ๐This project is a smart, cost-effective Automatic Number Plate Recognition (ANPR) system using the DFRobot's ESP32-S3 AI Camera Module and Google Gemini Vision API. It captures vehicle images, processes them using cloud-based AI, and optionally sends the recognized plate data to Firebase along with a timestamp and Base64 image.
Unlike traditional setups involving Raspberry Pi or heavy Linux environments, this uses a microcontroller with camera support and runs almost everything at the edge.
I'm very grateful to DFRobot for providing me their awesome hardware and supporting my Project's Idea with ESP32-S3 AI Camera Module ๐
Now Lets see the implementation of the project in detail.
Hardware ๐ ๏ธIn this project we are going to use following device - ESP32-S3 AI Camera Module
Device comes with following Components
The ESP32-S3 AI Camera is a cutting-edge intelligent camera module built around the high-performance ESP32-S3 chip, designed for efficient video processing, edge AI, and voice interaction. Featuring a wide-angle infrared camera, onboard microphone, and speaker, it is ideally suited for applications such as electronic peepholes, baby monitors, and license plate recognition.
AI assistants
With powerful AI processing capabilities, it integrates seamlessly into IoT ecosystems, supporting edge image recognition and online AI model interaction through Wi-Fi connectivity, making it an essential component for IoT applications, from security surveillance to AI assistants.
Key Features of ESP32-S3 AI Camera Module ๐ท
- Processor: Xtensaยฎ Dual-core 32-bit LX7 Microprocessor, 240 MHz
- Built-in OV3660 3MP Camera.
- 16 MB Flash, 8MB PSRAM for smooth image capture
- On board Mic and Kit comes with Speaker
- USB: USB 2.0 OTG Full-Speed Interface
- SD Card Slot
- ALS: LTR-308 ambient light sensor
- 4 LED's for IR: Infrared illumination
Camera Specifications
The wide-angle infrared camera on the ESP32-S3 AI Camera, combined with infrared illumination and a light sensor, ensures excellent image clarity even in low light or complete darkness. Whether day or night, the ESP32-S3 AI Camera guarantees the stability and clarity of surveillance footage, providing reliable support for security and monitoring systems.
- Sensor Model: OV3660
- Pixel: 3 Megapixels
- Sensitivity: Visible light, 940nm infrared
- Field of View: 160ยฐ
- Focal Length: 0.95
- Aperture: 2.0
- Distortion: <8%
This is all about this awesome hardware. You can know more about it on its Wiki Page. They have explained thorough details, Features, Specifications, Pinouts, Getting started Guides and so on.
Getting Started with DFRobot ESP32-S3 AI CameraCheck out our blog article on Hackster for more information on getting started with ESP32-S3 AI Camera Module.
You can also check out following video, we have explained detailed information about this ESP32 board
How The Project Works ๐ ๏ธNow lets see about how this project will work. Following are important steps -
- Capture: ESP32-S3 captures an image using the onboard OV3660 sensor.
- Encode: Image is converted to Base64 format.
- AI Detection: A request is sent to Gemini Vision API to detect and extract the number plate.
- Validation: Logic filters and validates output to ensure plate quality.
- Storage (Optional): The result is pushed to Firebase Realtime DB with date/time and image.
- Repeat: Runs periodically every 20 seconds.
In this project, the ESP32-S3 AI camera captures an image of a vehicle and converts it into a Base64-encoded string, which is then embedded into a JSON payload along with a natural language prompt requesting number plate extraction. This payload is sent via an HTTP POST request to Google's Gemini API (generateContent endpoint). The Gemini API processes the image and returns a JSON-formatted response, where the extracted number plate (or a relevant message) is found within a nested text field. The ESP32 then parses this JSON response using ArduinoJson, extracts the plain-text number plate, andโif validโlogs it or sends it to Firebase for storage and further monitoring.
Software ๐ปIn this project we require following software components -
- Arduino IDE (with ESP32 Board package)
- Google Gemini Vision API for image understanding
- Firebase Realtime Database (optional)
Libraries used:
WiFi.h
โ Wi-Fi connectionHTTPClient.h
โ REST API communicationArduinoJson.h
โ JSON parsingesp_camera.h
โ Camera interfacingtime.h
โ Date and time sync via NTP
We have explained all the things in Demo Video
Get a Gemini API key ๐
==> Why We Need Gemini API ?
The Gemini API serves as the intelligent core of the Automatic Number Plate Recognition (ANPR) system. While the ESP32-S3 AI camera can capture high-quality images, it lacks the computational power and deep learning models required to accurately perform Optical Character Recognition (OCR) and interpret complex image data. Gemini fills this gap by using its powerful multimodal capabilities to analyze the image, understand the content, and extract the number plate text. Unlike traditional OCR libraries that may struggle with different plate fonts, lighting conditions, or orientations, Gemini leverages advanced vision-language models to perform this task robustly and flexiblyโall from a simple API request. It transforms a raw image into actionable insight (a number plate) with just one HTTP call, making it ideal for low-power edge devices.
To use the Gemini API, you need an API key. You can create a key with a few clicks in Google AI Studio
Get API key - We have explained all procedure in Demo Video
Firebase Realtime Database ๐
==> Why We Need Firebase Realtime Database ?
Firebase Realtime Database acts as a secure, cloud-based storage system to log and monitor detected number plates along with associated timestamps and images. Since the ESP32 is a transient device with limited onboard memory and no persistent storage, Firebase ensures that valuable detection data is preserved for future reference, analytics, or alerting systems. It allows multiple stakeholders such as administrators, security personnel, or appsโto access the data in real-time from anywhere. Additionally, Firebase integrates seamlessly with other Google services and offers scalability, making it an ideal backend for deploying this project in smart parking, access control, or surveillance scenarios.
You can create a real time Firebase database on Firebase Console. We have explained all procedure in Demo Video
- Once you get the Gemini API Key and URL of Firebase database(Realtime), then enter them into the code.
- You also need to enter your WiFi credentials.
For Firebase Database implementation - We have kept this as optional.
// Enable Firebase integration
#define ENABLE_FIREBASE true // Set to false to disable Firebase
- If you do not want to use Database you can set above definition as false.
- If you use Google Firebase Database - Then do not forget to enter correct URL
// Firebase URL (Set if using Firebase)
const char* FIREBASE_URL = "https://your-project.firebaseio.com/data.json";
- In above URL don't forget to add
data.json
- In the Firebase Realtime Database, the .json at the end of the URL is required only when accessing the database over the REST API, which is exactly what the ESP32 is doing using HTTPClient. Here's what it means in your line:
// Firebase URL (Set if using Firebase)
const char* FIREBASE_URL = "https://your-project.firebaseio.com/data.json";
data
refers to the node or path in your database where you want to store the data. You can enter any name. for example -numberplate.json
orlicenceplate.json
etc.json
is required by the Firebase REST API to specify that you're sending or receiving JSON-formatted data.- So, this URL tells Firebase:
โAccess thedata
node in the root of the database and treat the request body as JSON.โ
For NTP timing settings
// NTP Time
const long gmtOffset_sec = 0;
- Above code sets the time zone offset in seconds from GMT/UTC. A value of
0
means you're using GMT/UTC time (no offset). - So for India, we followed Indian Standard Time (IST), which is UTC +5 hours 30 minutes.
5 hours = 5 ร 3600 = 18000 seconds
30 minutes = 30 ร 60 = 1800 seconds
Total = 18000 + 1800 = 19800 seconds
- So to set it for India, convert 5 hours and 30 minutes into seconds:
// NTP Time
const char* ntpServer = "pool.ntp.org";
// for IST (UTC +5:30) for India. You can set as per your location
const long gmtOffset_sec = 19800;
const int daylightOffset_sec = 0;
This ensures your ESP32 will sync and display the correct local time for India when using NTP servers.
Code Explanation </>- Project code runs on the DFRobot ESP32-S3 AI Camera module and performs automatic license plate recognition (ANPR) using Googleโs Gemini API. It first connects to Wi-Fi and synchronizes the real-time clock via NTP. The camera is initialized with the correct GPIO pins and captures images periodically.
- Each image is base64-encoded and sent as part of an HTTP POST request to the Gemini API with a prompt asking it to detect the vehicle's number plate.
- The response is parsed from JSON, and if a valid plate number is extracted, the code logs the detection time and plate number to the serial monitor. Optionally, if Firebase integration is enabled, the result (plate number, timestamp, and image) is also sent to a Firebase Realtime Database. This creates a compact but intelligent edge-AI pipeline for real-time vehicle monitoring and logging.
- When the ESP32 sends an image and prompt to the Gemini API using the generateContent endpoint (e.g., for the model gemini-2.0-flash), the response returned is in JSON format.
- However, the actual number plate text (or any AI-generated response) you're interested in is embedded inside that JSON under specific fields. Here's a sample response format:
{
"candidates": [
{
"content": {
"parts": [
{
"text": "KL10AH6791"
}
]
}
}
]
}
So on the ESP32, we:
- Get the response as a string from http.getString();
- Parse it using ArduinoJson
- Extract the useful text value using:
const char* aiText = doc["candidates"][0]["content"]["parts"][0]["text"];
Therefore our final
- The response is JSON
- The number plate is a plain text string nested inside the JSON
You can see in following picture, Vehicle Number plate/License plate correctly detected by the system
In firebase Realtime Database, we get entry of License plate number with Timestamp
Watch the Demo -
Getting Started with ESP32-S3 AI Camera
Projects Demo -
Potential Applications of the Project โณ
There are several places/domains where this project can be used
- Smart Parking Systems ๐ ฟ๏ธ
- Law Enforcement & Traffic Monitoring ๐
- Entry/Exit Gate Automation ๐ง
- Residential Smart Surveillance ๐
- Fleet Management Systems ๐ป
- AI-powered Edge Image Testing Rigs ๐งช
Future Improvements ๐ฎ
In future I want to upgrade this project with next application of Garage Door Opener. But this board has no Breakout pins to interface with. Therefore we have to use another ESP32 Board with MQTT interface.
Project DocumentationI will share all the documents, codes, schematics, etc. on GitHub.
Suggestions about this Tutorial/Project design, Circuits, code modifications, Optimization, Errors/Bugs findings and queries are most welcomed. Feel free to raise you queries, suggest your opinions and point out any errors or bugs.Credits
Thank you Hackster, DFRobot, and all other peoples, websites and entities who helped me (directly/indirectly) for creating this article.
Comments