Merge branch 'stable'
This commit is contained in:
+51
-24
@@ -19,7 +19,7 @@ from typing import Tuple
|
||||
|
||||
from .Stitcher import Stitcher
|
||||
from .tracker import Tracker
|
||||
from .HHD import nHHD
|
||||
from .hhd import nHHD
|
||||
from . import configs
|
||||
from .get_depth import Contact3D
|
||||
from .backend_availability import (check_cupy_available, check_opencl_available)
|
||||
@@ -202,7 +202,7 @@ class Sensor:
|
||||
Capture and preprocess a frame.
|
||||
|
||||
Returns:
|
||||
np.ndarray: Processed grayscale image
|
||||
np.ndarray | None: Processed image, or None on capture failure.
|
||||
"""
|
||||
# Simple direct read - buffer size of 1 should minimize frame accumulation
|
||||
# Timing measurement helps identify if capture or processing is the bottleneck
|
||||
@@ -265,39 +265,66 @@ class Sensor:
|
||||
def detect_motion(self, threshold=6):
|
||||
|
||||
# detect motion by optical flow magnitude
|
||||
mag = np.linalg.norm(self.flow, axis=1)
|
||||
mag = np.linalg.norm(self.flow, axis=-1)
|
||||
# print(f"mag: {mag.max()}, {mag.min()}, {mag.mean()}")
|
||||
return mag.mean() > threshold
|
||||
|
||||
def compute_deformation(self, decompose=True, check_motion=False, threshold=6, tail_frames = 5):
|
||||
def compute_deformation(self, decompose=True, check_motion=True, threshold=6, tail_frames=10):
|
||||
"""
|
||||
Compute optical flow and decompose into force components.
|
||||
|
||||
Returns:
|
||||
np.ndarray: Optical flow field
|
||||
Compute optical flow and optionally decompose it into force components.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
decompose : bool
|
||||
If True, run HHD decomposition (`compute_hhd`) after flow computation.
|
||||
check_motion : bool
|
||||
If True, gate decomposition with `detect_motion(threshold)`. When motion
|
||||
falls below threshold, decomposition may still run for up to
|
||||
`tail_frames` additional frames to avoid abrupt force drop-off.
|
||||
threshold : float
|
||||
Motion-detection threshold on mean flow magnitude.
|
||||
tail_frames : int
|
||||
Number of extra non-motion frames allowed to keep running HHD when
|
||||
`check_motion=True`.
|
||||
|
||||
Returns
|
||||
-------
|
||||
bool | None
|
||||
- `True` : motion is currently detected (`check_motion=True`)
|
||||
- `False` : motion is currently not detected (`check_motion=True`)
|
||||
- `None` : motion gating disabled (`check_motion=False`)
|
||||
"""
|
||||
if self.img is None:
|
||||
raise Exception("Warning: Get image first")
|
||||
|
||||
|
||||
self.compute_flow()
|
||||
# self.compute_hhd()
|
||||
if check_motion:
|
||||
if self.detect_motion(threshold=threshold):
|
||||
self.tail_frames_count = 0
|
||||
self.compute_hhd()
|
||||
return True
|
||||
else:
|
||||
if self.tail_frames_count <= tail_frames:
|
||||
self.tail_frames_count +=1
|
||||
self.compute_hhd()
|
||||
return True
|
||||
return False
|
||||
else:
|
||||
if not check_motion:
|
||||
self.tail_frames_count = 0
|
||||
if decompose:
|
||||
self.compute_hhd()
|
||||
|
||||
return None
|
||||
# return True
|
||||
|
||||
is_motion = self.detect_motion(threshold=threshold)
|
||||
try:
|
||||
tail_frames = max(0, int(tail_frames))
|
||||
except (TypeError, ValueError):
|
||||
tail_frames = 0
|
||||
|
||||
if is_motion:
|
||||
self.tail_frames_count = 0
|
||||
if decompose:
|
||||
self.compute_hhd()
|
||||
return True
|
||||
|
||||
# No motion this frame. Keep HHD alive briefly if requested, but do not
|
||||
# report this as "motion detected".
|
||||
if decompose and self.tail_frames_count < tail_frames:
|
||||
self.tail_frames_count += 1
|
||||
self.compute_hhd()
|
||||
else:
|
||||
self.tail_frames_count = tail_frames
|
||||
|
||||
return False
|
||||
|
||||
def compute_flow(self):
|
||||
if self.img is None:
|
||||
|
||||
Reference in New Issue
Block a user