This guide provides practical examples and common workflows for using PyPTV effectively.
The test_cavity example is included with PyPTV and demonstrates a complete 4-camera PTV setup.
PyPTV uses a modern conda environment (environment.yml
) and separates tests into headless (tests/
) and GUI (tests_gui/
) categories. See the README for details.
cd tests/test_cavity
ls -la
You’ll find:
test_cavity/
├── parameters_Run1.yaml # Main parameter file
├── cal/ # Calibration data
│ ├── cam1.tif - cam4.tif # Calibration images
│ ├── *.ori # Calibration results
│ ├── *.addpar # Additional parameters
│ └── target_on_a_side.txt # Target coordinates
├── img/ # Image sequence
│ ├── cam1.10001 - cam1.10004
│ ├── cam2.10001 - cam2.10004
│ ├── cam3.10001 - cam3.10004
│ └── cam4.10001 - cam4.10004
└── plugins/ # Example plugins
├── ext_sequence_*.py
└── ext_tracker_*.py
cd tests/test_cavity
python -m pyptv
parameters_Run1.yaml
The test_cavity example demonstrates:
num_cams: 4
Starting a new PTV experiment from scratch.
mkdir my_experiment
cd my_experiment
# Create subdirectories
mkdir cal img results
# Copy template from test_cavity
cp tests/test_cavity/parameters_Run1.yaml parameters_my_experiment.yaml
Edit parameters_my_experiment.yaml
:
num_cams: 3 # Adjust for your camera count
sequence:
base_name:
- img/cam1.%d
- img/cam2.%d
- img/cam3.%d
first: 1
last: 100
cal_ori:
img_cal_name:
- cal/cam1_cal.tif
- cal/cam2_cal.tif
- cal/cam3_cal.tif
fixp_name: cal/my_target.txt
# Copy calibration images
cp /path/to/calibration/cam1.tif cal/cam1_cal.tif
cp /path/to/calibration/cam2.tif cal/cam2_cal.tif
cp /path/to/calibration/cam3.tif cal/cam3_cal.tif
# Copy image sequence
cp /path/to/sequence/cam1_* img/
cp /path/to/sequence/cam2_* img/
cp /path/to/sequence/cam3_* img/
# Create target coordinate file
cat > cal/my_target.txt << EOF
# X Y Z ID
-30.0 -30.0 0.0 1
30.0 -30.0 0.0 2
30.0 30.0 0.0 3
-30.0 30.0 0.0 4
EOF
Optimizing parameters for better tracking results.
Start with conservative detection parameters:
detect_plate:
gvth_1: 50 # Start higher, reduce if too few particles
gvth_2: 50
gvth_3: 50
min_npix: 20 # Minimum particle size
max_npix: 200 # Maximum particle size
Test detection on a representative frame:
Adjust tracking parameters based on your flow:
track:
# For slow flows
dvxmax: 5.0
dvxmin: -5.0
dvymax: 5.0
dvymin: -5.0
dvzmax: 2.0
dvzmin: -2.0
# For fast flows
dvxmax: 50.0
dvxmin: -50.0
# ... etc
For large measurement volumes or improved accuracy.
multi_planes:
n_planes: 3
plane_name:
- cal/plane_front
- cal/plane_middle
- cal/plane_back
PyPTV supports plugins for extended functionality.
Check available plugins in your parameter file:
plugins:
available_tracking:
- default
- ext_tracker_splitter # For splitter systems
available_sequence:
- default
- ext_sequence_rembg # Background removal
- ext_sequence_contour # Contour detection
selected_tracking: default
selected_sequence: default
To use background removal:
pip install rembg[cpu] # or rembg[gpu]
plugins:
selected_sequence: ext_sequence_rembg
For splitter-based stereo systems:
plugins:
selected_tracking: ext_tracker_splitter
ptv:
splitter: true
cal_ori:
cal_splitter: true
Symptoms: High residuals, tracking errors
Solutions:
Symptoms: Empty detection results
Solutions:
Symptoms: Broken trajectories, false matches
Solutions:
Symptoms: Slow processing, crashes
Solutions:
After tracking, analyze results with Python:
import numpy as np
import matplotlib.pyplot as plt
# Load tracking results (format depends on output)
# trajectories = load_trajectories('results/trajectories.txt')
# Example analysis
# velocities = compute_velocities(trajectories)
# plot_velocity_field(velocities)
# Compute flow statistics
# mean_velocity = np.mean(velocities, axis=0)
# velocity_fluctuations = velocities - mean_velocity
# turbulent_intensity = np.std(velocity_fluctuations, axis=0)
num_cams
, never n_img