Commercial SDK

The OpenALPR commercial SDK exposes APIs for identifying license plates in individual images, as well as videos or feeds of sequential images. The SDK can run on your hardware and integrate directly with your application.

The APIs are available as C/C++ library with additional bindings in C#, Java, and Python.

Installation

Windows

The Windows SDK package can be downloaded here: https://deb.openalpr.com/windows-sdk/openalpr64-sdk-latest.zip

Linux

The Linux SDK is available in OpenALPR’s commercial APT repository. The libopenalpr-dev package will install the necessary headers and library packages into your system. To install, run:

bash <(curl -s https://deb.openalpr.com/install)

Select “install_sdk” from the menu.

Alpr API

Overview

The OpenALPR C API recognizes license plates given individual images. The library instance should be initialized once for each thread. There is a significant initilization time (a few seconds) so you should not destroy the instance until you are finished using it.

This instance is not threadsafe by design. An ALPR instance should be used on a single thread and not shared across threads.

C++

Defines

OPENALPR_DLL_EXPORT
namespace alpr
class Alpr

Public Functions

Alpr(const std::string country, const std::string configFile = "", const std::string runtimeDir = "", const std::string licenseKey = "")

Initialize the OpenALPR library. This operation should be performed once per thread.

Parameters
  • country: The country used for recognition (e.g., us for North American, eu for European, br for Brazil, etc.)
  • configFile: The path to the openalpr.conf file. Default is /etc/openalpr/openalpr.conf
  • runtimeDir: The path to the runtime_data directory. Default is /usr/share/openalpr/runtime_data/
  • licenseKey: The OpenALPR commercial license key

virtual ~Alpr()
void setCountry(std::string country)

Set the country used for plate recognition

Parameters
  • country: Country code (e.g., us, eu, in, etc.)

void setPrewarp(std::string prewarp_config)

Update the prewarp setting without reloading the library. Since version 2.4.101, the accuracy at angles has improved that setting a prewarp value is no longer necessary or recommended. It may still help in some cases for simple image rotation to correct for a camera installed at an angle.

Parameters
  • prewarp_config: A specially constructed string produced by the openalpr_calibrate utility

void setMask(unsigned char *pixelData, int bytesPerPixel, int imgWidth, int imgHeight)

Update the detection mask without reloading the library. The detection mask is used to improve processing efficiency (by ignoring areas for recognition) and to reduce false positives (by disqualifying plates found in areas where there could not be plates).

The Mask is simply a black/white image that should match the input resolution of the images. If it does not match, it will be stretched to fit. The white portions are areas that should be included for processing and the black areas will be ignored.

Parameters
  • pixelData: raw image bytes for BGR channels
  • bytesPerPixel: Number of bytes for each pixel (e.g., 3)
  • imgWidth: Width of the image in pixels
  • imgHeight: Height of the image in pixels

void setDetectRegion(bool detectRegion)

Parameters
  • detectRegion: true to enable region detection, false to disable

void setTopN(int topN)

Set the maximum number of plate candidates to return

Parameters
  • topN: an integer specifying the maximum possible plate results to return (default: 10)

void setDefaultRegion(std::string region)

Specify a region to use when applying patterns. For example, if the camera is installed in Germany, and 90% of the license plates will be German plates, using a pattern of “de” would try to match the results against the German plate patterns and improve accuracy.

Parameters
  • region: The state/province to use as the default for pattern matching (e.g., md for USA/Maryland, be for Europe/Belgium).

AlprResults recognize(std::string filepath)

Recognize from an image on disk. The file should be an image in an encoded format such as JPG, PNG, BMP, GIF, etc.

Return
The results of the ALPR recognition for this image
Parameters
  • filepath: Location of the file on disk (e.g., /tmp/image.jpg)

AlprResults recognize(std::vector<char> imageBytes)

Recognize from byte data representing an encoded image (e.g., BMP, PNG, JPG, GIF etc).

Return
The results of the ALPR recognition for this image
Parameters
  • imageBytes: array of bytes for the image

AlprResults recognize(std::vector<char> imageBytes, std::vector<AlprRegionOfInterest> regionsOfInterest)

Recognize from byte data representing an encoded image (e.g., BMP, PNG, JPG, GIF etc).

Return
The results of the ALPR recognition for this image
Parameters
  • imageBytes: Image bytes for the encoded image
  • regionsOfInterest: an array of regions to recognize. Areas not covered by a region of interest would be ignored. You may pass an empty array to scan the entire image.

AlprResults recognize(unsigned char *pixelData, int bytesPerPixel, int imgWidth, int imgHeight, std::vector<AlprRegionOfInterest> regionsOfInterest)

Recognize from raw pixel data.

Return
The results of the ALPR recognition for this image
Parameters
  • pixelData: raw image bytes for BGR channels
  • bytesPerPixel: Number of bytes for each pixel (e.g., 3)
  • imgWidth: Width of the image in pixels
  • imgHeight: Height of the image in pixels
  • regionsOfInterest: an array of regions to recognize. Areas not covered by a region of interest would be ignored. You may pass an empty array to scan the entire image.

std::vector<AlprResults> recognize_batch(std::vector<std::vector<char>> imageBytes)

Recognize a batch of images from byte data representing encoded images (e.g., BMP, PNG, JPG, GIF etc).

Return
The results of the ALPR recognition for this image
Parameters
  • imageBytes: An array of encoded image bytes

std::vector<AlprResults> recognize_batch(unsigned char **pixelData, int bytesPerPixel, int imgWidth, int imgHeight, int num_images, std::vector<std::vector<AlprRegionOfInterest>> regionsOfInterest)

Recognize a batch of images from raw pixel data. Batch processing is recommended when using a GPU for processing. Sending a batch of images allows the GPU to process them in parallel improving the overall efficiency.

Return
The results of the ALPR recognition for this image
Parameters
  • pixelData: raw image bytes for BGR channels
  • bytesPerPixel: Number of bytes for each pixel (e.g., 3)
  • imgWidth: Width of the image in pixels
  • imgHeight: Height of the image in pixels
  • num_images: The number of images in the batch
  • regionsOfInterest: an array of regions to recognize. Areas not covered by a region of interest would be ignored. You may pass an empty array to scan the entire image.

bool isLoaded()

Verifies whether the OpenALPR instance was properly loaded

Return
true if the engine is ready to use, false otherwise

Config *getConfig()

Public Static Functions

static std::string toJson(const std::vector<AlprResults> results)
static std::string toJson(const AlprResults results)

Converts the AlprResult object to JSON

Return
a properly formatted JSON string describing the ALPR results
Parameters

static std::string toJson(const AlprPlateResult result)
static AlprResults fromJson(std::string json)
static std::string getVersion()

Gets the current version of the OpenALPR software

Return
A version string (e.g., 2.4.102)

Private Members

AlprImpl *impl
struct AlprCoordinate

Public Members

int x
int y
struct AlprPlate
#include <alpr.h>

An individual plate result.

Public Members

std::string characters

The string characters of the plate (e.g., ABC123)

float overall_confidence

The confidence score from 0-100.

bool matches_template

Whether the plate matches a template for the province.

class AlprPlateResult

Public Functions

AlprPlateResult()
virtual ~AlprPlateResult()

Public Members

int requested_topn

The number requested is always >= the topNPlates count.

std::string country

The country (training data code) that was used to recognize the plate.

AlprPlate bestPlate

the best plate is the topNPlate with the highest confidence

std::vector<AlprPlate> topNPlates

A list of possible plate number permutations.

float processing_time_ms

The processing time for this plate.

AlprCoordinate plate_points[4]

the X/Y coordinates of the corners of the plate (clock-wise from top-left)

int plate_index

The index of the plate if there were multiple plates returned.

std::string region

When province detection is enabled, this returns the region (e.g., md).

int regionConfidence

The confidence for the detected region (0-100)

AlprRegionOfInterest vehicle_region

A bounding box where the car is likely to be found.

std::vector<unsigned char> plate_crop_jpeg

A cropped image (encoded as a JPEG) for the plate.

class AlprRegionOfInterest
#include <alpr.h>

Specifies a region of interest to restrict the area that OpenALPR analyzes. The region(s) must be rectangular. The x,y positions are specified in pixels and correspond to the top left corners of the rectangle. The width and height are also specified in pixels. The coordinate system origin (0,0) is the top left of the image

Public Functions

AlprRegionOfInterest()
AlprRegionOfInterest(int x, int y, int width, int height)

Public Members

int x
int y
int width
int height
class AlprResults

Public Functions

AlprResults()
virtual ~AlprResults()

Public Members

int64_t epoch_time

The time (in epoch ms) when the image for this image was captured.

int64_t frame_number

The relative frame number for this image.

int img_width
int img_height
float total_processing_time_ms

The total processing time for detecting and recognizing all plates in the image.

std::string image_uuid

A globally unique ID for this image.

bool error

True if an error occurred during processing, false otherwise.

std::string error_message

An error message if there was an error processing.

std::vector<AlprPlateResult> plates

An array of plate results.

std::vector<AlprRegionOfInterest> regionsOfInterest

The regions of interest provided when requesting recognition.

C

OpenALPR C API for license plate recognition on single images.

Typedefs

typedef void OPENALPR

Functions

OPENALPR *openalpr_init(const char *country, const char *configFile, const char *runtimeDir, const char *licenseKey = "")

Initializes the openALPR library and returns a pointer to the OpenALPR instance

The instance should be reused many times. Eventually you will want to destroy the instance when you are finished recognizing license plates.

see also openalpr_cleanup()

Return
An OpenALPR instance that can be used with other openalpr functions

int openalpr_is_loaded(OPENALPR *instance)

Verify that the OpenALPR library loaded correctly and can accept image inputs

see also alpr::Alpr::isLoaded()

Return
Returns 1 if the library was loaded successfully, 0 otherwise

void openalpr_set_country(OPENALPR *instance, const char *country)

Set the country used for plate recognition see also alpr::Alpr::setCountry()

void openalpr_set_prewarp(OPENALPR *instance, const char *prewarp_config)

Update the prewarp setting without reloading the library

see also alpr::Alpr::setPrewarp()

void openalpr_set_mask(OPENALPR *instance, unsigned char *pixelData, int bytesPerPixel, int imgWidth, int imgHeight)

Update the detection mask without reloading the library

see also alpr::Alpr::setMask()

void openalpr_set_detect_region(OPENALPR *instance, int detectRegion)

/deprecated Enables/disables state/province detection. Set this in openalpr.conf

see also alpr::Alpr::setDetectRegion()

void openalpr_set_topn(OPENALPR *instance, int topN)

Specify a region to use when applying patterns.

see also alpr::Alpr::setTopN()

void openalpr_set_default_region(OPENALPR *instance, const char *region)

Specify a region to use when applying patterns.

see also alpr::Alpr::setDefaultRegion()

char *openalpr_recognize_rawimage(OPENALPR *instance, unsigned char *pixelData, int bytesPerPixel, int imgWidth, int imgHeight, struct AlprCRegionOfInterest roi)

Recognizes the provided image and responds with JSON. Image is expected to be raw pixel data (BGR, 3 channels) Caller must call openalpr_free_response_string() on the returned object

see also alpr::Alpr::recognize()

Return
JSON formatted plate recognition results

char *openalpr_recognize_encodedimage(OPENALPR *instance, unsigned char *bytes, long long length, struct AlprCRegionOfInterest roi)

Recognizes the encoded (e.g., JPEG, PNG) image. bytes are the raw bytes for the image data. Image is expected to be raw pixel data (BGR, 3 channels) Caller must call openalpr_free_response_string() on the returned object

see also alpr::Alpr::recognize(), openalpr_recognize_rawimage()

Return
JSON formatted plate recognition results

void openalpr_free_response_string(char *response)

Frees a char* response that was provided from a recognition request. You must call this function on every response to avoid memory leaks.

Parameters
  • response: The string returned from an openalpr_recognize function

void openalpr_cleanup(OPENALPR *instance)

Free the memory for the OpenALPR instance created with openalpr_init

Parameters
  • instance: OpenALPR instance object

struct AlprCRegionOfInterest
#include <alpr_c.h>

Specifies a region of interest to restrict the area that OpenALPR analyzes. The region(s) must be rectangular. The x,y positions are specified in pixels and correspond to the top left corners of the rectangle. The width and height are also specified in pixels. The coordinate system origin (0,0) is the top left of the image

Public Members

int x
int y
int width
int height

Samples

C

First, install the OpenALPR library on your target platform. Make sure the software runs by testing it with the alpr command-line executable.

  1. Add “alpr_c.h” as an include file to your project.
  2. Include the libopenalpr.dll (Windows) or libopenalpr.so (Unix) file with your binaries.
  3. Include all other required shared libraries.
  4. Insert the openalpr.conf and runtime_data directory in the same location as the binaries. Alternatively, you can specify the location of the runtime_data in openalpr.conf or directly in the code.
  5. Add a commercial license key to the “license.conf” file in the same location as the binaries.

Below is a simple example of using the OpenALPR library with the C library:

#include <stdio.h>
#include <stdlib.h>
#include <alpr_c.h>

long read_file(const char* file_path, unsigned char** buffer)
{
    FILE *fileptr;
    long filelen;

    fileptr = fopen(file_path, "rb");     // Open the file in binary mode
    if (!fileptr)
        return 0;

    fseek(fileptr, 0, SEEK_END);          // Jump to the end of the file
    filelen = ftell(fileptr);             // Get the current byte offset in the file
    rewind(fileptr);                      // Jump back to the beginning of the file

    *buffer = (unsigned char *)malloc((filelen+1)*sizeof(char)); // Enough memory for file + \0
    fread(*buffer, filelen, 1, fileptr); // Read in the entire file
    fclose(fileptr); // Close the file

    return filelen;
}

int main(int argc, char *argv[])
{
    OPENALPR* alpr_obj;

    if (argc != 2)
    {
        printf("Usage: %s [path to image file]\n", argv[0]);
        return 1;
    }

    const char* file_path = argv[1];

    // Leave the config and runtime directory blank to look for these in the current directory.
    alpr_obj = openalpr_init("us", "", "");

    if (openalpr_is_loaded(alpr_obj))
    {
        // We don't want to restrict the size of the recognition area, so we set this to an extremely large pixel size
        // rather than decode and find the actual image width/height.
        struct AlprCRegionOfInterest roi;
        roi.x = 0;
        roi.y = 0;
        roi.width = 10000;
        roi.height = 10000;

        // Read the image file
        unsigned char* buffer;
        long long length = read_file(file_path, &buffer);

        printf("file size (bytes): %d\n", length);

        if (length > 0)
        {
            char* plate_response = openalpr_recognize_encodedimage(alpr_obj, buffer, length, roi);
            printf("Alpr response:\n%s\n", plate_response);
            openalpr_free_response_string(plate_response);
        }

        free(buffer);


    }

    openalpr_cleanup(alpr_obj);


    return 0;
}

C++

The C++ commercial SDK is available for Linux. For Windows computers, we recommend that you use the C library.

Add “alpr.h” as an include file to your project.

Below is a simple example of using the OpenALPR library with the C library:

#include <alpr.h>

// Initialize the library using United States-style license plates.
// You can use other countries/regions as well (for example: "eu", "au", or "kr").
alpr::Alpr openalpr("us", "/path/to/openalpr.conf");

// Optionally, you can specify the top N possible plates to return (with confidences). The default is ten.
openalpr.setTopN(20);

// Optionally, you can provide the library with a region for pattern matching. This improves accuracy by
// comparing the plate text with the regional pattern.
openalpr.setDefaultRegion("md");

// Make sure the library loads before continuing.
// For example, it could fail if the config/runtime_data is not found.
if (openalpr.isLoaded() == false)
{
    std::cerr << "Error loading OpenALPR" << std::endl;
    return 1;
}

// Recognize an image file. Alternatively, you could provide the image bytes in-memory.
alpr::AlprResults results = openalpr.recognize("/path/to/image.jpg");

// Carefully observe the results. There may be multiple plates in an image,
// and each plate returns the top N candidates.
for (int i = 0; i < results.plates.size(); i++)
{
  alpr::AlprPlateResult plate = results.plates[i];
  std::cout << "plate" << i << ": " << plate.topNPlates.size() << " results" << std::endl;

    for (int k = 0; k < plate.topNPlates.size(); k++)
    {
      alpr::AlprPlate candidate = plate.topNPlates[k];
      std::cout << "    - " << candidate.characters << "\t confidence: " << candidate.overall_confidence;
      std::cout << "\t pattern_match: " << candidate.matches_template << std::endl;
    }
}

C# and VB.NET

Source code: https://github.com/openalpr/openalpr/tree/master/src/bindings/csharp

using openalprnet;

var alpr = new AlprNet("us", "/path/to/openalpr.conf", "/path/to/runtime_data");
if (!alpr.IsLoaded())
{
    Console.WriteLine("OpenAlpr failed to load!");
    return;
}
// Optionally, you can apply pattern matching for a particular region.
alpr.DefaultRegion = "md";

var results = alpr.Recognize("/path/to/image.jpg");

foreach (var result in results.Plates)
{
    Console.WriteLine("Plate {0}: {1} result(s)", i++, result.TopNPlates.Count);
    Console.WriteLine("  Processing Time: {0} msec(s)", result.ProcessingTimeMs);
    foreach (var plate in result.TopNPlates)
    {
        Console.WriteLine("  - {0}\t Confidence: {1}\tMatches Template: {2}", plate.Characters,
                          plate.OverallConfidence, plate.MatchesTemplate);
    }
}

Python

Source code: https://github.com/openalpr/openalpr/tree/master/src/bindings/python

from openalpr import Alpr

alpr = Alpr("us", "/path/to/openalpr.conf", "/path/to/runtime_data")
if not alpr.is_loaded():
    print("Error loading OpenALPR")
    sys.exit(1)

alpr.set_top_n(20)
alpr.set_default_region("md")

results = alpr.recognize_file("/path/to/image.jpg")

i = 0
for plate in results['results']:
    i += 1
    print("Plate #%d" % i)
    print("   %12s %12s" % ("Plate", "Confidence"))
    for candidate in plate['candidates']:
        prefix = "-"
        if candidate['matches_template']:
            prefix = "*"

        print("  %s %12s%12f" % (prefix, candidate['plate'], candidate['confidence']))

# Call when completely done to release memory
alpr.unload()

Java

Source code: https://github.com/openalpr/openalpr/tree/master/src/bindings/java

import com.openalpr.jni.Alpr;
import com.openalpr.jni.AlprPlate;
import com.openalpr.jni.AlprPlateResult;
import com.openalpr.jni.AlprResults;

Alpr alpr = new Alpr("us", "/path/to/openalpr.conf", "/path/to/runtime_data");

// Set top N candidates returned to 20.
alpr.setTopN(20);

// Set pattern to Maryland.
alpr.setDefaultRegion("md");

AlprResults results = alpr.recognize("/path/to/image.jpg");
System.out.format("  %-15s%-8s\n", "Plate Number", "Confidence");
for (AlprPlateResult result : results.getPlates())
{
    for (AlprPlate plate : result.getTopNPlates()) {
        if (plate.isMatchesTemplate())
            System.out.print("  * ");
        else
            System.out.print("  - ");
        System.out.format("%-15s%-8f\n", plate.getCharacters(), plate.getOverallConfidence());
    }
}

// Make sure to call this to release memory.
alpr.unload();

Node.js

A Node.js binding to OpenALPR is available here: https://www.npmjs.com/package/node-openalpr

The source code is available here: https://github.com/netPark/node-openalpr

AlprStream API

Overview

OpenALPR AlprStream API is used for license plate recognition on videos or time-ordered image sequences.

The AlprStream API organizes video streams so that they can be efficiently processed by OpenALPR. The library utilizes motion detection to improve performance, and groups sequential plate results for each vehicle into a single result with the highest possible confidence. AlprStream also buffers incoming video and handles cases where video input is faster than the available processing by evenly dropping frames from the video buffer.

You may configure AlprStream to connect directly to a video feed (either an IP camera stream URL or a file). AlprStream will create a background thread that constantly pulls from the source to keep the video buffer full. You may also feed video frames directly. If sending video manually, you should do this on a separate thread.

AlprStream maintains a buffer of frames for processing. You may share an AlprStream object across threads. Each thread should maintain its own Alpr object. Passing the Alpr object to AlprStream using a process_frame() call performs a recognition and returns individual results. The AlprStream object keeps track of these results and forms plate groups.

Plate Groups can be accessed at any time by popping or peeking from the active list. Once a plate group is fully formed, and we are confident that the vehicle is no longer in the scene, it is available to be popped. Otherwise, it will remain on the list that you can peek, until enough time has passed.

Vehicle recognition is optionally run on each AlprGroup after it has been popped. The vehicle recognition is CPU/GPU intensive. AlprStream uses a region centered around the license plate to perform the vehicle recognition.

The AlprStream object should be initialized once for each video stream. The initialization time is minimal. The AlprStream instance is threadsafe.

C++

Defines

OPENALPRSTREAM_DLL_EXPORT
namespace alpr
class AlprGroupResult

Public Functions

AlprGroupResult()
virtual ~AlprGroupResult()
std::string toJson()

Convert the object to JSON.

void add_uuid(std::string uuid, int plate_index)

Assign a UUID to the group object. Used internally.

Public Members

int64_t epoch_ms_time_start

The time that the first plate in the group was seen.

int64_t epoch_ms_time_end

The time that the final plate in the group was seen.

int64_t frame_start

The first frame in the video stream when this group was active.

int64_t frame_end

The last frame in the video stream when this group was active.

std::vector<std::string> image_uuids

The unique identifiers for the individual plates that are part of this group.

std::vector<int> plate_indexes

The plate index in each image.

std::string country

The country (training data code) that was used to recognize the plate.

AlprPlateResult best_plate

the best plate is the topNPlate with the highest confidence

std::vector<AlprPlate> plate_candidates

All other possible plates for this group.

float best_confidence

The ALPR result in the group that had the highest confidence.

std::vector<unsigned char> best_plate_jpeg

A full image (encoded as a JPEG) for the frame in the group that had the highest confidence.

std::string best_uuid

The UUID for the highest confidence plate in the group.

std::string best_plate_number

The plate number for the highest confidence plate in the group.

std::string best_region

The state/province for the highest confidence plate in the group.

float best_region_confidence

Confidence of the region detection.

bool matches_template

Whether or not the group matches a regional pattern.

float travel_direction

Direction of motion for the license plate in degrees (clockwise with 0 degrees on top)

bool is_parked

Whether or not the plate number has been spotted recently at the same location.

VehicleResults vehicle_results

Results for vehicle body type, make, model, and color. Requires calling alpr::AlprStream::recognize_vehicle()

std::string agent_type

The type of agent that collected this data (The OpenALPR agent uses “alprd”)

std::string company_id

A unique identifier for the company.

std::string agent_uid

A unique identifier for the agent PC.

std::string user_data

An optional string specified by the user attached to each result.

int64_t camera_id

A unique identifier for the camera that captured the image.

class AlprStream

Public Functions

AlprStream(int frame_queue_size, bool use_motion_detection = true)

Initialize an AlprStream object. An AlprStream object should be initialized for each video input source.

This object is threadsafe.

Parameters
  • frame_queue_size: The size of the video buffer to be filled by incoming video frames
  • use_motion_detection: Whether or not to enable motion detection on this stream

virtual ~AlprStream()
int get_queue_size()

Check the size of the video buffer

Return
The total number of images waiting to be processed on the video buffer

void connect_video_stream_url(std::string url, std::string gstreamer_pipeline_format = "")

Spawns a thread that connects to the specified RTSP/MJPEG URL The thread continually fills the processing queue with images from the stream

Parameters
  • url: the full URL to be used to connect to the video stream
  • gstreamer_pipeline_format: An optional override for the GStreamer format. Use {url} for a marker to substitude the url value

std::string get_stream_url()

Get the stream URL.

Return
the stream URL that is currently being used to stream

void disconnect_video_stream()

Disconnect the video stream if you no longer wish for it to push frames to the video buffer.

void connect_video_file(std::string video_file_path, int64_t video_start_time)

Spawns a thread that fills the processing queue with frames from a video file The thread will slow down to make sure that it does not overflow the queue The “video_start_time” is used to us with the epoch start time of of the video

Parameters
  • video_file_path: The location on disk to the video file.
  • video_start_time: The start time of the video in epoch ms. This time is used as an offset for identifying the epoch time for each frame in the video

void disconnect_video_file()

If you wish to stop the video, calling this function will remove it from the stream

bool video_file_active()

Check the status of the video file thread

Return
True if currently active, false if inactive or complete

double get_video_file_fps()

Get the frames per second for the video file.

int push_frame(std::vector<char> imageBytes, int64_t frame_epoch_time = -1)

Push an encoded image (e.g., BMP, PNG, JPG, GIF etc). onto the video input buffer.

Return
The video input buffer size after adding this image, or -1 if an error occurred decoding the image.
Parameters
  • imageBytes: The image bytes for the encoded image
  • frame_epoch_time: The time when the image was captured. If not specified current time will be used

int push_frame(unsigned char *pixelData, int bytesPerPixel, int imgWidth, int imgHeight, int64_t frame_epoch_time = -1)

Push raw image data onto the video input buffer.

Return
The video input buffer size after adding this image
Parameters
  • pixelData: raw image bytes for BGR channels
  • bytesPerPixel: Number of bytes for each pixel (e.g., 3)
  • imgWidth: Width of the image in pixels
  • imgHeight: Height of the image in pixels
  • frame_epoch_time: The time when the image was captured. If not specified current time will be used

void set_uuid_format(std::string format)

Sets the format used for generating UUIDs. Default is “{time}-{random}” Valid options are: {time} - epoch_ms time the image was received {frame} - Frame number (starts at 0) {camera}, {company_uuid}, {agent_uid} - Any of the values specified in set_env_parameters {random} - a 16 character random string

Parameters
  • format: A string containing the UUID format

RecognizedFrame process_frame(Alpr *alpr)

Process the image at the front of the queue and return the individual results. Aggregates the results in a group

Return
The results for the recognized frames that was processed
Parameters
  • alpr: The Alpr instance that you wish to use for processing the images

std::vector<RecognizedFrame> process_batch(Alpr *alpr)

Process the image at the front of the queue and return the individual results. This function is most useful when using GPU acceleration. Processing frames in a batch more efficiently uses GPU resources.

You should make sure that the video buffer size for this AlprStream object is greater than or equal to the configured GPU batch size (in openalpr.conf).

Return
An array of the results for all recognized frames that were processed
Parameters
  • alpr: The Alpr instance that you wish to use for processing the images

RecognizedFrame skip_frame(bool return_jpeg = false)

Removes a frame from the queue without processing it

Return
A frame object for the skipped frame. If requested, it may contain the skipped frame JPEG.
Parameters
  • return_jpeg: Whether or not you wish to encode a JPEG for the skipped frame

std::vector<AlprGroupResult> pop_completed_groups()

If there are any groups that are complete, they will be returned in an array and removed from the grouping queue

Return
a vector containing all completed plate groups

std::vector<AlprGroupResult> peek_active_groups()

Checks the grouping list for active groups. Calling this function does not remove any entries from the grouping queue.

Return
a full list of all currently active groups.

void combine_grouping(AlprStream *other_stream)

Combine plate grouping across cameras. This is useful if one or more cameras are looking at roughly the same (i.e., from different angles), and you want to combine the group results.

Parameters
  • other_stream: another AlprStream pointer for the grouping to be combined

void recognize_vehicle(AlprGroupResult *alpr_group, VehicleClassifier *vehicle_classifier)

Recognize a vehicle for a given group. This operation is computationally more expensive than recognizing a plate.

void set_env_parameters(std::string company_id, std::string agent_uid, int camera_id)

Specify unique identifiers that are applied to the result JSON.

void set_group_parameters(int min_plates_to_group, int max_plates_per_group, float min_confidence, int max_delta_time)

Set grouping parameters that control the plate grouping sensitivity

Parameters
  • min_plates_to_group: A plate group must have at least this number of individual plate reads to form a group.
  • max_plates_per_group: At some point, if a plate is seen more than this number of times, it is wrapped into a group and sent even if the plate is still in the frame.
  • min_confidence: The plate read must have at least this confidence to be considered for grouping.
  • max_delta_time: The plate group waits this long for another plate to be identified with a similar license plate. If a matching plate is seen, this timer is reset.

void set_parked_vehicle_detect_params(bool enabled, int64_t max_delta_ms, float max_distance_multiplier, int max_text_distance)

Parked car detection flags plates that have not moved as being parked. The group results will still be sent, however the group will have a “parked_car” value set to true

Parameters
  • enabled: enable or disable detection.
  • max_delta_ms: The amount of time to wait for considering a car parked (default 120000 ms)
  • max_distance_multiplier: The relative distance from the previous position which we will consider the plate as not having moved. This is a multiplier relative to the plate width (default = 1.5)
  • max_text_distance: The levenshtein distance between plate group results to consider them the same (default = 1)

void set_detection_mask(std::vector<char> imageBytes)

Set a black/white mask to ignore content during motion detection/analysis

see also alpr::Alpr::setMask()

Parameters
  • imageBytes: The bytes of an encoded (e.g., JPEG, PNG, BMP, etc) image

void set_detection_mask(unsigned char *pixelData, int bytesPerPixel, int imgWidth, int imgHeight)
void set_jpeg_compression(int compression_level)

Set the jpeg compression level (between 1-100) for returning images

Parameters
  • compression_level: 100 is high quality with a large file size, 1 is low quality with a small file size. Default=85

void set_always_return_jpeg(bool always_return_jpeg)

By default, OpenALPR only encodes/returns a JPEG image if a plate is found this setting always encodes/returns a JPEG after processing.

Encoding a JPEG has some performance impact, so it is best to leave this off. unless you are using the return value.

This option can be toggled off and on during runtime and will immediately take effect.

Parameters
  • always_return_jpeg: True if you always wish for a JPEG to be returned, false otherwise

void set_motion_stickiness(float motion_stickiness)

Configures the motion detection to watch recently moving regions for longer. For highway traffic where vehicles are constantly moving, this should be a lower number For places where the vehicles may stop and start, a higher value will prevent duplicate plate reads

Parameters
  • motion_stickiness: A percentage between 0-100 determining how sticky the motion detection should be. 100=very sticky, 0=not sticky. Default=60

int get_camera_id()

Get the configured camera ID for this stream.

std::string get_agent_uid()

Get the configured Agent UID for this stream.

std::string get_company_id()

Get the configured company ID for this stream.

std::string get_user_data()

Get the configured User Data string for this stream.

StreamStatData getStats()

Get the latest statistic data for this stream.

void set_logger(void *log4cplus_ptr)

Sets the log4cplus logger (used internally)

std::string toJson(const AlprResults plate_read, std::string agent_type = "alprd")

Convert the AlprResults to JSON and include extended attributes such as company_id, agent_uid, etc. (used internally)

void set_user_data(const std::string user_data)

Specify an optional string to be applied to every plate/group result. This value will be appended to the JSON result.

Parameters
  • user_data: Arbitrary string value to be appended to plate and group results

Public Members

AlprStreamImpl *impl
struct RecognizedFrame

Public Members

bool image_available

True if there is an encoded JPEG returned. Otherwise false.

std::vector<unsigned char> jpeg_bytes

Encoded JPEG for the frame.

int64_t frame_epoch_time_ms

The epoch time (in milliseconds) that the image was captured.

int64_t frame_number

A 0-indexed frame number. This count starts when the stream is initialized.

AlprResults results

ALPR recognition results for the frame.

struct StreamStatData
#include <alprstream.h>

Contains statistics for measuring the performance of the stream. The values returned show the amount of video entering the stream, the amount of video that contained motion and the amount of moving video that was recognized for license plates.

Public Members

float measurement_period_seconds

The number of seconds between the now and the previous measurement.

float motion_percent

Percent of pixels that had motion compared to total video pixels.

float recognized_percent

Percent of pixels that were recognized compared to total motion pixels.

float video_fps

Average number of frames per second over the measurement period.

float motion_fps
float dropped_fps
float recognition_fps
int64_t video_pixel_throughput_ps

Average number of pixels per second over the measurement period.

int64_t motion_pixel_throughput_ps
int64_t dropped_pixel_throughput_ps
int64_t recognition_pixel_throughput_ps
bool is_streaming

If using alprstream to pull the RTSP/MJPEG stream, this provides stats.

int64_t last_stream_update

C

OpenALPR AlprStream C API for license plate recognition on videos or time-ordered image sequences.

Typedefs

typedef void ALPRSTREAM

void ALPRSTREAM

The instantiated AlprStream object. This is created by the alprstream_init() function and should be passed into subsequent functions.

Functions

ALPRSTREAM *alprstream_init(int frame_queue_size, int use_motion_detection = 1)

Initializes the ALPRSTREAM instance. Each stream of video should have its own AlprStream instance. This object is threadsafe.

Return
an ALPRSTREAM instance that can be used in future calls. Call alprstream_cleanup() once you’re finished with the object. See also alpr::AlprStream::AlprStream()

int alprstream_get_queue_size(ALPRSTREAM *instance)

Check the size of the video buffer

See also alpr::AlprStream::get_queue_size()

void alprstream_connect_video_stream_url(ALPRSTREAM *instance, const char *url)

See alpr::AlprStream::connect_video_stream_url()

void alprstream_disconnect_video_stream(ALPRSTREAM *instance)

See alpr::AlprStream::disconnect_video_stream()

void alprstream_connect_video_file(ALPRSTREAM *instance, const char *video_file_path, int64_t video_start_time)

See alpr::AlprStream::connect_video_file()

void alprstream_disconnect_video_file(ALPRSTREAM *instance)

See alpr::AlprStream::disconnect_video_file()

int alprstream_video_file_active(ALPRSTREAM *instance)

See alpr::AlprStream::video_file_active()

int alprstream_push_frame_encoded(ALPRSTREAM *instance, unsigned char *bytes, long long length, int64_t frame_epoch_time = -1)

See alpr::AlprStream::push_frame()

int alprstream_push_frame(ALPRSTREAM *instance, unsigned char *pixelData, int bytesPerPixel, int imgWidth, int imgHeight, int64_t frame_epoch_time = -1)

See alpr::AlprStream::push_frame()

AlprStreamRecognizedFrameC *alprstream_process_frame(ALPRSTREAM *instance, OPENALPR *alpr)

See alpr::AlprStream::process_frame(). Each response must be freed with alprstream_free_frame_response()

void alprstream_free_frame_response(AlprStreamRecognizedFrameC *response)

Frees memory from an alpr_stream_process_frame() response.

void alprstream_free_batch_response(AlprStreamRecognizedBatchC *response)

Frees memory from an alprstream_process_batch() response.

AlprStreamRecognizedFrameC *alprstream_skip_frame(ALPRSTREAM *instance, int return_image)

See alpr::AlprStream::skip_frame()

AlprStreamRecognizedBatchC *alprstream_process_batch(ALPRSTREAM *instance, OPENALPR *alpr)

See alpr::AlprStream::process_batch()

char *alprstream_pop_completed_groups(ALPRSTREAM *instance)

See alpr::AlprStream::pop_completed_groups()

Return
a JSON-formatted string describing the list of completed group results. Make sure to release the string memory using alprstream_free_response_string() after using it

char *alprstream_peek_active_groups(ALPRSTREAM *instance)

See alpr::AlprStream::peek_active_groups()

Return
a JSON-formatted string describing the list of active group results. Make sure to release the string memory using alprstream_free_response_string() after using it

char *alprstream_pop_completed_groups_and_recognize_vehicle(ALPRSTREAM *instance, VEHICLECLASSIFIER *vehicle_classifier)

Gets the completed groups from the list and performs vehicle make/model/color/type recognition before returning vehicle results. This is a CPU or GPU intensive operation so it may be best to perform on a separate thread.

Return
a JSON-formatted string describing the list of completed group results. Each group result will contain vehicle information as well. Make sure to release the string memory using alprstream_free_response_string() after using it
Parameters
  • vehicle_classifier: An initialized instance of the VehicleClassifier that AlprStream will use to perform vehicle recognition

void alprstream_combine_grouping(ALPRSTREAM *instance, ALPRSTREAM *other_stream)

See alpr::AlprStream::combine_grouping()

void alprstream_set_uuid_format(ALPRSTREAM *instance, const char *format)

See alpr::AlprStream::set_uuid_format()

void alprstream_set_env_parameters(ALPRSTREAM *instance, const char *company_id, const char *agent_uid, int camera_id)

See alpr::AlprStream::set_env_parameters()

void alprstream_set_detection_mask_encoded(ALPRSTREAM *instance, unsigned char *bytes, long long length)

See alpr::AlprStream::set_detection_mask()

void alprstream_set_detection_mask(ALPRSTREAM *instance, unsigned char *pixelData, int bytesPerPixel, int imgWidth, int imgHeight)

See alpr::AlprStream::set_detection_mask()

void alprstream_set_jpeg_compression(ALPRSTREAM *instance, int compression_level)

See alpr::AlprStream::set_jpeg_compression()

void alprstream_set_always_return_jpeg(ALPRSTREAM *instance, int always_return_jpeg)

See alpr::AlprStream::set_always_return_jpeg()

void alprstream_free_response_string(char *response)

Frees a char* response that was provided from a recognition request.

Parameters
  • response: A JSON character string from a previous pop/peek operation

void alprstream_cleanup(ALPRSTREAM *instance)

Free the memory for the OpenALPR instance created with alprstream_init()

struct AlprStreamRecognizedFrameC
#include <alprstream_c.h>

See alpr::RecognizedFrame.

Public Members

bool image_available
char *jpeg_bytes
int64_t jpeg_bytes_size
int64_t frame_epoch_time_ms
int64_t frame_number
char *results_str
struct AlprStreamRecognizedBatchC

Public Members

AlprStreamRecognizedFrameC **results_array
size_t results_size
char *batch_results

Samples

C

The following sample uses AlprStream API to recognize frames from a video. The Video is fed into the library asynchronously, and the processing occurs on the main thread.

To use ALPR on multiple CPU cores, you should create multiple threads that call the alprstream_process_frame() function. Each thread should have its own Alpr object, but can share the AlprStream object across threads.

// System imports
#include <cstdlib>
#include <vector>
#include <string>
#include <string.h>
#include <sstream>
#include <iostream>

// Import OpenALPR alprstream_c (also pulls in alpr_c.h and vehicleclassifier_c.h)
#include <alprstream_c.h>
#include <alpr_c.h>

using namespace std;


int main(int argc, char** argv) {

    cout << "Initializing" << endl;
    const std::string LICENSEPLATE_COUNTRY = "eu";

    // Video buffer frames controls the number of frames to buffer in memory.
    const int VIDEO_BUFFER_SIZE = 15;

    // The stream will assume sequential frames.  If there is no motion from frame to frame, then
    // processing can be skipped for some frames
    const int USE_MOTION_DETECTION = 1;

    // The point in time (ms) to start in the video file
    const int VIDEO_START_MS = 0;

    OPENALPR* alpr = openalpr_init(LICENSEPLATE_COUNTRY.c_str(), "", "");
    ALPRSTREAM* stream = alprstream_init(VIDEO_BUFFER_SIZE, USE_MOTION_DETECTION);

    // AlprStream will spawn a background thread to read the eu-clip.mp4 video file
    // and push to the queue.  Alternatively, you may connect to a stream URL, or
    // push individual image frames into the alprstream object yourself
    alprstream_connect_video_file(stream, "C:\\Temp\\eu-clip.mp4", VIDEO_START_MS);

    // Process until the video file is done and all remaining frames in the buffer have been processed
    while (true)
    {
        // If the buffer is empty wait for it to replenish
        if (alprstream_get_queue_size(stream) <= 0)
            Sleep(100);


        // AlprStream will now perform recognition on the oldest video frame on the queue
        AlprStreamRecognizedFrameC* response = alprstream_process_frame(stream, alpr);

        cout << "Content: " << response->results_str << endl;

        // Writes the image frame to a temp file on disk for demonstration purposes
        if (response->image_available)
        {
            FILE *file = fopen("c:\\temp\\test.jpg", "wb");
            fwrite(response->jpeg_bytes, sizeof(char), response->jpeg_bytes_size, file);
            fclose(file);
        }

        // Free the memory for each response
        alprstream_free_frame_response(response);

        cout << "Stream queue size: " << alprstream_get_queue_size(stream) << endl;
    }

    cout << "Done" << endl;

    // Cleanup the memory for the Alpr object
    openalpr_cleanup(alpr);

    // Cleanup the memory for the AlprStream object
    alprstream_cleanup(stream);
    return 0;
}