tune for dq6a to reach 30 fps for 2 sensors

This commit is contained in:
radxa-d6a
2026-04-02 16:44:02 +08:00
parent 51c259e523
commit 80e951d6cd
15 changed files with 474 additions and 70 deletions
+37 -21
View File
@@ -60,7 +60,8 @@ class Sensor:
# =========================================================================
def __init__(self, vid_src, cuda=True, isstitch=True, verbose=True, debug=False,
config_name="prototype", cal_path=None, override=False, box=None, mirror=True, backend='auto'):
config_name="prototype", cal_path=None, override=False, box=None, mirror=True,
backend='auto'):
"""
Initialize Sensor with video source and configuration.
@@ -78,6 +79,8 @@ class Sensor:
"cupy": Use CuPy for GPU acceleration
"opencl": Use OpenCL for GPU acceleration
"cpu": Use CPU for computation
hhd_downsample: Downsample factor for flow field before HHD (default: 1, no downsampling).
Factor of 2 halves each dimension, giving ~4x speedup in Poisson solve.
"""
self.CUPY_AVAILABLE = check_cupy_available()
@@ -147,7 +150,12 @@ class Sensor:
self.__tracker = Tracker(adaptive=True, cuda=cuda, verbose=self.verbose, config_tracker=self.__config_tracker)
self.__contact3d = Contact3D(config_contact=self.__config_contact, verbose=self.verbose)
self.__hhd = None
self.poisson_backend = backend
# cfg_ds = self.__config_tracker.get("hhd_downsample", None)
# self._hhd_downsample = max(1, int(cfg_ds if cfg_ds is not None else hhd_downsample))
self._hhd_downsample = self.__config_tracker.get("hhd_downsample", None)
self._hhd_grid_shape = None
cfg_backend = self.__config_tracker.get("backend", None)
self.poisson_backend = cfg_backend if cfg_backend is not None else backend
self._use_pyav = False
self._av_container = None
self._av_stream = None
@@ -287,28 +295,36 @@ class Sensor:
flow = self.flow
if flow is None:
raise Exception("Warning: Compute flow first")
# Initialize HHD solver
if self.__hhd is None:
self.__hhd = nHHD(cuda=self.cuda, grid=flow.shape[:2], spacings=(18, 18), poisson_backend=self.poisson_backend, debug=self.debug)
# Force computation
# When OpenCL backend is selected, use host force path to ensure
# Poisson solve goes through PoissonSolver.solve_opencl().
_, forces = self.__hhd.get_force(flow)
# if self.poisson_backend == 'opencl':
# _, forces = self.__hhd.get_force_host(flow)
# elif self.cuda and self.CUPY_AVAILABLE:
# _, forces = self.__hhd.get_force_gpu_v2(flow)
# else:
# _, forces = self.__hhd.get_force_host(flow)
orig_h, orig_w = flow.shape[:2]
k = self._hhd_downsample
if k > 1:
ds_w = max(1, orig_w // k)
ds_h = max(1, orig_h // k)
flow_ds = cv2.resize(flow, (ds_w, ds_h), interpolation=cv2.INTER_AREA)
else:
flow_ds = flow
ds_shape = flow_ds.shape[:2]
if self.__hhd is None or self._hhd_grid_shape != ds_shape:
spacings = (18 * k, 18 * k)
self.__hhd = nHHD(cuda=self.cuda, grid=ds_shape, spacings=spacings, poisson_backend=self.poisson_backend, debug=self.debug)
self._hhd_grid_shape = ds_shape
_, forces = self.__hhd.get_force(flow_ds)
self.fnormal, self.fshearx, self.fsheary, self.ftor = forces
# Get components
self.vnormal = self.__hhd.get_normal()
self.vshear = self.__hhd.get_shear()
# Update state
vnormal_ds = self.__hhd.get_normal()
vshear_ds = self.__hhd.get_shear()
if k > 1:
self.vnormal = cv2.resize(vnormal_ds, (orig_w, orig_h), interpolation=cv2.INTER_LINEAR)
self.vshear = cv2.resize(vshear_ds, (orig_w, orig_h), interpolation=cv2.INTER_LINEAR)
else:
self.vnormal = vnormal_ds
self.vshear = vshear_ds
self.compute_deformation_valid = True
return True