OpenALPR API

The OpenALPR Application Program Interface (API) is a way for programmers to make use of the OpenALPR engine in their own software. The API is available either as a REST API (The Cloud API) or as an On-Premises SDK.

Cloud API

The OpenALPR Cloud API is a web-based service that analyzes images for license plates as well as vehicle information such as make, model, and color. The Cloud API service is easy to integrate into your application via a web-based REST service. When you send image data to the OpenALPR API, we process that data and return JSON data describing the license plate and vehicle.

Check out the online demo: http://www.openalpr.com/demo-image.html

Sign Up

When you’re ready to get started, sign-up for an account at https://cloud.openalpr.com/

Once enrolled, you will automatically be assigned a free account with a limited number of API credits per month. Each recognition provided by the service costs one API credit. You may enter your credit card information and upgrade your plan to receive access to more credits per month.

Integration

Because the OpenALPR Cloud API is REST-based, it works with any programming language on any operating system. You can make API calls using whatever method you prefer.

The endpoint for the OpenALPR Cloud APIs are described in the REST API documentation.

Code Samples

For example, to connect to the OpenALPR API from the command line:

Bash

curl -X POST -F image=@/car1.jpg 'https://api.openalpr.com/v2/recognize?recognize_vehicle=1&country=us&secret_key=sk_DEMODEMODEMODEMODEMODEMO'

Python

#!/usr/bin/python

import requests
import base64
import json

# Sample image file is available at http://plates.openalpr.com/ea7the.jpg
IMAGE_PATH = '/tmp/sample.jpg'
SECRET_KEY = 'sk_DEMODEMODEMODEMODEMODEMO'

with open(IMAGE_PATH, 'rb') as image_file:
    img_base64 = base64.b64encode(image_file.read())

url = 'https://api.openalpr.com/v2/recognize_bytes?recognize_vehicle=1&country=us&secret_key=%s' % (SECRET_KEY)
r = requests.post(url, data = img_base64)

print(json.dumps(r.json(), indent=2))

C#

using System;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Http;
using System.IO;

namespace ConsoleApplicationTest
{
    class Program
    {
        private static readonly HttpClient client = new HttpClient();

        public static async Task<string> ProcessImage(string image_path)
        {
            string SECRET_KEY = "sk_DEMODEMODEMODEMODEMODEMO";

            Byte[] bytes = File.ReadAllBytes(image_path);
            string imagebase64 = Convert.ToBase64String(bytes);

            var content = new StringContent(imagebase64);

            var response = await client.PostAsync("https://api.openalpr.com/v2/recognize_bytes?recognize_vehicle=1&country=us&secret_key=" + SECRET_KEY, content).ConfigureAwait(false);

            var buffer = await response.Content.ReadAsByteArrayAsync().ConfigureAwait(false);
            var byteArray = buffer.ToArray();
            var responseString = Encoding.UTF8.GetString(byteArray, 0, byteArray.Length);

            return responseString;
        }

        static void Main(string[] args)
        {
            Task<string> recognizeTask = Task.Run(() => ProcessImage(@"C:\Temp\car1.jpg"));
            recognizeTask.Wait();
            string task_result = recognizeTask.Result;

            System.Console.WriteLine(task_result);
        }
    }
}

Java

import java.net.*;
import java.io.*;
import java.nio.file.*;
import java.util.Base64;


class TestOpenALPR {

    public static void main(String[] args)
    {
        try
        {
            String secret_key = "sk_DEMODEMODEMODEMODEMODEMO";

            // Read image file to byte array
            Path path = Paths.get("/storage/projects/alpr/samples/testing/car1.jpg");
            byte[] data = Files.readAllBytes(path);

            // Encode file bytes to base64
            byte[] encoded = Base64.getEncoder().encode(data);

            // Setup the HTTPS connection to api.openalpr.com
            URL url = new URL("https://api.openalpr.com/v2/recognize_bytes?recognize_vehicle=1&country=us&secret_key=" + secret_key);
            URLConnection con = url.openConnection();
            HttpURLConnection http = (HttpURLConnection)con;
            http.setRequestMethod("POST"); // PUT is another valid option
            http.setFixedLengthStreamingMode(encoded.length);
            http.setDoOutput(true);

            // Send our Base64 content over the stream
            try(OutputStream os = http.getOutputStream()) {
                os.write(encoded);
            }

            int status_code = http.getResponseCode();
            if (status_code == 200)
            {
                // Read the response
                BufferedReader in = new BufferedReader(new InputStreamReader(
                                        http.getInputStream()));
                String json_content = "";
                String inputLine;
                while ((inputLine = in.readLine()) != null)
                    json_content += inputLine;
                in.close();

                System.out.println(json_content);
            }
            else
            {
                System.out.println("Got non-200 response: " + status_code);
            }


        }
        catch (MalformedURLException e)
        {
            System.out.println("Bad URL");
        }
        catch (IOException e)
        {
            System.out.println("Failed to open connection");
        }

    }
}

JavaScript

<html>
    <title>
        Cloud API Demo
    </title>

    <head>
        <script>
        // Open connection to api.openalpr.com
        var secret_key = "sk_DEMODEMODEMODEMODEMODEMO";
        var url = "https://api.openalpr.com/v2/recognize_bytes?recognize_vehicle=1&country=us&secret_key=" + secret_key;
        var xhr = new XMLHttpRequest();
        xhr.open("POST", url);

        // Send POST data and display response
        xhr.send("base64_string");  // Replace with base64 string of an actual image
        xhr.onreadystatechange = function() {
            if (xhr.readyState == 4) {
                document.getElementById("response").innerHTML = xhr.responseText;
            } else {
                document.getElementById("response").innerHTML = "Waiting on response...";
            }
        }
        </script>
    </head>

    <body>
        JSON response: <p id="response"></p><br>
    </body>
</html>

Results

The JSON response is as follows:

{
   "uuid" : "",
   "regions_of_interest" : [
      {
         "height" : 600,
         "width" : 600,
         "y" : 0,
         "x" : 0
      }
   ],
   "credits_monthly_used" : 7040,
   "credit_cost" : 2,
   "img_height" : 600,
   "error" : false,
   "epoch_time" : 1522978197756,
   "version" : 2,
   "results" : [
      {
         "plate_index" : 0,
         "vehicle_region" : {
            "y" : 7,
            "width" : 568,
            "height" : 568,
            "x" : 16
         },
         "processing_time_ms" : 68.9315719604492,
         "vehicle" : {
            "body_type" : [
               {
                  "name" : "sedan-compact",
                  "confidence" : 89.6389389038086
               },
               {
                  "name" : "suv-standard",
                  "confidence" : 2.92187452316284
               },
               {
                  "name" : "sedan-wagon",
                  "confidence" : 2.83985614776611
               }
            ],
            "year" : [
               {
                  "confidence" : 47.3032341003418,
                  "name" : "2000-2004"
               },
               {
                  "name" : "2005-2009",
                  "confidence" : 39.6665573120117
               },
               {
                  "name" : "1995-1999",
                  "confidence" : 7.91491031646729
               }
            ],
            "make_model" : [
               {
                  "confidence" : 40.9104766845703,
                  "name" : "chevrolet_hhr"
               },
               {
                  "name" : "toyota_ist",
                  "confidence" : 22.9741859436035
               },
               {
                  "confidence" : 6.41662836074829,
                  "name" : "chevrolet_trailblazer"
               },
               {
                  "confidence" : 1.58923923969269,
                  "name" : "mazda_verisa"
               },
               {
                  "confidence" : 1.31779313087463,
                  "name" : "nissan_micra"
               },
               {
                  "name" : "mazda_tribute",
                  "confidence" : 1.24455153942108
               },
               {
                  "confidence" : 0.991917014122009,
                  "name" : "chevrolet_uplander"
               }
            ],
            "make" : [
               {
                  "confidence" : 32.4275550842285,
                  "name" : "chevrolet"
               },
               {
                  "name" : "toyota",
                  "confidence" : 31.9965953826904
               },
               {
                  "confidence" : 15.4623928070068,
                  "name" : "nissan"
               },
               {
                  "confidence" : 8.25705337524414,
                  "name" : "daihatsu"
               },
               {
                  "name" : "mazda",
                  "confidence" : 3.8371422290802
               }
            ],
            "color" : [
               {
                  "name" : "silver-gray",
                  "confidence" : 73.2146682739258
               },
               {
                  "name" : "blue",
                  "confidence" : 15.9568424224854
               }
            ],
            "orientation" : [
               {
                  "name" : "180",
                  "confidence" : 97.7202453613281
               },
               {
                  "confidence" : 1.84529066085815,
                  "name" : "225"
               }
            ]
         },
         "matches_template" : 1,
         "plate" : "627WWI",
         "requested_topn" : 10,
         "coordinates" : [
            {
               "x" : 237,
               "y" : 357
            },
            {
               "y" : 359,
               "x" : 364
            },
            {
               "x" : 362,
               "y" : 416
            },
            {
               "x" : 237,
               "y" : 414
            }
         ],
         "region_confidence" : 99,
         "region" : "wa",
         "candidates" : [
            {
               "matches_template" : 1,
               "confidence" : 94.9990844726562,
               "plate" : "627WWI"
            }
         ],
         "confidence" : 94.9990844726562
      }
   ],
   "credits_monthly_total" : 10000000000,
   "img_width" : 600,
   "data_type" : "alpr_results",
   "processing_time" : {
      "total" : 621.703000000025,
      "plates" : 140.277725219727,
      "vehicles" : 476.741000000004
   }
}

On-Premises 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. In addition to the installation options above, the Alpr API is available as a pip package through PyPI here: https://pypi.org/project/openalpr/.

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

Enums

enum AlprHardwareAcceleration

Values:

ALPR_CPU = 0
ALPR_NVIDIA_GPU = 1
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()
Alpr(const std::string country, const std::string configFile = "", const std::string runtimeDir = "")

Deprecated - Legacy constructor to support existing symbols.

Alpr(const std::string country, const std::string configFile, const std::string runtimeDir, const std::string licenseKey, AlprHardwareAcceleration acceleration_type, int gpu_id = 0, int batch_size = 10)

Initialize the OpenALPR library. This operation should be performed once per thread. Overrides the configuration in openalpr.conf to set GPU usage explicitly

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
  • acceleration_type: Nvidia GPU or CPU
  • gpu_id: The ID of the GPU to use. Default=0
  • batch_size: The number of images to process on the GPU simultaneously. Default=10

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)

Deprecated. This function no longer functions. Since version 2.4.101, the accuracy at angles has improved that setting a prewarp value is no longer used. The parameter has a detrimental affect on both performance and accuracy. Simple image rotation in AlprStream can be handled with gstreamer parameters.

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

bool getUseGpu()
int getGpuBatchSize()
int getGpuId()
Config *getConfig()

Public Static Functions

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

Deprecated: Converts the AlprResult object to JSON Use the toJson/fromJson on the AlprResults and AlprPlateResult classes

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()
std::string toJson(bool serialize_crop = false)

Exports this object to a JSON representation.

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.

Public Static Functions

static AlprPlateResult fromJson(std::string json_string)

Rebuilds this object from a JSON string.

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()
std::string toJson(bool serialize_crop = false)

Exports this object to a JSON representation.

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.

Public Static Functions

static AlprResults fromJson(std::string json_string)

Rebuilds this object from a JSON string.

C

OpenALPR C API for license plate recognition on single images.

Typedefs

typedef void OPENALPR
typedef void OPENALPR_IMAGE_BATCH

Enums

enum AlprCHardwareAcceleration

Values:

ALPRC_CPU = 0
ALPRC_NVIDIA_GPU = 1

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

OPENALPR *openalpr_init_gpu(const char *country, const char *configFile, const char *runtimeDir, const char *licenseKey, AlprCHardwareAcceleration acceleration_type, int gpu_id, int batch_size)

Initializes the openALPR library, overriding the openalpr.conf configuration for GPU 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. 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

OPENALPR_IMAGE_BATCH *openalpr_create_image_batch()

Creates an object that can be used to send a batch of images to OpenALPR Make sure to free the memory with openalpr_release_image_batch after you finish with the batch

Return
a pointer that can be passed into openalpr_add_image_to_batch and openalpr_recognize_batch

void openalpr_add_image_to_batch(OPENALPR_IMAGE_BATCH *batch, unsigned char *pixelData, int bytesPerPixel, int imgWidth, int imgHeight, struct AlprCRegionOfInterest roi)

Add an image to an OpenALPR batch object. Image is expected to be raw pixel data (BGR, 3 channels) The number of images should not exceed the configured batch_size property in openalpr.conf

void openalpr_add_encoded_image_to_batch(OPENALPR_IMAGE_BATCH *batch, unsigned char *bytes, long long length, struct AlprCRegionOfInterest roi)

Add an encoded image (e.g., JPEG, PNG, BMP, etc) to the batch

Parameters
  • bytes: raw bytes for the encoded image
  • length: length of the data
  • roi: region of interest to look for license plates

char *openalpr_recognize_batch(OPENALPR *instance, OPENALPR_IMAGE_BATCH *batch)

Recognizes the provided batch of images and responds with JSON. Caller must call openalpr_free_response_string() on the returned object

Return
JSON formatted plate recognition results for each image in the batch

void openalpr_release_image_batch(OPENALPR_IMAGE_BATCH *batch)

Free memory associated with an image batch crated by openalpr_create_image_batch()

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 AlprNet;

var alpr = new Alpr("us", "/path/to/openalpr.conf", "/path/to/runtime_data");
alpr.Initialize();
if (!alpr.IsLoaded())
{
    Console.WriteLine("OpenAlpr failed to load!");
    return;
}

var frame_lpr_data = alpr.Recognize("C:/path/to/imagefile/infiniti.jpg");
int i = 0;
foreach (var result in frame_lpr_data.results)
{
    Console.WriteLine("Plate {0}: {1} result(s)", ++i, result.candidates.Count);
    Console.WriteLine("  Processing Time: {0} msec(s)", result.processing_time_ms);
    foreach (var plate in result.candidates)
    {
        Console.WriteLine("  - {0}\t Confidence: {1}\tMatches Template: {2}", plate.plate,
                          plate.confidence, plate.matches_template);
    }
}
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

Enums

enum EncodeJpeg

Values:

ENCODE_NEVER = 0
ENCODE_PLATES = 1
ENCODE_ALWAYS = 2
class AlprGroupResult

Public Functions

AlprGroupResult()
virtual ~AlprGroupResult()
std::string toJson(bool serialize_crop = false)

Convert the object to JSON

Return
a string with JSON data describing the plate group
Parameters
  • serialize_crop: If enabled, the JPEG crop for the plate will be serialized as base64 in the 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.

int32_t best_image_width

The width of the image (in pixels) for the best_image referenced by this group.

int32_t best_image_height

The height of the image (in pixels) for the best_image referenced by this group.

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::vector<unsigned char> vehicle_jpeg

A full image (encoded as a JPEG) for the vehicle in the group if vehicle recognition is enabled.

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.

float gps_latitude

Latitude position (e.g., from GPS or static configuration)

float gps_longitude

Longitude position (e.g., from GPS or static configuration)

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.

Public Static Functions

static AlprGroupResult fromJson(std::string json_string)

Produces an AlprGroupResult object from JSON.

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_encode_jpeg(EncodeJpeg encode_jpeg)

By default, OpenALPR only encodes/returns a JPEG image if a plate is found this setting forces the JPEG encoder to always encode or never encode.

Encoding a JPEG has some performance impact. When processing on GPU, the encoding happens on CPU background threads. Disabling this setting (if the JPEG images are not used) will reduce CPU usage.

If encode_jpeg is set to never, vehicle recognition will not function correctly

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

Parameters
  • encode_jpeg: 0=Never, 1=On Found Plates, 2=Always

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.

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

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

void set_location(float latitude, float longitude)

Specify the current position of the camera (e.g., from GPS or static configuration) The value will be sent along with the alpr_group results

Parameters
  • latitude: latitude decimal value
  • longitude: longitude decimal value

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

void set_record_video(bool enabled, int max_storage_size_gb, std::string rolling_db_path)

For H264 streaming video streams over RTSP, optionally record the video to a rolling buffer The camera stream must be configured with “rtsph264” gstreamer_format in order to work.

Parameters
  • enabled: enable or disable video recording. Default is disabled
  • max_storage_size_gb: The maximum size of the rolling buffer (in gigabytes)
  • rolling_db_path: The path on disk to store the rolling database of video clips

void set_max_fps(int frames_per_second)

Specifies a max rate for incoming video. This improves efficiency if the video rate is higher than the available CPU cores can process. This is used for realtime streams, not video files or frame raw inputs. This function must be called prior to initializing the stream

Parameters
  • frames_per_second: an integer between 1 and 30. A value less than or equal to 0 means unlimited

Public Members

AlprStreamImpl *impl
struct RecognizedFrame

Public Members

bool image_available

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

bool queue_empty

True if we attempted to grab a frame, but none was available (empty queue)

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_group_parameters(ALPRSTREAM *instance, int min_plates_to_group, int max_plates_per_group, float min_confidence, int max_delta_time)

See alpr::AlprStream::set_group_parameters()

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_encode_jpeg(ALPRSTREAM *instance, int always_return_jpeg)

See alpr::AlprStream::set_encode_jpeg()

void alprstream_set_record_video(ALPRSTREAM *instance, int enabled, int max_storage_size_gb, char *rolling_db_path)

See alpr::AlprStream::set_record_video()

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);

        // Get Group results:
        char* group_result = alprstream_pop_completed_groups_and_recognize_vehicle(stream);
        cout << "Groups: " << group_result << endl;
        alprstream_free_response_string(group_result);

        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;
}
Python

Download our sample video file (http://download.openalpr.com/bench/720p.mp4) which has several cars with license plates in a parking lot (or take your own video in .mp4 format). Then, run the following code:

import sys
from alprstream import AlprStream
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_stream = AlprStream(frame_queue_size=10, use_motion_detection=True)
if not alpr_stream.is_loaded():
    print("Error loading AlprStream")
    sys.exit(1)

alpr_stream.connect_video_file('/path/to/720p.mp4', 0)

while alpr_stream.video_file_active() or alpr_stream.get_queue_size() > 0:
    single_frame = alpr_stream.process_frame(alpr)
    active_groups = len(alpr_stream.peek_active_groups())
    print("Active groups: {:<3} \tQueue size: {}".format(active_groups, alpr_stream.get_queue_size()))
    groups = alpr_stream.pop_completed_groups()
    for group in groups:
        print("=" * 50)
        print("Group ({}-{}): {} ({:.2f}% confident)".format(
            group['epoch_start'], group['epoch_end'],
            group['best_plate']['plate'], group['best_plate']['confidence']))
        print("=" * 50)