SimpleLPR is a professional-grade license plate recognition (LPR/ANPR) library that provides automatic detection and reading of vehicle license plates in images and video streams. Developed over 10+ years and deployed in thousands of production systems worldwide, SimpleLPR delivers enterprise-level reliability with a simple, developer-friendly API. **Proven Performance** Achieves 85-95% recognition accuracy under typical conditions (plate text height ≥20 pixels, reasonable image quality). The specialized OCR engine is trained specifically for license plate fonts and formats, handling challenging real-world scenarios including varying lighting, camera angles up to ±30°, and vehicle motion. **Comprehensive Input Support** • Static images: JPEG, PNG, TIFF, BMP from files or memory buffers • Video files: AVI, MP4, MKV and other common formats • Live streams: RTSP, HTTP, and other network protocols • Configurable resolution limits for performance optimization **Advanced Features** • Multi-threaded processor pools enable concurrent analysis of multiple streams • Intelligent plate tracking correlates detections across video frames, reducing false positives • Plate region detection provides exact coordinates and confidence scores • Character-level analysis with individual confidence metrics • Contrast sensitivity adjustment for shadow and glare compensation • Automatic perspective correction for angled plate views • Support for approximately 90 countries with region-specific templates **Developer-Focused Design** SimpleLPR offers native APIs for C++, .NET (C#, VB.NET, F#), and Python, each following platform conventions. The library handles all complexity internally - developers simply provide an image and receive structured results containing the plate text, country, confidence scores, and location coordinates. **Video Processing Capabilities** The video API includes frame extraction, automatic buffering, stream reconnection for network sources, and synchronized result delivery. The plate tracker maintains temporal consistency across frames, eliminating transient misreads common in frame-by-frame processing. **System Requirements** • Windows 10/11 (x64) or Linux Ubuntu 20.04+ (x64) • .NET Standard 2.0 or higher for .NET integration • Python 3.8, 3.9, 3.10, 3.11, 3.12, 3.13, or 3.14 for Python integration • Optional: CUDA-capable GPU for performance boost (SDK version) **Licensing** 60-day evaluation included. Production license is one-time purchase with unlimited, royalty-free redistribution rights. Includes one year of technical support and updates. **Resources** • Project Site: https://www.warelogic.com • Documentation: https://www.warelogic.com/doc/SimpleLPR3.pdf • .NET API Reference: https://www.warelogic.com/doc/SimpleLPR.chm • Python API Reference: https://www.warelogic.com/doc/simplelpr_python_api_reference.htm • Python Quick Start: https://www.warelogic.com/doc/simplelpr_python_quickstart_guide.htm • Sample Code: https://github.com/xgirones/SimpleLPR-samples • Support: support@warelogic.com See the project README for complete documentation and code examples.
$ dotnet add package SimpleLPRSimpleLPR is a software component for vehicle license plate recognition. It has a very simple programming interface that allows applications to supply a path to an image or a buffer in memory and returns the detected license plate text and its location in the input image. It can be used from C++, .NET-enabled programming languages, or Python.
Typical detection rates range between 85% and 95%, provided the license plates are in good condition, free of obstructions, and the text height is at least 20 pixels.
For further information, please download the user's guide and the class reference for .NET.
You can submit your questions/issues/bug reports/feedback to support@warelogic.com
Integration is simple and straightforward, as demonstrated in the following example:
using System;
using System.Collections.Generic;
using SimpleLPR3;
namespace TestSimpleLPR
{
class Program
{
static void Main(string[] args)
{
// Create an instance of the SimpleLPR engine.
EngineSetupParms setupP;
setupP.cudaDeviceId = -1; // Select CPU
setupP.enableImageProcessingWithGPU = false;
setupP.enableClassificationWithGPU = false;
setupP.maxConcurrentImageProcessingOps = 0; // Use the default value.
ISimpleLPR lpr = SimpleLPR.Setup(setupP);
// Output the version number
VersionNumber ver = lpr.versionNumber;
Console.WriteLine("SimpleLPR version {0}.{1}.{2}.{3}", ver.A, ver.B, ver.C, ver.D);
try
{
bool bOk = (args.Length == 2 || args.Length == 3);
if (bOk)
{
string sFilePath = args[1];
// Configure country weights based on the selected country
uint countryId = uint.Parse(args[0]);
if (countryId >= lpr.numSupportedCountries)
throw new Exception("Invalid country id");
for (uint ui = 0; ui < lpr.numSupportedCountries; ++ui)
lpr.set_countryWeight(ui, 0.0f);
lpr.set_countryWeight(countryId, 1.0f);
lpr.realizeCountryWeights();
// Set the product key (if supplied)
if (args.Length == 3)
lpr.set_productKey(args[2]);
// Create a processor object
IProcessor proc = lpr.createProcessor();
proc.plateRegionDetectionEnabled = true;
proc.cropToPlateRegionEnabled = true;
// Use the analyze version that takes the path to a file
List<Candidate> cds = proc.analyze(sFilePath);
// Output the results
Console.WriteLine("***********");
Console.WriteLine("Results of IProcessor.analyze(file)");
if (cds.Count == 0)
{
Console.WriteLine("No license plate found");
}
else
{
Console.WriteLine("{0} license plate candidates found:", cds.Count);
// Iterate over all candidates
foreach (Candidate cd in cds)
{
Console.WriteLine("***********");
Console.WriteLine("Light background: {0}, left: {1}, top: {2}, width: {3}, height: {4}", cd.brightBackground, cd.bbox.Left, cd.bbox.Top, cd.bbox.Width, cd.bbox.Height);
Console.WriteLine("Plate confidence: {0}. Plate vertices: {1}", cd.plateDetectionConfidence, string.Join(", ", cd.plateRegionVertices));
Console.WriteLine("Matches:");
// Iterate over all country matches
foreach (CountryMatch match in cd.matches)
{
Console.WriteLine("-----------");
Console.WriteLine("Text: {0}, country: {1}, ISO: {2}, confidence: {3}", match.text, match.country, match.countryISO, match.confidence);
Console.WriteLine("Elements:");
foreach (Element e in match.elements)
{
Console.WriteLine(" Glyph: {0}, confidence: {1}, left: {2}, top: {3}, width: {4}, height: {5}",
e.glyph, e.confidence, e.bbox.Left, e.bbox.Top, e.bbox.Width, e.bbox.Height);
}
}
}
}
}
else
{
Console.WriteLine("\nUsage: {0} <country id> <source file> [product key]", Environment.GetCommandLineArgs()[0]);
Console.WriteLine(" Parameters:");
Console.WriteLine(" country id: Country identifier. The allowed values are");
for (uint ui = 0; ui < lpr.numSupportedCountries; ++ui)
Console.WriteLine("\t\t\t{0}\t: {1}", ui, lpr.get_countryCode(ui));
Console.WriteLine(" source file: file containing the image to be processed");
Console.WriteLine(" product key: product key file. this value is optional, if not provided SimpleLPR will run in evaluation mode");
}
}
catch (System.Exception ex)
{
Console.WriteLine("Exception occurred!: {0}", ex.Message);
}
}
}
}