Vehicle Counter with gvaanalytics Tripwires
June 1, 2026 · View on GitHub
This sample demonstrates how to use the DLStreamer gvaanalytics element with tripwires to count vehicles crossing a virtual line in both directions.
The pipeline detects vehicles, tracks them across frames, and counts how many cross the tripwire from left-to-right and right-to-left.
A custom GStreamer element displays the crossing counters as a single-line watermark text overlay.
Pipeline Architecture
graph LR
A[filesrc] --> B[decodebin3]
B --> C[gvadetect]
C --> D[queue]
D --> E[gvatrack]
E --> F[queue]
F --> G[gvaanalytics]
G --> H[vehicle_counter_text]
H --> I[gvawatermark]
I --> J[gvafpscounter]
J --> K[videoconvert]
K --> L[autovideosink]
The pipeline stages implement the following functions:
- filesrc - reads video from a local file
- decodebin3 - decodes video into individual frames
- gvadetect - runs AI inference for object detection on each frame
- gvatrack - tracks detected objects across frames (required for tripwire detection)
- gvaanalytics - analyzes object trajectories and detects tripwire crossings
- vehicle_counter_text - custom element that counts crossings and adds watermark text
- gvawatermark - renders detection results and watermark text on frames
- autovideosink - renders the video stream to the display
How It Works
Step 1 - Detection and Tracking
The pipeline first detects vehicles using gvadetect, then passes the results through gvatrack to maintain consistent object IDs across frames.
Step 2 - Tripwire Analytics
The gvaanalytics element is configured with tripwire-config.json, which defines a vertical line at the middle of the frame (x=320 for 640x360).
As tracked objects cross this virtual line, the element generates TripwireMtd (tripwire metadata) events with direction information (1 = left-to-right crossing, -1 = right-to-left crossing).
Step 3 - Custom Counter Element
The vehicle_counter_text custom element (a GstBaseTransform) monitors the analytics metadata stream, counts tripwire crossings, and attaches watermark text metadata.
The text is displayed as a single line showing: L→R: X | R→L: Y | Total: Z
Step 4 - Watermark Rendering
The gvawatermark element renders the text overlay and detection bounding boxes on the video frames.
Step 5 - Pipeline Execution
The application sets the pipeline to PLAYING state and processes messages until the input video completes.
Tripwire Configuration
The tripwire-config.json file defines a vertical virtual line at the middle of the frame (x=320 for 640x360 resolution) where vehicles are counted:
{
"tripwires": [
{
"id": "vertical",
"points": [
{"x": 320, "y": 0},
{"x": 320, "y": 360}
]
}
]
}
The x-coordinate is set to 320 pixels (middle of 640px width). Adjust for different resolutions:
- 1920x1080: x=960
- 1280x720: x=640
- 640x360: x=320
Direction tracking:
- direction = 1: Vehicle crossing from left to right (crosses x=320 left-to-right)
- direction = -1: Vehicle crossing from right to left (crosses x=320 right-to-left)
Custom Element Architecture
This sample follows the same architecture as watermark_meta sample:
- Custom GStreamer Element - A
GstBaseTransformelement (vehicle_counter_text) that processes analytics metadata - Parse Launch Pipeline - Pipeline constructed using
Gst.parse_launch()for simplicity and readability - Element Registration - Custom element is registered at runtime for use in the pipeline string
The vehicle_counter_text element:
- Monitors tripwire crossing events from
gvaanalytics - Counts vehicles crossing left-to-right and right-to-left
- Filters detections by vehicle type (configurable via
vehicle-typesproperty) - Displays a single-line text overlay:
L→R: X | R→L: Y | Total: Z - Uses
DLStreamerWatermarkMeta.text_meta_add()for professional text rendering with:- Cyan color (RGB: 0, 255, 255) for good visibility
- Font size 0.6 (scaled for 640x360 resolution)
- White background for text readability
Vehicle Type Filtering
The element includes a vehicle-types property to filter which object types are counted:
# Count only cars, buses, and trucks (excludes persons, bicycles, etc.)
vehicle_counter_text vehicle-types=car,bus,truck
# Count all vehicles
vehicle_counter_text vehicle-types=car,bus,truck,motorcycle
# Customize for your use case
vehicle_counter_text vehicle-types=car,truck
The property accepts a comma-separated list of object class names returned by the detection model. Objects not in this list are ignored by the counter.
Running the Sample
Setup
The sample requires a video file and an object detection model. Download sample assets:
cd <python/gvaanalytics_tripwire directory>
export MODELS_PATH=${PWD}
wget https://videos.pexels.com/video-files/1192116/1192116-sd_640_360_30fps.mp4
../../../download_public_models.sh yolo11n
Note: This may take several seconds depending on your network speed.
Execution
You can run the sample using the provided shell script (easiest) or directly with Python.
Using the shell script:
./vehicle_counter.sh
This uses default settings: downloads the test video, uses YOLO11n model, and saves output to /tmp/vehicle_counter_output.mp4.
You can also customize the input, model, and output:
./vehicle_counter.sh file:///path/to/video.mp4 /path/to/model.xml /path/to/output.mp4
Using Python directly:
# Display output on screen
python3 ./vehicle_counter.py file:///path/to/video.mp4 ${MODELS_PATH}/public/yolo11n/FP16/yolo11n.xml
# Save output to file (H.264 MP4)
python3 ./vehicle_counter.py file:///path/to/video.mp4 ${MODELS_PATH}/public/yolo11n/FP16/yolo11n.xml output.mp4
The video stream displays with:
- Vehicle detection bounding boxes
- A horizontal line indicating the tripwire
- A counter showing vehicles crossing (left-to-right and right-to-left, filtered by vehicle type)
- Console output for each detected crossing
The sample saves output to file by default.
Customization
Save Output to File
The sample supports optional video file output with H.264 encoding:
# Save the analyzed video with detection and counter overlays
python3 ./vehicle_counter.py file:///path/to/input.mp4 model.xml output.mp4
The output file will contain:
- Vehicle detection bounding boxes
- Tripwire line visualization
- Live vehicle crossing counters overlaid as text
- All analytics metadata preserved
This is useful for reviewing results, sharing with others, or archiving analyzed footage.
Filter by Vehicle Types
The sample is pre-configured to count only cars, buses, and trucks. To customize:
Edit vehicle_counter.py and change the pipeline:
# Count only cars and trucks (exclude buses)
f"vehicle_counter_text vehicle-types=car,truck ! "
# Count all detected objects
f"vehicle_counter_text vehicle-types=car,bus,truck,motorcycle,bicycle,person ! "
# Count only trucks
f"vehicle_counter_text vehicle-types=truck ! "
The object type names depend on your detection model's class labels. Common classes include:
- Vehicles:
car,truck,bus,motorcycle,bicycle - People:
person - Animals:
dog,cat,bird, etc.
Adjust Tripwire Position
Edit tripwire-config.json to change the line position or add additional tripwires for counting in different directions.
Change Tracking Type
Modify the tracking-type property in vehicle_counter.py
Filter by Object Type
Extend the probe callback to check object categories and count only specific vehicle types (cars, trucks, etc.)