API Reference — License Plate Recognition
Endpoint REST API untuk membuat pipeline License Plate Recognition pada stream Visionaire4, event streaming hasil OCR via WebSocket, dan struktur event JSON.
← Kembali ke License Plate Recognition
Pengenalan, varian, persyaratan kamera, konfigurasi, dan output event.
Konfigurasi LPR
Referensi lengkap parameter body pipeline.
Endpoint pipeline (/pipeline/...) memanggil Visionaire4 API — basis URL dikonfigurasi melalui variabel VISIONAIRE_API_URL (default: http://localhost:4004). Autentikasi mengikuti konfigurasi deployment Visionaire4 Anda.
Manajemen Pipeline
Endpoint untuk membuat, memperbarui, membaca, dan menghapus pipeline LPR. Setiap pipeline diidentifikasi oleh kombinasi node_num + stream_id + analytic_id; segmen terakhir path menentukan varian (NFV4-LPR2, NFV4-LPRS, NFV4-LPR3, NFV4-LPR3S).
Authorization
bearerAuth In: header
Path Parameters
Nomor node Visionaire. Gunakan 0 untuk deployment single-node.
ID unik stream video yang akan diproses pipeline ini.
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
curl -X POST "http://localhost:4004/pipeline/0/stream_001/NFV4-LPR2" \ -H "Content-Type: application/json" \ -d '{ "plate_confidence_threshold": 0.6, "vehicle_confidence_threshold": 0.6, "similarity_score_threshold": 0.7, "min_group_member": 2, "plate_cache_lifetime": 10, "areas": [ { "name": "Gate A", "roi_type": "whitelist", "points": [ { "x": 0.1, "y": 0.3 }, { "x": 0.9, "y": 0.3 }, { "x": 0.9, "y": 0.9 }, { "x": 0.1, "y": 0.9 } ] } ] }'{ "code": 200, "message": "pipeline successfully created", "node_num": 0, "stream_id": "stream_001", "analytic_id": "NFV4-LPR2"}{ "code": 400, "message": "Pipeline already exists"}{ "code": 404, "message": "Stream not found"}Authorization
bearerAuth In: header
Path Parameters
Nomor node Visionaire. Gunakan 0 untuk deployment single-node.
ID unik stream video yang akan diproses pipeline ini.
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
curl -X PUT "http://localhost:4004/pipeline/0/stream_001/NFV4-LPR2" \ -H "Content-Type: application/json" \ -d '{ "plate_confidence_threshold": 0.7, "similarity_score_threshold": 0.8 }'{ "code": 200, "message": "pipeline successfully updated", "node_num": 0, "stream_id": "stream_001", "analytic_id": "NFV4-LPR2"}{ "code": 400, "message": "Pipeline already exists"}{ "code": 404, "message": "Stream not found"}Authorization
bearerAuth In: header
Path Parameters
Nomor node Visionaire. Gunakan 0 untuk deployment single-node.
ID unik stream video yang akan diproses pipeline ini.
Response Body
application/json
application/json
curl -X GET "http://localhost:4004/pipeline/0/stream_001/NFV4-LPR2"{ "code": 200, "node_num": 0, "stream_id": "stream_001", "analytic_id": "NFV4-LPR2", "config": {}, "message": "configuration has been successfully retrieved from the runtime pipeline"}{ "code": 400, "message": "analytic_id: NFV4-LPR2 is not exists given stream_id: stream_001"}Authorization
bearerAuth In: header
Path Parameters
Nomor node Visionaire. Gunakan 0 untuk deployment single-node.
ID unik stream video yang akan diproses pipeline ini.
Response Body
application/json
application/json
curl -X DELETE "http://localhost:4004/pipeline/0/stream_001/NFV4-LPR2"{ "code": 200, "message": "pipeline successfully deleted", "node_num": 0, "stream_id": "stream_001", "analytic_id": "NFV4-LPR2"}{ "code": 404, "message": "Stream not found"}Authorization
bearerAuth In: header
Path Parameters
Nomor node Visionaire. Gunakan 0 untuk deployment single-node.
ID unik stream video yang akan diproses pipeline ini.
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
curl -X POST "http://localhost:4004/pipeline/0/stream_001/NFV4-LPRS" \ -H "Content-Type: application/json" \ -d '{ "plate_confidence_threshold": 0.6, "vehicle_confidence_threshold": 0.6, "areas": [ { "name": "Checkpoint", "roi_type": "whitelist", "points": [ { "x": 0, "y": 0.2 }, { "x": 1, "y": 0.2 }, { "x": 1, "y": 1 }, { "x": 0, "y": 1 } ] } ] }'{ "code": 200, "message": "pipeline successfully created", "node_num": 0, "stream_id": "stream_001", "analytic_id": "NFV4-LPRS"}{ "code": 400, "message": "Pipeline already exists"}{ "code": 400, "message": "Pipeline already exists"}Authorization
bearerAuth In: header
Path Parameters
Nomor node Visionaire. Gunakan 0 untuk deployment single-node.
ID unik stream video yang akan diproses pipeline ini.
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
curl -X PUT "http://localhost:4004/pipeline/0/stream_001/NFV4-LPRS" \ -H "Content-Type: application/json" \ -d '{ "plate_confidence_threshold": 0.7 }'{ "code": 200, "message": "pipeline successfully updated", "node_num": 0, "stream_id": "stream_001", "analytic_id": "NFV4-LPRS"}{ "code": 400, "message": "Pipeline already exists"}{ "code": 400, "message": "Pipeline already exists"}Authorization
bearerAuth In: header
Path Parameters
Nomor node Visionaire. Gunakan 0 untuk deployment single-node.
ID unik stream video yang akan diproses pipeline ini.
Response Body
application/json
application/json
curl -X GET "http://localhost:4004/pipeline/0/stream_001/NFV4-LPRS"{ "code": 200, "node_num": 0, "stream_id": "stream_001", "analytic_id": "NFV4-LPR2", "config": {}, "message": "configuration has been successfully retrieved from the runtime pipeline"}{ "code": 400, "message": "Pipeline already exists"}Authorization
bearerAuth In: header
Path Parameters
Nomor node Visionaire. Gunakan 0 untuk deployment single-node.
ID unik stream video yang akan diproses pipeline ini.
Response Body
application/json
application/json
curl -X DELETE "http://localhost:4004/pipeline/0/stream_001/NFV4-LPRS"{ "code": 200, "message": "pipeline successfully deleted", "node_num": 0, "stream_id": "stream_001", "analytic_id": "NFV4-LPRS"}{ "code": 400, "message": "Pipeline already exists"}Authorization
bearerAuth In: header
Path Parameters
Nomor node Visionaire. Gunakan 0 untuk deployment single-node.
ID unik stream video yang akan diproses pipeline ini.
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
curl -X POST "http://localhost:4004/pipeline/0/stream_001/NFV4-LPR3" \ -H "Content-Type: application/json" \ -d '{ "plate_confidence_threshold": 0.7, "vehicle_confidence_threshold": 0.6, "plate_recognition_fps": 6, "plate_cache_lifetime": 3, "areas": [ { "name": "Toll Gate 1", "points": [ { "x": 0, "y": 0 }, { "x": 0.25, "y": 0 }, { "x": 0.25, "y": 1 }, { "x": 0, "y": 1 } ] } ] }'{ "code": 200, "message": "pipeline successfully created", "node_num": 0, "stream_id": "stream_001", "analytic_id": "NFV4-LPR3"}{ "code": 400, "message": "Pipeline already exists"}{ "code": 400, "message": "Pipeline already exists"}Authorization
bearerAuth In: header
Path Parameters
Nomor node Visionaire. Gunakan 0 untuk deployment single-node.
ID unik stream video yang akan diproses pipeline ini.
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
curl -X PUT "http://localhost:4004/pipeline/0/stream_001/NFV4-LPR3" \ -H "Content-Type: application/json" \ -d '{ "plate_recognition_fps": 8 }'{ "code": 200, "message": "pipeline successfully updated", "node_num": 0, "stream_id": "stream_001", "analytic_id": "NFV4-LPR3"}{ "code": 400, "message": "Pipeline already exists"}{ "code": 400, "message": "Pipeline already exists"}Authorization
bearerAuth In: header
Path Parameters
Nomor node Visionaire. Gunakan 0 untuk deployment single-node.
ID unik stream video yang akan diproses pipeline ini.
Response Body
application/json
application/json
curl -X GET "http://localhost:4004/pipeline/0/stream_001/NFV4-LPR3"{ "code": 200, "node_num": 0, "stream_id": "stream_001", "analytic_id": "NFV4-LPR2", "config": {}, "message": "configuration has been successfully retrieved from the runtime pipeline"}{ "code": 400, "message": "Pipeline already exists"}Authorization
bearerAuth In: header
Path Parameters
Nomor node Visionaire. Gunakan 0 untuk deployment single-node.
ID unik stream video yang akan diproses pipeline ini.
Response Body
application/json
application/json
curl -X DELETE "http://localhost:4004/pipeline/0/stream_001/NFV4-LPR3"{ "code": 200, "message": "pipeline successfully deleted", "node_num": 0, "stream_id": "stream_001", "analytic_id": "NFV4-LPR3"}{ "code": 400, "message": "Pipeline already exists"}Authorization
bearerAuth In: header
Path Parameters
Nomor node Visionaire. Gunakan 0 untuk deployment single-node.
ID unik stream video yang akan diproses pipeline ini.
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
curl -X POST "http://localhost:4004/pipeline/0/stream_001/NFV4-LPR3S" \ -H "Content-Type: application/json" \ -d '{ "plate_confidence_threshold": 0.7, "vehicle_confidence_threshold": 0.6, "plate_recognition_fps": 6, "areas": [ { "name": "Toll Gate 2", "points": [ { "x": 0.25, "y": 0 }, { "x": 0.5, "y": 0 }, { "x": 0.5, "y": 1 }, { "x": 0.25, "y": 1 } ] } ] }'{ "code": 200, "message": "pipeline successfully created", "node_num": 0, "stream_id": "stream_001", "analytic_id": "NFV4-LPR3S"}{ "code": 400, "message": "Pipeline already exists"}{ "code": 400, "message": "Pipeline already exists"}Authorization
bearerAuth In: header
Path Parameters
Nomor node Visionaire. Gunakan 0 untuk deployment single-node.
ID unik stream video yang akan diproses pipeline ini.
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
curl -X PUT "http://localhost:4004/pipeline/0/stream_001/NFV4-LPR3S" \ -H "Content-Type: application/json" \ -d '{ "plate_recognition_fps": 8 }'{ "code": 200, "message": "pipeline successfully updated", "node_num": 0, "stream_id": "stream_001", "analytic_id": "NFV4-LPR3S"}{ "code": 400, "message": "Pipeline already exists"}{ "code": 400, "message": "Pipeline already exists"}Authorization
bearerAuth In: header
Path Parameters
Nomor node Visionaire. Gunakan 0 untuk deployment single-node.
ID unik stream video yang akan diproses pipeline ini.
Response Body
application/json
application/json
curl -X GET "http://localhost:4004/pipeline/0/stream_001/NFV4-LPR3S"{ "code": 200, "node_num": 0, "stream_id": "stream_001", "analytic_id": "NFV4-LPR2", "config": {}, "message": "configuration has been successfully retrieved from the runtime pipeline"}{ "code": 400, "message": "Pipeline already exists"}Authorization
bearerAuth In: header
Path Parameters
Nomor node Visionaire. Gunakan 0 untuk deployment single-node.
ID unik stream video yang akan diproses pipeline ini.
Response Body
application/json
application/json
curl -X DELETE "http://localhost:4004/pipeline/0/stream_001/NFV4-LPR3S"{ "code": 200, "message": "pipeline successfully deleted", "node_num": 0, "stream_id": "stream_001", "analytic_id": "NFV4-LPR3S"}{ "code": 400, "message": "Pipeline already exists"}Respons POST untuk kombinasi node_num + stream_id + analytic_id yang sudah ada adalah HTTP 400 (bukan 409) dengan pesan error dari server. Endpoint GET mengembalikan bentuk config yang berbeda tergantung varian — untuk NFV4-LPR2/NFV4-LPRS, config berisi daftar parameter default lengkap beserta areas aktif; untuk NFV4-LPR3/NFV4-LPR3S, config hanya berisi body konfigurasi terakhir yang tersimpan di database (server tidak memasukkan kedua varian ini ke daftar verbose-config).
Event Streaming (WebSocket)
Visionaire4 mengirim setiap event hasil deteksi/OCR melalui WebSocket. Untuk berlangganan event dari pipeline LPR pada stream tertentu, buka koneksi ke:
ws://<host>:4004/event_channel/{node_num}/{stream_id}/{analytic_id}Ganti {analytic_id} dengan varian yang dipakai (NFV4-LPR2, NFV4-LPRS, NFV4-LPR3, atau NFV4-LPR3S) — harus sama dengan analytic_id pipeline yang dibuat.
Setelah koneksi terbuka, server langsung mendorong (push) setiap event ke client tanpa handshake atau pesan subscribe. Tutup koneksi untuk berhenti menerima event.
Parameter Path
| Parameter | Tipe | Deskripsi |
|---|---|---|
node_num | integer | Nomor node tempat stream berjalan (0 = master) |
stream_id | string | ID stream yang akan dipantau |
Query Parameter (Opsional)
| Parameter | Tipe | Deskripsi |
|---|---|---|
logic | string | Filter event berdasarkan nama logic rule yang aktif pada pipeline. Tanpa parameter ini, semua event dari analitik akan dikirim. |
Contoh Koneksi
const ws = new WebSocket(
'ws://localhost:4004/event_channel/0/<stream_id>/NFV4-LPR2'
);
ws.onmessage = (msg) => {
const event = JSON.parse(msg.data);
console.log(event.primary_text, event.pipeline_data);
};
ws.onerror = (err) => console.error('WebSocket error', err);
ws.onclose = () => console.log('Disconnected');import asyncio
import json
import websockets
async def listen():
url = "ws://localhost:4004/event_channel/0/<stream_id>/NFV4-LPR2"
async with websockets.connect(url) as ws:
async for msg in ws:
event = json.loads(msg)
print(event["primary_text"], event["pipeline_data"])
asyncio.run(listen())Endpoint Channel Lainnya
Untuk mendengarkan event yang lebih luas (lintas analitik atau lintas stream), gunakan endpoint berikut yang dijelaskan pada Developer Guide:
| Endpoint | Cakupan |
|---|---|
WS /event_channel/ | Semua event dari seluruh node |
WS /event_channel/{node_num}/ | Semua event dari satu node |
WS /event_channel/{node_num}/{stream_id} | Semua event dari satu stream (semua analitik) |
Live View (MJPEG)
GET /mjpeg/{node_num}/{stream_id}/{analytic_id} menghasilkan MJPEG stream dengan overlay pipeline (bounding box kendaraan/plat, garis ROI) — berguna untuk memverifikasi konfigurasi areas secara visual. Tanpa {analytic_id} (GET /mjpeg/{node_num}/{stream_id}), endpoint ini menampilkan stream mentah tanpa overlay analitik apa pun.
Query Parameter
| Parameter | Tipe | Default | Deskripsi |
|---|---|---|---|
fps | integer | 0 | Frame per detik output MJPEG. 0 = tidak dibatasi. |
height | integer | 320 | Tinggi output dalam piksel. |
jq | integer | 60 | Kualitas JPEG (0–100). |
curl "http://localhost:4004/mjpeg/0/gate_entry_001/NFV4-LPR2?fps=10&height=480&jq=70"GET /visual/{node_num}/{stream_id}/{analytic_id} bukan endpoint MJPEG — ia mengembalikan halaman HTML viewer, bukan gambar/stream langsung. Untuk mengambil MJPEG secara terprogram, gunakan /mjpeg/... di atas. Path /pipeline/{node_num}/{stream_id}/{analytic_id}/mjpeg, /pipeline/.../config, dan /pipeline/.../snapshot yang muncul di dokumentasi versi lama tidak ada — endpoint MJPEG selalu berada di bawah prefix /mjpeg/..., terpisah dari /pipeline/....
Struktur Event
Pipeline memancarkan satu event setiap kali kendaraan dengan plat selesai diproses dan lolos semua filter (atau, jika enable_dump_non_plate aktif, saat kendaraan tanpa plat terdeteksi keluar dari frame). Event dikirim melalui event channel WebSocket dan disimpan ke database node kecuali --db-disable-event-store aktif.
Semua modul analitik Visionaire memakai envelope yang sama; bagian yang spesifik LPR ada di pipeline_data.
{
"timestamp": 1705314600,
"node_num": 0,
"stream_id": "gate_entry_001",
"stream_name": "Gerbang Utama",
"stream_address": "rtsp://10.7.2.50:554/stream",
"stream_longitude": 106.823649,
"stream_latitude": -6.261376,
"analytic_id": "NFV4-LPR2",
"primary_text": "car|Gate A",
"secondary_text": "B1234ABC",
"pipeline_data": {
"event_id": "1705314600-1a2b3c4d",
"confidence": 0.95,
"label": "car",
"area_name": "Gate A",
"plate_number": "B1234ABC",
"plate_type": "plate",
"bounding_box": { "left": 812.0, "top": 611.0, "width": 96.0, "height": 34.0 },
"direction": "down",
"attributes": {
"vehicle": { "label": "car", "confidence": 0.92 },
"plate": { "label": "plate", "confidence": 0.88 },
"character": { "label": "B1234ABC", "confidence": 0.95 }
}
},
"image_jpeg": "<base64 JPEG>"
}Field Envelope
| Field | Tipe | Deskripsi |
|---|---|---|
timestamp | int | Waktu event dalam epoch detik (UTC). |
node_num | int | Nomor node tempat pipeline berjalan. |
stream_id | string | Identifier stream sumber. |
stream_name | string | Nama stream. |
stream_address | string | URL sumber video stream. |
stream_longitude, stream_latitude | float | Posisi kamera. |
analytic_id | string | Varian pipeline yang memancarkan event — NFV4-LPR2, NFV4-LPRS, NFV4-LPR3, atau NFV4-LPR3S. |
primary_text | string | Label kendaraan (mis. car), ditambah suffix |<area_name> jika mode whitelist dan area bukan default. |
secondary_text | string | Nomor plat hasil OCR (ditambah , <plate_type> jika bukan plate). |
pipeline_data | object | Detail deteksi — lihat tabel berikutnya. |
image_jpeg | string (base64) | Crop JPEG kendaraan/plat hasil deteksi. |
Envelope tidak memiliki field event_id di level atas maupun timestamp_ms — keduanya sering diasumsikan ada tapi tidak pernah dikirim. ID unik event ada di pipeline_data.event_id.
Field pipeline_data
| Field | Tipe | Deskripsi |
|---|---|---|
event_id | string | ID unik event berformat <timestamp>-<hash8>. |
confidence | float | Confidence hasil OCR karakter plat (0.0–1.0). |
label | string | Jenis kendaraan — car, bus, truck, motorcycle (dan bicycle pada NFV4-LPR3/NFV4-LPR3S). |
area_name | string | Nama area ROI tempat kendaraan terdeteksi, atau default pada mode blacklist / saat areas tidak dikonfigurasi. |
plate_number | string | Hasil OCR nomor plat. Kosong jika event berasal dari enable_dump_non_plate tanpa plat terdeteksi. |
plate_type | string | NFV4-LPR2/NFV4-LPR3: selalu plate. NFV4-LPRS/NFV4-LPR3S: salah satu dari private, public, government, embassy, new_vehicle, police, tni_1-AU, tni_2-AD, tni_3-AL, kemenhan, mabes_tni. |
bounding_box | object | Posisi plat (bukan kendaraan) dalam koordinat pixel pada frame asli — {left, top, width, height}. Untuk event dari enable_dump_non_plate tanpa plat, field ini berisi bounding box kendaraan. |
direction | string | NFV4-LPR2/NFV4-LPRS: up, down, atau none, dihitung dari pergerakan vertikal plat antar sampel. NFV4-LPR3/NFV4-LPR3S: selalu unknown. Lihat Varian & Cara Kerja. |
attributes.vehicle | object | {label, confidence} hasil deteksi kendaraan. |
attributes.plate | object | {label, confidence} hasil deteksi plat — label sama dengan plate_type. |
attributes.character | object | {label, confidence} hasil OCR karakter — label sama dengan plate_number. |
bounding_box berisi koordinat pixel absolut relatif terhadap dimensi frame asli, bukan koordinat dinormalisasi [0,1] seperti areas.points pada request body. Jangan menyamakan sistem koordinat keduanya.
Best Practices & Troubleshooting
Tuning threshold, keterbatasan sistem, dan runbook untuk masalah umum pada License Plate Recognition.
People Analytics
Analitik video real-time untuk menghitung orang yang melintas, memantau zona, mendeteksi orang yang berdiam, dan mengestimasi kepadatan — dengan atribut demografis opsional.