tuned pipeline to 60 fps
This commit is contained in:
@@ -14,6 +14,7 @@ import time
|
||||
import cv2
|
||||
import numpy as np
|
||||
import orisys
|
||||
from orisys.configs import load_config
|
||||
from orisys.frame_processors import UVUnrollFrameProcessor
|
||||
from orisys.unroll import (
|
||||
barycentric_grid,
|
||||
@@ -23,6 +24,9 @@ from orisys.unroll import (
|
||||
load_calib_json,
|
||||
load_exported_data,
|
||||
recommend_edge_expand,
|
||||
resolve_uv_runtime_sizes,
|
||||
scale_camera_geometry,
|
||||
scaled_map_cache_path,
|
||||
uv_triangle_to_image,
|
||||
)
|
||||
|
||||
@@ -304,12 +308,18 @@ def open_source(video_path, camera_id):
|
||||
|
||||
PERF_TUNING_EPILOG = """
|
||||
Performance tuning (config JSON + CLI):
|
||||
tracker.dis_preset medium -> fast/ultrafast faster DIS optical flow
|
||||
tracker.loop_closure_interval 1 -> 3-5 fewer loop-closure remaps
|
||||
tracker.hhd_downsample 3 -> 4 smaller HHD Poisson grid
|
||||
contact.denoise_sigma 12 -> 6 or 0 faster FoE contact step
|
||||
--masked_poisson_solver sparse vs capfft benchmark HHD solve time
|
||||
--no-viz skip dashboard/imshow ~20 ms/frame savings
|
||||
camera.resolution_stitch [280, 300] UV output + SDK flow/HHD grid
|
||||
camera.source_scale 0.4 shrink source before uv_prep/remap
|
||||
tracker.dis_preset medium -> fast faster DIS optical flow
|
||||
tracker.hhd_downsample 5 -> 4 smaller HHD Poisson grid
|
||||
contact.denoise_sigma 12 -> 6 or 0 faster FoE contact step
|
||||
--source_scale 0.4 override config source scale
|
||||
--masked_poisson_solver sparse vs capfft benchmark HHD solve time
|
||||
--no-viz skip dashboard ~20 ms/frame savings
|
||||
|
||||
Recommended dd02-ov fast profile:
|
||||
resolution_stitch [280, 300], source_scale 0.4, hhd_downsample 5
|
||||
Delete or rename stale unroll_map_uv.npz after changing output scale.
|
||||
"""
|
||||
|
||||
|
||||
@@ -349,6 +359,32 @@ def configure_masked_poisson(sensor, args):
|
||||
sensor.masked_poisson_reg = args.masked_poisson_reg
|
||||
|
||||
|
||||
def resolve_runtime_geometry(args):
|
||||
"""Apply config defaults and optional source-scale to UV/camera geometry."""
|
||||
sdk_config = load_config(args.sdk_config)
|
||||
camera_config = sdk_config.get("camera", {})
|
||||
out_width, out_height, source_scale = resolve_uv_runtime_sizes(
|
||||
camera_config,
|
||||
out_width=args.out_width,
|
||||
out_height=args.out_height,
|
||||
source_scale=args.source_scale,
|
||||
)
|
||||
stitch = camera_config.get("resolution_stitch")
|
||||
if stitch and len(stitch) >= 2 and (int(stitch[0]) != out_width or int(stitch[1]) != out_height):
|
||||
print(
|
||||
"Warning: UV output "
|
||||
f"{out_width}x{out_height} differs from resolution_stitch "
|
||||
f"{int(stitch[0])}x{int(stitch[1])} in {args.sdk_config}; "
|
||||
"Sensor.get_img will resize again."
|
||||
)
|
||||
|
||||
args.out_width = out_width
|
||||
args.out_height = out_height
|
||||
args.source_scale = source_scale
|
||||
args.map_cache = scaled_map_cache_path(args.map_cache, source_scale)
|
||||
return sdk_config, camera_config
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Real-time UV-based finger unrolling",
|
||||
@@ -362,8 +398,14 @@ def main():
|
||||
# With a 12% UV edge band on each side, only about 76% of each axis is the
|
||||
# lower-distortion middle region. Use a slightly larger full remap so the
|
||||
# useful center keeps roughly the same sampling density as the prior 506x550.
|
||||
parser.add_argument("--out_width", type=int, default=504)
|
||||
parser.add_argument("--out_height", type=int, default=506)
|
||||
parser.add_argument("--out_width", type=int, default=None, help="UV flatten width (default: camera.resolution_stitch in sdk config)")
|
||||
parser.add_argument("--out_height", type=int, default=None, help="UV flatten height (default: camera.resolution_stitch in sdk config)")
|
||||
parser.add_argument(
|
||||
"--source_scale",
|
||||
type=float,
|
||||
default=None,
|
||||
help="Resize live source to this fraction before uv_prep/uv_remap; scales K accordingly (default: camera.source_scale or work4[3] in sdk config, else 1.0)",
|
||||
)
|
||||
parser.add_argument("--camera_id", type=int, default=0)
|
||||
parser.add_argument("--video", help="Video file path (overrides camera)")
|
||||
parser.add_argument("--map_cache", default="unroll_map_uv.npz")
|
||||
@@ -386,6 +428,7 @@ def main():
|
||||
help="Skip OpenCV dashboard; print forces and benchmark timings only",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
_, camera_config = resolve_runtime_geometry(args)
|
||||
|
||||
print("[benchmark] Startup timing:")
|
||||
data = benchmark_step("load_exported_data", load_exported_data, args.mesh, args.intrinsics_path, args.pose)
|
||||
@@ -429,15 +472,29 @@ def main():
|
||||
|
||||
if args.calib:
|
||||
source_K, dist_coeffs, img_size = benchmark_step("load_calib_json", load_calib_json, args.calib)
|
||||
source_width, source_height = img_size
|
||||
print(f"Calibration loaded. Live image size: {(source_width, source_height)}")
|
||||
native_width, native_height = img_size
|
||||
print(f"Calibration loaded. Live image size: {(native_width, native_height)}")
|
||||
else:
|
||||
source_K = data["K"]
|
||||
dist_coeffs = None
|
||||
source_width = data["width"]
|
||||
source_height = data["height"]
|
||||
native_width = data["width"]
|
||||
native_height = data["height"]
|
||||
print("No calibration file provided; using exported intrinsics for projection.")
|
||||
|
||||
source_K, source_width, source_height = scale_camera_geometry(
|
||||
source_K,
|
||||
native_width,
|
||||
native_height,
|
||||
args.source_scale,
|
||||
)
|
||||
print(
|
||||
"UV runtime geometry: "
|
||||
f"native={native_width}x{native_height}, "
|
||||
f"source={source_width}x{source_height} (scale={args.source_scale:g}), "
|
||||
f"output={args.out_width}x{args.out_height}, "
|
||||
f"map_cache={args.map_cache}"
|
||||
)
|
||||
|
||||
domain = benchmark_step(
|
||||
"build_or_load_domain",
|
||||
build_or_load_domain,
|
||||
@@ -454,6 +511,7 @@ def main():
|
||||
edge_band=args.edge_band,
|
||||
edge_expand=edge_expand,
|
||||
include_surface=True,
|
||||
source_scale=args.source_scale,
|
||||
)
|
||||
remap = domain.remap
|
||||
remap.ensure_fast_maps()
|
||||
@@ -495,8 +553,8 @@ def main():
|
||||
print("Cannot open camera/video source")
|
||||
sys.exit(1)
|
||||
|
||||
cap.set(cv2.CAP_PROP_FRAME_WIDTH, source_width)
|
||||
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, source_height)
|
||||
cap.set(cv2.CAP_PROP_FRAME_WIDTH, native_width)
|
||||
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, native_height)
|
||||
|
||||
sensor = benchmark_step(
|
||||
"sensor_init",
|
||||
@@ -600,8 +658,8 @@ def main():
|
||||
arrows = orisys.util.draw_arrows(
|
||||
img,
|
||||
flow,
|
||||
threshold=1,
|
||||
grid_spacing=15,
|
||||
threshold=0.4,
|
||||
grid_spacing=10,
|
||||
arrow_scale=1.0,
|
||||
)
|
||||
contact_img = orisys.util.draw_contact(img, contour, centroid)
|
||||
|
||||
Reference in New Issue
Block a user