A gRPC-based multi-object tracking service built on top of PaddleDetection. It accepts a video URL, processes it frame by frame, and streams back per-frame tracking results including bounding boxes, cropped person images, re-identification (ReID) features, and person attributes (gender, age range, glasses, hat, clothing, etc.).
Client -- VideoInfo (video URL) --> gRPC Server (async)
|
v
Executor Thread
- PaddleDetection pipeline
- MOT (multi-object tracking)
- ReID (re-identification)
- Attribute recognition
|
Janus Queue
|
v
Client <-- stream TrackResult -- Async consumer loop
- The server uses
grpc.aiofor async streaming. - A
janus.Queuebridges the synchronous PaddleDetection pipeline thread and the async gRPC response stream. - Each RPC call spawns an independent pipeline instance -- no shared state between requests.
.
├── src/
│ ├── server.py # gRPC server entry point
│ ├── client.py # Example client
│ ├── pipeline_wrapper.py # PaddleDetection pipeline initialization
│ └── utils.py # Image encode/decode utilities
├── protos/
│ ├── tracking_service.proto # Service and message definitions
│ ├── tracking_service_pb2.py # Generated protobuf bindings
│ ├── tracking_service_pb2_grpc.py # Generated gRPC stubs
│ └── tracking_service_pb2.pyi # Generated type stubs
├── overrides/PaddleDetection/deploy/pipeline/
│ ├── pipeline.py # Custom pipeline override
│ └── config/
│ ├── infer_cfg_pphuman.yml # Inference configuration (models, thresholds)
│ └── tracker_config.yml # Tracker algorithm parameters
├── Dockerfile
├── pyproject.toml
└── README.md
- Docker with NVIDIA GPU support (CUDA 11.2, cuDNN 8)
- The base image
paddlecloud/paddledetection:2.6-gpu-cuda11.2-cudnn8-latestincludes PaddlePaddle, PaddleDetection, OpenCV, and NumPy.
docker build -t tracking_service:1.0.0.1 .Start the container with GPU access. The server listens on port 10080.
docker run --gpus all -p 10080:10080 tracking_service:1.0.0.1For local debugging without the full gRPC server, you can process a single video directly:
docker run --gpus all tracking_service:1.0.0.1 uv run python src/server.py --video /path/to/video.mp4Copy .env.example to .env and adjust as needed. The service works without a .env file using the defaults below.
| Variable | Default | Description |
|---|---|---|
GRPC_LISTEN_ADDR |
[::]:10080 |
Address the gRPC server binds to |
PADDLE_HOME |
/home/PaddleDetection |
Root path of the PaddleDetection installation |
PADDLE_DEVICE |
GPU |
Device for inference (GPU or CPU) |
LOG_LEVEL |
INFO |
Python logging level (DEBUG, INFO, WARNING, ERROR) |
Defined in protos/tracking_service.proto.
service TrackingService {
rpc Track(VideoInfo) returns (stream TrackResult) {}
}The client sends a VideoInfo containing a video URL. The server streams back a sequence of TrackResult messages -- one per processed frame -- followed by a final PipelineResult indicating completion.
| Message | Description |
|---|---|
VideoInfo |
Request containing video_url |
TrackResult |
Wrapper holding either a FrameResult or a PipelineResult |
FrameResult |
Per-frame data: frame_id, list of StrackInfo |
StrackInfo |
Per-person data: track_id, bounding box, JPEG-encoded crop, ReID feature vector, ReID quality score, PersonAttribute |
PersonAttribute |
Gender, age range, facing direction, glasses, hat, upper-body clothing info |
PipelineResult |
Final message indicating the pipeline has finished |
import asyncio
import grpc
from protos import tracking_service_pb2, tracking_service_pb2_grpc
async def main():
async with grpc.aio.insecure_channel("localhost:10080") as channel:
stub = tracking_service_pb2_grpc.TrackingServiceStub(channel)
async for result in stub.Track(
tracking_service_pb2.VideoInfo(video_url="http://example.com/video.mp4")
):
if result.frame_result.frame_id:
print(f"Frame {result.frame_result.frame_id}: "
f"{len(result.frame_result.strack_infos)} persons tracked")
asyncio.run(main())A runnable example is also available at src/client.py. Set TRACK_SERVER_ADDR and TEST_VIDEO_URL environment variables to configure the target server and test video.
From the protos/ directory:
uv run python -m grpc_tools.protoc -I./ --python_out=./ --pyi_out=./ --grpc_python_out=./ tracking_service.protoControls which models are loaded and their batch sizes. Key sections:
- MOT -- detection + tracking model (PP-YOLOE-L), processes every frame by default (
skip_frame_num: -1) - ATTR -- person attribute recognition model (PPHGNet-small)
- REID -- re-identification embedding model
- KPT -- keypoint detection model (HRNet-W32)
Supports multiple tracker backends: JDETracker (ByteTrack-style, default), OCSORTTracker, DeepSORTTracker, and BOTSORTTracker. Switch by changing the type field.
| Package | Version | Purpose |
|---|---|---|
| grpcio | 1.48.0 | gRPC runtime |
| grpcio-tools | 1.48.0 | Protobuf code generation |
| janus | 1.0.0 | Sync/async queue bridge |
PaddlePaddle, PaddleDetection, OpenCV, and NumPy are provided by the base Docker image.