# Samples

## C

First, install the Rekor Scout® 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 license key to the `license.conf` file in the same location as the binaries.

Below is a simple example:

```c
#include <stdio.h>
#include <stdlib.h>
#include <alpr_c.h>
#include <vehicle_classifier_c.h>
#include "json.hpp" // https://github.com/nlohmann/json
#include <iostream>

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;
    // Optional module to classify vehicle make/model/color
    VEHICLECLASSIFIER vehicle_classifier_obj;

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

    const char file_path = argv[1];
    const char OPENALPR_LICENSE_KEY = "";
    const char COUNTRY = "us";
    // Leave the config and runtime directory blank to look for these in the current directory.
    alpr_obj = openalpr_init(COUNTRY, "", "", OPENALPR_LICENSE_KEY);
    vehicle_classifier_obj = vehicleclassifier_init("", "", 0, 1, 0, OPENALPR_LICENSE_KEY);

    if (!openalpr_is_loaded(alpr_obj))
    {
      std::cout << "Error loading the OpenALPR library" << std::endl;
      return 1;
    }
    if (!vehicleclassifier_is_loaded(vehicle_classifier_obj))
    {
      std::cout << "Error loading the Vehicle Classifier library" << std::endl;
      return 1;
    }

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

        if (length == 0)
        {
          std::cout << "Unable to read file: " << file_path << std::endl;
          return 1;
        }

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

            // Parse the JSON that comes back
            nlohmann::json parsed_plate_data = nlohmann::json::parse(plate_response);
            // Free the JSON string now that we are done with it
            openalpr_free_response_string(plate_response);

            // Iterate over each plate and print the results
            for (nlohmann::json result : parsed_plate_data["results"])
            {
              std::cout << "plate: " << result["plate"].get<std::string>() << " - " << result["region"].get<std::string>() << " (" << result["confidence"].get<float>() << ")" << std::endl;

              // Classify the vehicle -- set the region of interest based on where ALPR tells us the car is
              VehicleClassifierCRegionOfInterest roi;
              roi.x = result["vehicle_region"]["x"];
              roi.y = result["vehicle_region"]["y"];
              roi.width = result["vehicle_region"]["width"];
              roi.height = result["vehicle_region"]["height"];
              char* vehicle_response = vehicleclassifier_recognize_encodedimage(vehicle_classifier_obj, COUNTRY, buffer, length, roi);

              // Parse the JSON that comes back
              nlohmann::json parsed_vehicle_data = nlohmann::json::parse(vehicle_response);
              //printf("Vehicle Response:\n%s\n", vehicle_response);
              vehicleclassifier_free_response_string(vehicle_response);

              // Write results to console
              for (std::string category : {"make", "color", "orientation", "make_model", "body_type", "year"})
                std::cout << "  - " << category << ": " << parsed_vehicle_data[category][0]["name"].get<std::string>() << " (" << parsed_vehicle_data[category][0]["confidence"].get<float>() << ")" << std::endl;

            }

        }

        free(buffer);

    }

    openalpr_cleanup(alpr_obj);
    vehicleclassifier_cleanup(vehicle_classifier_obj);

    return 0;
}
```

Output:

```json
./alpr_c_sample  cameraimage.jpg
plate: 4PCI264 - us-ca (94.7616195678711)
  - make: bmw (86.89132690429688)
  - color: silver-gray (90.59030151367188)
  - orientation: 180 (96.70639038085938)
  - make_model: bmw_3-series (86.49954223632813)
  - body_type: sedan-standard (96.80194854736328)
  - year: 2000-2004 (52.97491455078125)
```

## C++

The C++ Vehicle Recognition 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:

```cpp
#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>

```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>

```python
import sys
from openalpr import Alpr
from vehicleclassifier import VehicleClassifier

COUNTRY = 'us'
IMAGE_PATH = '/path/to/image.jpg'

# Initialize instances
alpr = Alpr(COUNTRY, '/path/to/openalpr.conf', '/path/to/runtime_data')
if not alpr.is_loaded():
    print('Error loading Alpr')
    sys.exit(1)
vehicle = VehicleClassifier('/path/to/openalpr.conf', '/path/to/runtime_data')
if not vehicle.is_loaded():
    print('Error loading VehicleClassifier')
    sys.exit(1)

# Set additional detection parameters (optional)
alpr.set_top_n(5)
alpr.set_default_region('md')

# Gather and print results
plate_results = alpr.recognize_file(IMAGE_PATH)
for i, plate in enumerate(plate_results['results']):
    print('Plate {:-<30}'.format(i))
    for c in plate['candidates']:
        display = '\t{:>7} {}'.format('{:.2f}%'.format(c['confidence']), c['plate'])
        if c['matches_template']:
            display += ' *'
        print(display)

vehicle_results = vehicle.recognize_file(COUNTRY, IMAGE_PATH)
best = [v[0]['name'] for k, v in  vehicle_results.items() if k != 'make']
print('\nTop vehicle: {} oriented at {} degrees'.format(' '.join(best[:-1]), best[-1]))
for attribute, candidates in vehicle_results.items():
    print('\n{:-<30}'.format(attribute.capitalize()))
    for c in candidates:
        label = c['name']
        if c['name'] == 'missing':
            label = 'unknown'
        print('\t{:>7} {}'.format('{:.2f}%'.format(c['confidence']), label))

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

## Java

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

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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.rekor.ai/developers/vehicle-recognition-sdk/vehicle-recognition-image-api/samples.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
