Skip to content

Repository files navigation

Tracking Service

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

Architecture

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.aio for async streaming.
  • A janus.Queue bridges the synchronous PaddleDetection pipeline thread and the async gRPC response stream.
  • Each RPC call spawns an independent pipeline instance -- no shared state between requests.

Project Structure

.
├── 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

Prerequisites

  • Docker with NVIDIA GPU support (CUDA 11.2, cuDNN 8)
  • The base image paddlecloud/paddledetection:2.6-gpu-cuda11.2-cudnn8-latest includes PaddlePaddle, PaddleDetection, OpenCV, and NumPy.

Build

docker build -t tracking_service:1.0.0.1 .

Run

Start the container with GPU access. The server listens on port 10080.

docker run --gpus all -p 10080:10080 tracking_service:1.0.0.1

For 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.mp4

Environment Variables

Copy .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)

gRPC API

Defined in protos/tracking_service.proto.

Service

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.

Key Messages

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

Example Client

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.

Regenerating Protobuf Bindings

From the protos/ directory:

uv run python -m grpc_tools.protoc -I./ --python_out=./ --pyi_out=./ --grpc_python_out=./ tracking_service.proto

Configuration

Inference (overrides/.../infer_cfg_pphuman.yml)

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

Tracker (overrides/.../tracker_config.yml)

Supports multiple tracker backends: JDETracker (ByteTrack-style, default), OCSORTTracker, DeepSORTTracker, and BOTSORTTracker. Switch by changing the type field.

Dependencies

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.

About

A gRPC-based multi-object tracking service

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages