Samples
C
The following sample uses the Vehicle Recognition Stream 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 the API 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 <vehicle_classifier_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(), "", "", "");
VEHICLECLASSIFIER vehicle_classifier = vehicleclassifier_init("", "", 0,0, 0, "");
ALPRSTREAM stream = alprstream_init(VIDEO_BUFFER_SIZE, USE_MOTION_DETECTION);
// Enable to see detailed debug messages related to video read/queue
putenv("GST_DEBUG=2");
// 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, vehicle_classifier);
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, VehicleClassifier
# See https://docs.rekor.ai/rekor-scout/scout-agent/nvidia-gpu-acceleration
# GPU processing must use a single Alpr object and single thread per GPU.
# CPU processing may use multiple threads, with one Alpr object/thread per CPU core.
USE_GPU = False
GPU_BATCH_SIZE = 10
GPU_ID = 0
TRACK_VEHICLES_WITHOUT_PLATES = True
OPENALPR_CONFIG = '' #'/path/to/openalpr.conf'
RUNTIME_DATA_PATH = '' #'/path/to/runtime_data'
ALPR_COUNTRY = 'us'
# Sample video available at http://download.openalpr.com/bench/720p.mp4
TEST_VIDEO_FILE_PATH = '/path/to/video.mp4'
# Initialize instances
alpr = Alpr(ALPR_COUNTRY, OPENALPR_CONFIG, RUNTIME_DATA_PATH, use_gpu=USE_GPU, gpu_id=GPU_ID, gpu_batch_size=GPU_BATCH_SIZE)
if not alpr.is_loaded():
print('Error loading Alpr')
sys.exit(1)
alpr_stream = AlprStream(frame_queue_size=GPU_BATCH_SIZE, use_motion_detection=True)
if not alpr_stream.is_loaded():
print('Error loading AlprStream')
sys.exit(1)
vehicle = VehicleClassifier(OPENALPR_CONFIG, RUNTIME_DATA_PATH)
if not vehicle.is_loaded():
print('Error loading VehicleClassifier')
sys.exit(1)
alpr.set_detect_vehicles(True, TRACK_VEHICLES_WITHOUT_PLATES)
# Speeds up GPU by copying video data to GPU memory while processing
if USE_GPU:
alpr_stream.set_gpu_async(GPU_ID)
# Connect to stream/video and process results
alpr_stream.connect_video_file(TEST_VIDEO_FILE_PATH, 0)
while alpr_stream.video_file_active() or alpr_stream.get_queue_size() > 0:
if alpr.use_gpu:
single_frame = alpr_stream.process_batch(alpr)
else:
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_and_recognize_vehicle(vehicle, alpr)
for group in groups:
print('=' 40)
print('Group from frames {}-{}'.format(group['frame_start'], group['frame_end']))
if group['data_type'] == 'alpr_group':
print('Plate: {} ({:.2f}%)'.format(group['best_plate']['plate'], group['best_plate']['confidence']))
if group['data_type'] == 'vehicle' or group['data_type'] == 'alpr_group':
print('Vehicle attributes')
for attribute, candidates in group['vehicle'].items():
print('\t{}: {} ({:.2f}%)'.format(attribute.capitalize(), candidates[0]['name'], candidates[0]['confidence']))
print('=' 40)
# Call when completely done to release memory
alpr.unload()
vehicle.unload()
Last updated