Quick Start
Get results in minutes. Pick your language, then a scenario — read a plate from an
image, process a live RTSP stream, or classify a vehicle's
make & model. Each scenario is one complete, copy-paste program that runs
locally against nnAnpr.dll.
1 · Choose your language
Build with C / C++
- Prerequisites: Windows x64, Visual C++ 2015–2022 runtime, Visual Studio. Keep
bin\intact (nnAnpr.dll+data\). - Add to project: add
Include\to the include path,#include "nnAnpr.h"(and"nnVmm.h"for vehicles), linkInclude\nnAnpr.lib. - Platform: build x64, and run from the SDK
bin\folder.
2 · Choose a scenario
Plate · from image
Load an image, find every plate, read each one.
#include "nnAnpr.h"
#include <iostream>
#pragma comment(lib, "nnAnpr.lib")
int wmain()
{
if (NNANPR_Init() != NNANPR_RESULT_SUCCESS) return -1; // init once
NNANPR_Image_ptr image = nullptr; // load an image
NNANPR_CreateImage(&image);
if (NNANPR_LoadImage(L"testdata\\EU2.jpg", image) != NNANPR_RESULT_SUCCESS) return -2;
NNANPR_PlateFinder_ptr finder = nullptr; // create engines
NNANPR_PlateRecognizer_ptr recognizer = nullptr;
NNANPR_CreatePlateFinder (nngaEurope, nndIntelCPU, &finder);
NNANPR_CreatePlateRecognizer(nngaEurope, nndIntelCPU, &recognizer);
NNANPR_Object plates[30]; size_t count = 30; // find plates
if (NNANPR_FindPlates(finder, image, plates, &count) == NNANPR_RESULT_SUCCESS)
for (size_t i = 0; i < count; ++i) { // read each plate
NNANPR_RecognizerResult rr{};
if (NNANPR_RecognizePlate(recognizer, image, plates[i], &rr) == NNANPR_RESULT_SUCCESS)
std::wcout << rr.Characters << L" (" << rr.Country << L")\n";
}
NNANPR_FreePlateRecognizer(recognizer); // clean up (reverse order)
NNANPR_FreePlateFinder(finder);
NNANPR_FreeImage(image);
return 0;
}S AB 1234 (Germany).RTSP · live video
Open an rtsp:// stream (or camera) and read plates continuously. Detection and recognition run on SDK worker threads; the accumulator merges repeated reads of the same plate.
#include "nnAnpr.h"
#include <iostream>
struct App {
NNANPR_PlateFinder_ptr finder = nullptr;
NNANPR_PlateRecognizer_ptr recognizer = nullptr;
NNANPR_RecognitionAccumulator_ptr accumulator = nullptr;
NNANPR_ImageWindow_ptr window = nullptr;
NNANPR_ImageCapture_ptr capture = nullptr;
};
void OnRecognition(const NNANPR_RecognizerResult* rr, const NNANPR_Image_ptr image, void* ctx) {
if (rr->ErrorCode == NNANPR_RESULT_SUCCESS)
std::wcout << rr->Characters << L" (" << rr->Country << L")\n";
}
void OnPlateFound(const NNANPR_Object* plates, size_t count, const NNANPR_Image_ptr image, void* ctx) {
App* a = static_cast<App*>(ctx);
if (count == 0) return; // guard on the COUNT, not the pointer
NNANPR_RecognizePlateAsyncWithAccumulator(a->recognizer, a->accumulator, image, plates[0], OnRecognition, ctx);
}
void OnFrame(const NNANPR_Image_ptr image, void* ctx) {
App* a = static_cast<App*>(ctx);
NNANPR_DrawImage(a->window, image);
NNANPR_FindPlatesAsync(a->finder, image, OnPlateFound, ctx);
}
int wmain() {
if (NNANPR_Init() != NNANPR_RESULT_SUCCESS) return -1;
App app;
NNANPR_CreatePlateFinder (nngaEurope, nndIntelCPU, &app.finder);
NNANPR_CreatePlateRecognizer(nngaEurope, nndIntelCPU, &app.recognizer);
NNANPR_CreateRecognitionAccumulator(&app.accumulator);
NNANPR_SetupRecognitionAccumulator(app.accumulator, 2000, 5, 20, 3);
NNANPR_CreateImageWindow(nullptr, &app.window);
if (NNANPR_CreateVideoCapture(&app.capture, L"rtsp://user:pass@192.168.1.10/stream") != NNANPR_RESULT_SUCCESS)
return -2;
NNANPR_StartCaptureFrameAsync(app.capture, OnFrame, &app); // callbacks run on SDK threads
NNANPR_WaitImageWindow(app.window, 0, true); // block until the window is closed
NNANPR_StopCaptureFrameAsync(app.capture); // stop FIRST, then free
NNANPR_FreeVideoCapture(app.capture);
NNANPR_FreeRecognitionAccumulator(app.accumulator);
NNANPR_FreePlateRecognizer(app.recognizer);
NNANPR_FreePlateFinder(app.finder);
NNANPR_FreeImageWindow(app.window);
return 0;
}NNANPR_StopCaptureFrameAsync before freeing any engine, and guard the callback on the result count, not the array pointer.Make & model
Detect vehicles and classify make & model. The VMM API lives in nnVmm.h and mirrors the plate flow (no region parameter).
#include "nnVmm.h" // includes nnAnpr.h
#include <iostream>
int wmain()
{
if (NNANPR_Init() != NNANPR_RESULT_SUCCESS) return -1;
NNANPR_Image_ptr image = nullptr;
NNANPR_CreateImage(&image);
if (NNANPR_LoadImage(L"testdata\\Traker1.jpg", image) != NNANPR_RESULT_SUCCESS) return -2;
NNANPR_VehicleFinder_ptr vf = nullptr; // create vehicle engines
NNANPR_VehicleModelRecognizer_ptr vmr = nullptr;
NNANPR_CreateVehicleFinder(nndIntelCPU, &vf);
NNANPR_SetupVehicleFinder(vf, 0.5);
NNANPR_CreateVehicleModelRecognizer(nndIntelCPU, &vmr);
NNANPR_Object vehicles[30]; size_t count = 30; // find vehicles
if (NNANPR_FindVehicles(vf, image, vehicles, &count) == NNANPR_RESULT_SUCCESS)
for (size_t i = 0; i < count; ++i) { // classify each
NNANPR_ModelRecognizerResult mr{};
if (NNANPR_RecognizeVehicleModel(vmr, image, vehicles[i], &mr) == NNANPR_RESULT_SUCCESS)
std::wcout << mr.ModelName << L" " << mr.Confidence << L"\n";
}
NNANPR_FreeVehicleModelRecognizer(vmr); // VMM-specific free functions
NNANPR_FreeVehicleFinder(vf);
NNANPR_FreeImage(image);
return 0;
}NNANPR_FreeVehicleModelRecognizer / NNANPR_FreeVehicleFinder — not the plate free functions. Pass 0 instead of a vehicle object to classify a whole image.Examples\c++\)PlateRecognize\— plate from image (console)VideoAsync\— live ANPR on video / RTSP (async + accumulator)VideoSample\— live ANPR (synchronous) with open-image and camera listVehicleModelRecognize\— vehicle make & model (console)VideoAsyncVMM\— live make & model on videoMulticameras\— several streams in parallel
Build with C#
- Prerequisites: Windows x64, Visual C++ 2015–2022 runtime. Keep the SDK
bin\(withdata\) reachable — run from it or add it toPATH. - Add the binding: add
Include\nnAnpr.csto your project (andnnVmm.csfor vehicles). - Platform: set Platform target to x64 (not AnyCPU).
2 · Choose a scenario
Plate · from image
Load an image, find every plate, read each one.
using System;
class Program
{
static int Main()
{
if (nnAnpr.NNANPR_Init() != nnAnpr.NNANPR_RESULT_SUCCESS) return -1; // init once
IntPtr image = IntPtr.Zero; // load an image (handles are IntPtr)
nnAnpr.NNANPR_CreateImage(ref image);
if (nnAnpr.NNANPR_LoadImage(@"testdata\EU2.jpg", image) != nnAnpr.NNANPR_RESULT_SUCCESS) return -2;
IntPtr finder = IntPtr.Zero, recognizer = IntPtr.Zero; // create engines
nnAnpr.NNANPR_CreatePlateFinder(NNANPR_GeographicalArea.nngaEurope, NNANPR_Device.nndIntelCPU, ref finder);
nnAnpr.NNANPR_CreatePlateRecognizer(NNANPR_GeographicalArea.nngaEurope, NNANPR_Device.nndIntelCPU, ref recognizer);
ulong[] plates = new ulong[30]; // find plates
ulong count = (ulong)plates.Length;
if (nnAnpr.NNANPR_FindPlates(finder, image, ref plates[0], ref count) == nnAnpr.NNANPR_RESULT_SUCCESS)
for (ulong i = 0; i < count; i++) { // read each plate
var rr = new NNANPR_RecognizerResult();
if (nnAnpr.NNANPR_RecognizePlate(recognizer, image, plates[i], ref rr) == nnAnpr.NNANPR_RESULT_SUCCESS)
Console.WriteLine($"{Text(rr.Characters)} ({Text(rr.Country)})");
}
nnAnpr.NNANPR_FreePlateRecognizer(recognizer); // clean up
nnAnpr.NNANPR_FreePlateFinder(finder);
nnAnpr.NNANPR_FreeImage(image);
return 0;
}
static string Text(char[] a) => new string(a).TrimEnd('\0'); // fixed 50-char buffer
}S AB 1234 (Germany).RTSP · live video
Open an rtsp:// stream and read plates continuously. The callback delegates are stored in fields so the garbage collector can't collect them while the engine still calls them.
using System;
class LiveAnpr
{
// keep delegates alive for the whole run (GC-rooted)
readonly NNANPROnFrameCallback _onFrame;
readonly NNANPROnPlateFoundCallback _onPlates;
readonly NNANPROnRecognitionCallback _onRead;
IntPtr _finder, _recognizer, _accum, _window, _capture;
LiveAnpr() { _onFrame = OnFrame; _onPlates = OnPlatesFound; _onRead = OnPlateRead; }
void OnFrame(IntPtr image, IntPtr ctx) {
nnAnpr.NNANPR_DrawImage(_window, image);
nnAnpr.NNANPR_FindPlatesAsync(_finder, image, _onPlates, IntPtr.Zero);
}
void OnPlatesFound(ulong[] plates, ulong count, IntPtr image, IntPtr ctx) {
if (count > 0)
nnAnpr.NNANPR_RecognizePlateAsyncWithAccumulator(_recognizer, _accum, image, plates[0], _onRead, IntPtr.Zero);
}
void OnPlateRead(ref NNANPR_RecognizerResult rr, IntPtr image, IntPtr ctx) {
if (rr.ErrorCode == nnAnpr.NNANPR_RESULT_SUCCESS)
Console.WriteLine(new string(rr.Characters).TrimEnd('\0'));
}
static void Main() {
if (nnAnpr.NNANPR_Init() != nnAnpr.NNANPR_RESULT_SUCCESS) return;
var app = new LiveAnpr();
nnAnpr.NNANPR_CreatePlateFinder(NNANPR_GeographicalArea.nngaEurope, NNANPR_Device.nndIntelCPU, ref app._finder);
nnAnpr.NNANPR_CreatePlateRecognizer(NNANPR_GeographicalArea.nngaEurope, NNANPR_Device.nndIntelCPU, ref app._recognizer);
nnAnpr.NNANPR_CreateRecognitionAccumulator(ref app._accum);
nnAnpr.NNANPR_SetupRecognitionAccumulator(app._accum, 2000, 5, 20, 3);
nnAnpr.NNANPR_CreateImageWindow(IntPtr.Zero, ref app._window);
if (nnAnpr.NNANPR_CreateVideoCapture(ref app._capture, "rtsp://user:pass@192.168.1.10/stream") != nnAnpr.NNANPR_RESULT_SUCCESS) return;
nnAnpr.NNANPR_StartCaptureFrameAsync(app._capture, app._onFrame, IntPtr.Zero);
nnAnpr.NNANPR_WaitImageWindow(app._window, 0, true); // block until closed
nnAnpr.NNANPR_StopCaptureFrameAsync(app._capture); // stop FIRST, then free
nnAnpr.NNANPR_FreeVideoCapture(app._capture);
nnAnpr.NNANPR_FreeRecognitionAccumulator(app._accum);
nnAnpr.NNANPR_FreePlateRecognizer(app._recognizer);
nnAnpr.NNANPR_FreePlateFinder(app._finder);
nnAnpr.NNANPR_FreeImageWindow(app._window);
}
}Make & model
Detect vehicles and classify make & model with the nnVmm binding.
using System;
class Vmm
{
static int Main()
{
if (nnAnpr.NNANPR_Init() != nnAnpr.NNANPR_RESULT_SUCCESS) return -1;
IntPtr image = IntPtr.Zero;
nnAnpr.NNANPR_CreateImage(ref image);
if (nnAnpr.NNANPR_LoadImage(@"testdata\Traker1.jpg", image) != nnAnpr.NNANPR_RESULT_SUCCESS) return -2;
IntPtr vf = IntPtr.Zero, vmr = IntPtr.Zero;
nnVmm.NNANPR_CreateVehicleFinder(NNANPR_Device.nndIntelCPU, ref vf);
nnVmm.NNANPR_SetupVehicleFinder(vf, 0.5);
nnVmm.NNANPR_CreateVehicleModelRecognizer(NNANPR_Device.nndIntelCPU, ref vmr);
ulong[] vehicles = new ulong[30];
ulong count = (ulong)vehicles.Length;
if (nnVmm.NNANPR_FindVehicles(vf, image, ref vehicles[0], ref count) == nnAnpr.NNANPR_RESULT_SUCCESS)
for (ulong i = 0; i < count; i++) {
var mr = new NNANPR_ModelRecognizerResult();
if (nnVmm.NNANPR_RecognizeVehicleModel(vmr, image, vehicles[i], ref mr) == nnAnpr.NNANPR_RESULT_SUCCESS)
Console.WriteLine($"{new string(mr.ModelName).TrimEnd('\0')} {mr.Confidence:0.00}");
}
nnVmm.NNANPR_FreeVehicleModelRecognizer(vmr);
nnVmm.NNANPR_FreeVehicleFinder(vf);
nnAnpr.NNANPR_FreeImage(image);
return 0;
}
}Confidence (correctly spelled in the C# binding). Pass 0 instead of a vehicle to classify a whole image.Examples\c#\)VideoSampleCS\— live ANPR (synchronous) with an Open-image buttonVideoAsyncCS\— live ANPR on video / RTSP (async + accumulator)VehicleModelRecognizerCS\— vehicle make & model (console)
Build with Delphi
- Prerequisites: RAD Studio / Delphi, Windows x64, Visual C++ 2015–2022 runtime. Keep the SDK
bin\(withdata\) reachable. - Add the binding: add
Include\nnAnpr.pas(andnnVmm.pas) to your project or search path; list them inuses. - Platform: keep the target on Win64 (the binding is Win64-only).
2 · Choose a scenario
Plate · from image
Load an image, find every plate, read each one.
program QuickStart;
{$APPTYPE CONSOLE}
uses System.SysUtils, nnAnpr;
var
image : NNANPR_Image_ptr;
finder : NNANPR_PlateFinder_ptr;
recognizer : NNANPR_PlateRecognizer_ptr;
objs : PNNANPR_Object;
count, i : UInt64;
rr : NNANPR_RecognizerResult;
begin
if NNANPR_Init <> NNANPR_RESULT_SUCCESS then Halt(1); // init once
NNANPR_CreateImage(image); // load an image
if NNANPR_LoadImage('testdata\EU2.jpg', image) <> NNANPR_RESULT_SUCCESS then Halt(2);
NNANPR_CreatePlateFinder(nngaEurope, nndIntelCPU, finder); // create engines
NNANPR_CreatePlateRecognizer(nngaEurope, nndIntelCPU, recognizer);
count := 30; // find plates
if NNANPR_FindPlates(finder, image, objs, count) = NNANPR_RESULT_SUCCESS then
for i := 0 to count - 1 do // read each plate
if NNANPR_RecognizePlate(recognizer, image, objs[i], rr) = NNANPR_RESULT_SUCCESS then
Writeln(string(PChar(@rr.Characters[1])), ' (', string(PChar(@rr.Country[1])), ')');
NNANPR_FreePlateRecognizer(recognizer); // clean up
NNANPR_FreePlateFinder(finder);
NNANPR_FreeImage(image);
end.S AB 1234 (Germany).RTSP · live video
Open an rtsp:// stream and read plates continuously using global cdecl callbacks.
program LiveAnpr;
{$APPTYPE CONSOLE}
uses System.SysUtils, nnAnpr;
var
Finder : NNANPR_PlateFinder_ptr;
Recognizer : NNANPR_PlateRecognizer_ptr;
Accum : NNANPR_RecognitionAccumulator_ptr;
Window : NNANPR_ImageWindow_ptr;
Capture : NNANPR_ImageCapture_ptr;
procedure OnRecognition(rr: PNNANPR_RecognizerResult; image: NNANPR_Image_ptr; ctx: Pointer); cdecl;
begin
if rr^.ErrorCode = NNANPR_RESULT_SUCCESS then
Writeln(string(PChar(@rr^.Characters[1])), ' (', string(PChar(@rr^.Country[1])), ')');
end;
procedure OnPlateFound(plates: PNNANPR_Object; count: UInt64; image: NNANPR_Image_ptr; ctx: Pointer); cdecl;
begin
if count = 0 then Exit; // guard on the count
NNANPR_RecognizePlateAsyncWithAccumulator(Recognizer, Accum, image, plates[0], OnRecognition, nil);
end;
procedure OnFrame(image: NNANPR_Image_ptr; ctx: Pointer); cdecl;
begin
NNANPR_DrawImage(Window, image);
NNANPR_FindPlatesAsync(Finder, image, OnPlateFound, nil);
end;
begin
if NNANPR_Init <> NNANPR_RESULT_SUCCESS then Halt(1);
NNANPR_CreatePlateFinder(nngaEurope, nndIntelCPU, Finder);
NNANPR_CreatePlateRecognizer(nngaEurope, nndIntelCPU, Recognizer);
NNANPR_CreateRecognitionAccumulator(Accum);
NNANPR_SetupRecognitionAccumulator(Accum, 2000, 5, 20, 3);
NNANPR_CreateImageWindow(0, Window);
if NNANPR_CreateVideoCapture(Capture, 'rtsp://user:pass@192.168.1.10/stream') <> NNANPR_RESULT_SUCCESS then Halt(2);
NNANPR_StartCaptureFrameAsync(Capture, OnFrame, nil); // callbacks run on SDK threads
NNANPR_WaitImageWindow(Window, 0, True); // block until the window is closed
NNANPR_StopCaptureFrameAsync(Capture); // stop FIRST, then free
NNANPR_FreeVideoCapture(Capture);
NNANPR_FreeRecognitionAccumulator(Accum);
NNANPR_FreePlateRecognizer(Recognizer);
NNANPR_FreePlateFinder(Finder);
NNANPR_FreeImageWindow(Window);
end.TThread.Queue/Synchronize or PostMessage (see the shipped VideoAsync sample).Make & model
Detect vehicles and classify make & model with the nnVmm unit.
program VehicleModel;
{$APPTYPE CONSOLE}
uses System.SysUtils, nnAnpr, nnVmm;
var
image : NNANPR_Image_ptr;
vf : NNANPR_VehicleFinder_ptr;
vmr : NNANPR_VehicleModelRecognizer_ptr;
vehicles : PNNANPR_Object;
count, i : UInt64;
mr : NNANPR_ModelRecognizerResult;
begin
if NNANPR_Init <> NNANPR_RESULT_SUCCESS then Halt(1);
NNANPR_CreateImage(image);
if NNANPR_LoadImage('testdata\Traker1.jpg', image) <> NNANPR_RESULT_SUCCESS then Halt(2);
NNANPR_CreateVehicleFinder(nndIntelCPU, vf);
NNANPR_SetupVehicleFinder(vf, 0.5);
NNANPR_CreateVehicleModelRecognizer(nndIntelCPU, vmr);
count := 30;
if NNANPR_FindVehicles(vf, image, vehicles, count) = NNANPR_RESULT_SUCCESS then
for i := 0 to count - 1 do
if NNANPR_RecognizeVehicleModel(vmr, image, vehicles[i], mr) = NNANPR_RESULT_SUCCESS then
Writeln(string(PChar(@mr.ModelName[1])), ' ', FormatFloat('0.00', mr.Confinedce));
NNANPR_FreeVehicleModelRecognizer(vmr);
NNANPR_FreeVehicleFinder(vf);
NNANPR_FreeImage(image);
end.Confinedce in nnVmm.pas. Free with the VMM free functions; pass 0 to classify a whole image.Examples\Delphi 12\)VideoSample\— live ANPR (synchronous) with open-imageVideoAsync\— live ANPR on video / RTSP (async + accumulator)VehicleModelRecognizer\— vehicle make & model
Next steps
- Switch region — replace
nngaEuropewithnngaMiddleEast,nngaAfrica,nngaAsia_Australasia, ornngaUSA_SouthAmerica. - Open an industrial camera (GigE/USB3) instead of a file/URL with
NNANPR_GetSpecialVideoCaptureList+NNANPR_CreateSpecialVideoCapture. - Tune detection thresholds, restrict a detection zone, raise the async queue size, or load a country syntax template.
- See the full Developer Guide for the API reference, error codes, deployment and troubleshooting.
NN ANPR & VMM SDK — Quick Start · Windows x64 · C/C++ · C# · Delphi.
Samples are built against the shipped headers/bindings (current Recognize API);
run all demos from the SDK bin\ folder.
