Examples
This page provides complete code examples for common use cases.
Stereo Image Depth Estimation
Basic Example
import depthlib
# Load stereo pair and estimate depth
estimator = depthlib.StereoDepthEstimator(
left_source='./assets/stereo_pairs/im0.png',
right_source='./assets/stereo_pairs/im1.png',
downscale_factor=0.5
)
# Configure with camera parameters
estimator.configure_sgbm(
num_disp=280,
focal_length=3997.684,
baseline=0.193, # meters
doffs=131.111
)
# Estimate and visualize
disparity_px, depth_m = estimator.estimate_depth()
estimator.visualize_results()
With Statistics
import depthlib
import numpy as np
import time
# Setup
estimator = depthlib.StereoDepthEstimator(
left_source='./left.png',
right_source='./right.png',
downscale_factor=0.5
)
estimator.configure_sgbm(
num_disp=128,
focal_length=679.01,
baseline=0.5725
)
# Measure timing
start = time.time()
disparity_px, depth_m = estimator.estimate_depth()
elapsed_ms = (time.time() - start) * 1000
# Print statistics
print(f"Processing time: {elapsed_ms:.2f} ms")
# Disparity stats
valid_disp = disparity_px > 0
print(f"\n=== Disparity ===")
print(f"Range: {disparity_px[valid_disp].min():.1f} - {disparity_px[valid_disp].max():.1f} px")
print(f"Invalid pixels: {(~valid_disp).sum() / valid_disp.size * 100:.1f}%")
# Depth stats
if depth_m is not None:
valid_depth = np.isfinite(depth_m) & (depth_m > 0)
print(f"\n=== Depth ===")
print(f"Range: {depth_m[valid_depth].min():.2f} - {depth_m[valid_depth].max():.2f} m")
print(f"Mean: {depth_m[valid_depth].mean():.2f} m")
estimator.visualize_results()
Live Video Depth Estimation
USB Cameras
from depthlib import StereoDepthEstimatorVideo
# Two USB cameras (indices 0 and 1)
estimator = StereoDepthEstimatorVideo(
left_source=0,
right_source=1,
downscale_factor=0.5,
visualize_live=True,
fast_mode=True, # Faster processing
drop_frames=True, # Don't queue old frames
target_fps=30
)
estimator.configure_sgbm(
num_disp=128,
focal_length=679.01,
baseline=0.5725,
hole_filling=True
)
print("Press ESC to exit")
for depth_m in estimator.estimate_depth():
pass
Video Files
from depthlib import StereoDepthEstimatorVideo
estimator = StereoDepthEstimatorVideo(
left_source='./assets/left.mp4',
right_source='./assets/right.mp4',
downscale_factor=0.7,
visualize_live=True,
drop_frames=False, # Process all frames
target_fps=30
)
estimator.configure_sgbm(
num_disp=128,
focal_length=679.01,
baseline=0.5725
)
frame_count = 0
for depth_m in estimator.estimate_depth():
frame_count += 1
print(f"Processed {frame_count} frames")
Save Closest Distance
from depthlib import StereoDepthEstimatorVideo
import numpy as np
estimator = StereoDepthEstimatorVideo(
left_source='./left.mp4',
right_source='./right.mp4',
visualize_live=True
)
estimator.configure_sgbm(
num_disp=128,
focal_length=679.01,
baseline=0.5725
)
closest_distances = []
for depth_m in estimator.estimate_depth():
valid = np.isfinite(depth_m) & (depth_m > 0)
if valid.any():
closest = depth_m[valid].min()
closest_distances.append(closest)
print(f"Closest object: {closest:.2f} m")
# Analyze results
if closest_distances:
print(f"\n=== Summary ===")
print(f"Min distance seen: {min(closest_distances):.2f} m")
print(f"Max distance seen: {max(closest_distances):.2f} m")
Monocular Depth Estimation
Basic Example
import depthlib
model_path = "models/hub/models--depth-anything--Depth-Anything-V2-Base-hf/snapshots/b1958afc87fb45a9e3746cb387596094de553ed8"
estimator = depthlib.MonocularDepthEstimator(
model_path=model_path,
device='cuda',
downscale_factor=0.5
)
depth_map = estimator.estimate_depth('./image.png')
estimator.visualize_depth()
Batch Processing
import depthlib
import os
import time
model_path = "path/to/model"
image_dir = "./images"
output_dir = "./depth_maps"
os.makedirs(output_dir, exist_ok=True)
# Initialize once
estimator = depthlib.MonocularDepthEstimator(
model_path=model_path,
device='cuda',
downscale_factor=1.0
)
# Process all images
image_files = [f for f in os.listdir(image_dir) if f.endswith(('.png', '.jpg'))]
for filename in image_files:
image_path = os.path.join(image_dir, filename)
start = time.time()
depth_map = estimator.estimate_depth(image_path)
elapsed = (time.time() - start) * 1000
print(f"{filename}: {elapsed:.1f} ms")
# Save depth map
import numpy as np
output_path = os.path.join(output_dir, f"depth_{filename}")
np.save(output_path.replace('.png', '.npy').replace('.jpg', '.npy'), depth_map)
Custom Visualization
Side-by-Side Comparison
import depthlib
import matplotlib.pyplot as plt
import numpy as np
# Estimate depth
estimator = depthlib.StereoDepthEstimator(
left_source='./left.png',
right_source='./right.png'
)
estimator.configure_sgbm(num_disp=128, focal_length=1000, baseline=0.1)
disparity_px, depth_m = estimator.estimate_depth()
# Custom visualization
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
# Original image
import cv2
left = cv2.imread('./left.png')
left_rgb = cv2.cvtColor(left, cv2.COLOR_BGR2RGB)
axes[0].imshow(left_rgb)
axes[0].set_title('Left Image')
axes[0].axis('off')
# Disparity
valid_disp = disparity_px > 0
im1 = axes[1].imshow(disparity_px, cmap='jet',
vmin=np.percentile(disparity_px[valid_disp], 1),
vmax=np.percentile(disparity_px[valid_disp], 99))
axes[1].set_title('Disparity (pixels)')
axes[1].axis('off')
plt.colorbar(im1, ax=axes[1], fraction=0.046)
# Depth
if depth_m is not None:
valid_depth = np.isfinite(depth_m) & (depth_m > 0)
max_depth = np.percentile(depth_m[valid_depth], 95)
depth_display = np.clip(depth_m, 0, max_depth)
depth_display[~valid_depth] = max_depth
im2 = axes[2].imshow(depth_display, cmap='turbo_r', vmin=0, vmax=max_depth)
axes[2].set_title('Depth (meters)')
axes[2].axis('off')
plt.colorbar(im2, ax=axes[2], fraction=0.046)
plt.tight_layout()
plt.savefig('depth_comparison.png', dpi=150)
plt.show()
Parameter Tuning
Finding Optimal num_disp
import depthlib
import numpy as np
import matplotlib.pyplot as plt
# Test different num_disp values
num_disp_values = [64, 128, 192, 256]
results = []
for nd in num_disp_values:
estimator = depthlib.StereoDepthEstimator(
left_source='./left.png',
right_source='./right.png',
downscale_factor=0.5
)
estimator.configure_sgbm(
num_disp=nd,
focal_length=1000,
baseline=0.1
)
import time
start = time.time()
disparity_px, depth_m = estimator.estimate_depth()
elapsed = (time.time() - start) * 1000
valid = disparity_px > 0
coverage = valid.sum() / valid.size * 100
results.append({
'num_disp': nd,
'time_ms': elapsed,
'coverage': coverage
})
print(f"num_disp={nd}: {elapsed:.1f}ms, coverage={coverage:.1f}%")
# Plot results
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))
nds = [r['num_disp'] for r in results]
ax1.bar(nds, [r['time_ms'] for r in results])
ax1.set_xlabel('num_disp')
ax1.set_ylabel('Time (ms)')
ax1.set_title('Processing Time')
ax2.bar(nds, [r['coverage'] for r in results])
ax2.set_xlabel('num_disp')
ax2.set_ylabel('Valid pixels (%)')
ax2.set_title('Disparity Coverage')
plt.tight_layout()
plt.show()
Error Handling
Robust Stereo Estimation
import depthlib
import numpy as np
def estimate_depth_safe(left_path, right_path, **sgbm_params):
"""Estimate depth with error handling."""
try:
estimator = depthlib.StereoDepthEstimator(
left_source=left_path,
right_source=right_path,
downscale_factor=0.5
)
estimator.configure_sgbm(**sgbm_params)
disparity_px, depth_m = estimator.estimate_depth()
# Validate results
valid_disp = disparity_px > 0
if valid_disp.sum() < 0.1 * valid_disp.size:
print("Warning: Less than 10% valid disparities")
return None, None
return disparity_px, depth_m
except FileNotFoundError as e:
print(f"Image not found: {e}")
return None, None
except ValueError as e:
print(f"Invalid parameter: {e}")
return None, None
except Exception as e:
print(f"Unexpected error: {e}")
return None, None
# Usage
disparity, depth = estimate_depth_safe(
'./left.png',
'./right.png',
num_disp=128,
focal_length=1000,
baseline=0.1
)
if depth is not None:
print("Success!")
Integration Example
Obstacle Detection
from depthlib import StereoDepthEstimatorVideo
import numpy as np
DANGER_DISTANCE = 1.0 # meters
WARNING_DISTANCE = 3.0 # meters
estimator = StereoDepthEstimatorVideo(
left_source=0,
right_source=1,
visualize_live=True,
fast_mode=True
)
estimator.configure_sgbm(
num_disp=128,
focal_length=679.01,
baseline=0.5725
)
print("Obstacle Detection Running... (ESC to exit)")
for depth_m in estimator.estimate_depth():
valid = np.isfinite(depth_m) & (depth_m > 0)
if valid.any():
closest = depth_m[valid].min()
if closest < DANGER_DISTANCE:
print(f"⚠️ DANGER! Object at {closest:.2f}m")
elif closest < WARNING_DISTANCE:
print(f"⚡ Warning: Object at {closest:.2f}m")