Skip to main content
SDK Version: Next

DX-APP Python Usage Guide

This guide explains how to navigate and use the refactored Python example tree in DX-APP.


Overview

The Python examples are located under src/python_example/ and are organized by:

  • task
  • model family
  • execution and post-processing variant

All examples share a common runtime layer under src/python_example/common/ that provides base interfaces, processors, runners, input sources, visualizers, and utilities. This is the Python counterpart of src/cpp_example/common/ — both languages implement the same 7-module factory-based architecture. Each model directory contains only thin entry-point scripts and a factory that wires shared components together.

Representative task directories include:

  • 3d_object_detection/ — SFA3D
  • attribute_recognition/ — DeepMAR
  • classification/ — EfficientNet, AlexNet, ResNet, MobileNet, etc.
  • depth_estimation/ — FastDepth, SCDepthV3, DepthAnythingV2
  • embedding/ — ArcFace
  • face_alignment/ — 3DDFA v2
  • face_detection/ — SCRFD, YOLOv5Face, YOLOv7Face, RetinaFace
  • hand_detection/ — MediaPipe Hand
  • hand_landmark/ — Hand landmark estimation
  • image_denoising/, image_enhancement/, super_resolution/ — DnCNN, Zero-DCE, ESPCN, RealESRGAN
  • instance_segmentation/ — YOLOv8Seg, YOLOv26Seg
  • keypoint_detection/ — SuperPoint
  • obb_detection/ — YOLOv26OBB
  • object_detection/ — YOLOv3/v5/v7/v8/v9/v10/v11/v12, YOLO26, YOLOX, NanoDet, DAMOYOLO, SSD
  • object_pose_estimation/ — DOPE
  • panoptic_driving_perception/ — YOLOPv2
  • pose_estimation/ — YOLOv8-Pose, VitPose
  • ppu/ — PPU-accelerated variants (YOLOv5/v7/v8/v9/v10/v11/v12/SCRFD/Pose)
  • reid/ — Person re-identification (CasViT)
  • semantic_segmentation/ — BiSeNet, DeepLabV3+, SegFormer

For the full repository-level structure, refer to DX-APP Example Source Structure.


Architecture & Design Pattern

Architecture Strategy

Shared Runtime Layer (common/)

The common/ directory is the engine behind all Python examples:

ModuleRole
common/base/Abstract interfaces: IFactory, IProcessor, IVisualizer, IInputSource
common/config/ModelConfig — loads config.json (input size, labels, thresholds)
common/processors/35 shared post-processors covering all model families
common/runner/SyncRunner, AsyncRunner, run_dir, verify_serialize, args — generic execution engines with built-in profiling
common/inputs/Input source abstraction: image, video, camera, RTSP
common/visualizers/10 task-specific visualizers (detection, segmentation, pose, etc.)
common/utility/Labels, preprocessing, profiling, drawing helpers

Factory Pattern & Model Registry

Each model directory has a factory/{model}_factory.py that implements IFactory:

from common.processors import YOLOv5Postprocessor
from common.visualizers import DetectionVisualizer

class Yolov9sFactory(IFactory):
def create_processor(self):
return YOLOv5Postprocessor(self.config)
def create_visualizer(self):
return DetectionVisualizer(self.config)

The entry-point script simply delegates to the runner:

from common.runner import SyncRunner
runner = SyncRunner(factory)
runner.run()

Model Registry (config/model_registry.json)

A JSON registry stores per-model metadata (task, postprocessor type, input dimensions, thresholds). The scripts/add_model.sh tool reads this registry to auto-generate factory files, config.json, and all entry-point scripts — enabling zero-code model onboarding.

Directory & File Pattern

Each model family has its own directory with a consistent structure:

src/python_example/object_detection/yolov9s/
├── config.json # Model-specific runtime settings
├── factory/
│ └── yolov9s_factory.py # Wires shared processor + visualizer
├── yolov9s_sync.py # Pure Python synchronous
├── yolov9s_async.py # Pure Python asynchronous
├── yolov9s_sync_cpp_postprocess.py # Synchronous + C++ binding
└── yolov9s_async_cpp_postprocess.py # Asynchronous + C++ binding

Execution Framework

Execution Variants

Pure Python Flow (*_sync.py, *_async.py)

Use these when you want:

  • easier logic inspection — post-processing is readable Python in common/processors/
  • Python-first experimentation
  • simpler debugging during algorithm development

C++ Post-process Flow (*_cpp_postprocess.py)

Use these when you want:

  • faster post-processing — uses C++ via pybind11 (dx_postprocess)
  • better alignment with shared C++ decode logic
  • more realistic performance validation

CLI Interface

All Python examples use argparse via common/runner/args.py and share a consistent interface:

FlagShortTypeDescription
--model-mstringPath to .dxnn model file (auto-downloaded if missing)
--image-istringInput image file or directory
--video-vstringInput video file
--camera-cintCamera device index
--rtsp-rstringRTSP stream URL
--save-sflagSave rendered output to a run directory
--save-dirstringBase output directory (default: artifacts/python_example/)
--dump-tensorsflagDump input/output tensors to .npy files
--loop-lintInference repeat count (default: 1; bare --loop = 2)
--no-displayflagDisable visualization window
--show-logflagEnable verbose log output (default: quiet)
--configstringModel config JSON path (auto-detected if omitted)
--fast-postprocessflagOpt-in faster postprocessing variant where available (standard path is the default)
--output-ostringOutput file path (restoration/depth/SR only)
--help-hShow usage
  • Input source: --image, --video, --camera, and --rtsp form a mutually exclusive group. If none is specified, a default sample image is automatically selected based on the task type.
NOTE

Image-only tasks: embedding, reid, and attribute_recognition tasks accept --image input only. --video, --camera, and --rtsp are not supported for these tasks because meaningful inference requires a crop of a pre-detected subject (face or person). Running a single embedding model on a raw video stream without a preceding detector would not produce valid results. Passing a video/camera source to these tasks exits with an error.


Getting Started (Workflow)

Step 1. Prepare assets

./setup.sh

Step 2. Build shared libraries

./build.sh

Step 3. Run a Python example

python src/python_example/object_detection/yolov9s/yolov9s_sync.py --model assets/models/YoloV9S.dxnn --image sample/img/sample_kitchen.jpg
python src/python_example/object_detection/yolov9s/yolov9s_async_cpp_postprocess.py --model assets/models/YoloV9S.dxnn --video assets/videos/dance-group.mov

Advanced Operations & Debugging

Runtime Features

Auto-Download

When a specified model file is not found locally, the runner automatically attempts to download it via setup_sample_models.sh. If a --video file is missing, setup_sample_videos.sh is invoked. If the download fails, a clear error message with manual download instructions is displayed.

Default Input Fallback

If no input source is provided, the runner automatically selects a default sample image appropriate for the task type (e.g., sample/img/sample_street.jpg for object detection). A log message indicates which default was applied:

[DXAPP] [INFO] No input specified. Using default sample: sample/img/sample_street.jpg

Signal Handling

Both SyncRunner and AsyncRunner use stop_event (threading.Event) for graceful Ctrl+C shutdown. The async pipeline uses a SENTINEL chain to propagate stop signals through all queues.

Output Management (--save)

When --save is enabled, a timestamped directory is created (e.g., artifacts/python_example/{model}-image-{name}-{timestamp}/) containing run_info.txt, saved images/video, and optional tensor dumps.

Headless Mode

When DISPLAY/WAYLAND_DISPLAY environment variables are absent, cv2.imshow() is automatically skipped. Use --no-display for explicit headless operation.

Model Configuration (--config)

Runtime parameters (thresholds, top-k, etc.) are loaded via _FactoryConfigMixin with alias normalization (score_thresholdconf_threshold). If omitted, config.json is auto-detected adjacent to the model or script.

Fast Postprocessing (--fast-postprocess)

An opt-in, performance-oriented postprocessing path. By default the runner always uses the standard postprocessor; passing --fast-postprocess selects a faster variant only for the model families that provide one — other models silently keep the standard path, so the flag is always safe to add. The optimization skips work the standard path performs before thresholding (e.g. running sigmoid over the full anchor grid, taking argmax over every anchor, or upsampling each mask to the full input resolution).

There are two accuracy tiers:

TierOutput vs. standard pathModel families
ExactByte-identical (verified by parity unit tests)Object detection — YOLOv5 / YOLOv7, EfficientDet
ApproximateDiffers only at sub-pixel mask boundaries (binary masks agree at high IoU)Instance segmentation (YOLOv8-seg), YOLACT, SegFormer semantic segmentation
  • Exact tier (detection): the fast path gates anchors before the expensive decode. Because objectness/score gating is monotonic and the survivors are decoded with the same formulas, the detections are bit-for-bit identical to the standard path — it can be enabled with no accuracy cost.
  • Approximate tier (segmentation): the fast path crops and resizes masks at prototype (or output) resolution instead of upsampling each mask to the full input resolution first. This changes only sub-pixel boundary interpolation; on the profiled workloads the measured speedup is roughly 2.3x for instance segmentation and 4.9x for SegFormer-style semantic segmentation (the exact figure depends on the model, resolution, and host CPU).

When to enable. The benefit is largest when postprocessing dominates end-to-end latency — typically high-resolution feature grids or large anchor×class counts (dense detection heads, many-class detectors, high-resolution segmentation). Profile your own workload rather than assuming a fixed factor.

When to keep the default. The standard path is always the default and remains the accuracy reference. For the approximate (segmentation) tier, keep the standard path when exact mask boundaries matter.

# Object detection (exact tier) — identical results, faster decode
python src/python_example/object_detection/yolov7/yolov7_sync.py \
--model assets/models/YoloV7.dxnn --image sample/img/sample_street.jpg --fast-postprocess

Verification & Diagnostics

Numerical Verification (DXAPP_VERIFY)

Set DXAPP_VERIFY=1 to serialize all post-processing results to logs/verify/{model}.json for inspection and debugging.

Tensor Dump for Debugging (--dump-tensors)

Dumps raw input/output tensors as .npy files. On exception, tensors and a reason.txt are auto-dumped for debugging.

Model Validation (optional)

# Run NPU inference for all supported models
bash scripts/validate_models.sh --lang py

Environment Variables Reference

VariableDescription
DXAPP_SAVE_IMAGESave visualization to the specified file path (no --save required)
DXAPP_VERIFYWhen 1, dump JSON verification data

Supplementary Information

Component Relationships

The *_cpp_postprocess.py variants depend on the shared Python binding exposed from src/bindings/python/dx_postprocess/.

See also: DX-APP Pybind PostProcess Overview

Developer Resources