update using angle-based unwarp for display but projection for printing
This commit is contained in:
+34
-7
@@ -85,6 +85,8 @@ class Sensor:
|
||||
if vid_src is None:
|
||||
raise Exception("User must specify a video source.")
|
||||
|
||||
self._external_only = isinstance(vid_src, str) and vid_src.lower() == "external"
|
||||
|
||||
# Store settings
|
||||
self.vid_src = vid_src
|
||||
self.isstitch = isstitch
|
||||
@@ -171,7 +173,7 @@ class Sensor:
|
||||
self._is_live_camera = (
|
||||
isinstance(self.vid_src, int)
|
||||
or (isinstance(self.vid_src, str) and self.vid_src.startswith("/dev/video"))
|
||||
)
|
||||
) and not self._external_only
|
||||
self._capture_thread = None
|
||||
self._capture_running = False
|
||||
self._latest_frame = None
|
||||
@@ -179,8 +181,13 @@ class Sensor:
|
||||
self._last_consumed_seq = -1
|
||||
self._latest_frame_lock = threading.Lock()
|
||||
|
||||
# Setup video capture
|
||||
self._open_video_source(override, box)
|
||||
# Setup video capture unless this sensor is fed externally.
|
||||
if self._external_only:
|
||||
self.stitch_valid = False
|
||||
if self.verbose:
|
||||
print("Sensor initialized in external-frame mode.")
|
||||
else:
|
||||
self._open_video_source(override, box)
|
||||
|
||||
if self.verbose:
|
||||
print(f" Video source: {vid_src}")
|
||||
@@ -197,9 +204,19 @@ class Sensor:
|
||||
# Public API - Core Methods (Most Frequently Used)
|
||||
# =========================================================================
|
||||
|
||||
def get_img(self):
|
||||
def get_img(self, frame=None, already_processed=False):
|
||||
"""
|
||||
Capture and preprocess a frame.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
frame : np.ndarray | None
|
||||
Optional externally supplied frame. When provided, the sensor skips
|
||||
reading from its own video source and uses this frame instead.
|
||||
already_processed : bool
|
||||
If True, treat `frame` as the final BGR tactile image and skip the
|
||||
configured frame processor. This is useful for pipelines that
|
||||
generate a derived image, such as an unrolled tactile view.
|
||||
|
||||
Returns:
|
||||
np.ndarray | None: Processed image, or None on capture failure.
|
||||
@@ -207,7 +224,10 @@ class Sensor:
|
||||
# Simple direct read - buffer size of 1 should minimize frame accumulation
|
||||
# Timing measurement helps identify if capture or processing is the bottleneck
|
||||
t_capture_start = time.perf_counter()
|
||||
ret, frame = self._read_frame()
|
||||
if frame is None:
|
||||
ret, frame = self._read_frame()
|
||||
else:
|
||||
ret = frame is not None
|
||||
t_capture_end = time.perf_counter()
|
||||
self._last_capture_time = t_capture_end - t_capture_start
|
||||
|
||||
@@ -218,8 +238,15 @@ class Sensor:
|
||||
# Start processing timing
|
||||
t_processing_start = time.perf_counter()
|
||||
|
||||
self.frame = frame
|
||||
img_bgr = self.frame_processor.process(frame)
|
||||
self.frame = frame.copy() if isinstance(frame, np.ndarray) else frame
|
||||
if already_processed:
|
||||
img_bgr = frame
|
||||
if img_bgr.ndim == 2:
|
||||
img_bgr = cv2.cvtColor(img_bgr, cv2.COLOR_GRAY2BGR)
|
||||
elif img_bgr.ndim == 3 and img_bgr.shape[2] == 1:
|
||||
img_bgr = cv2.cvtColor(img_bgr[:, :, 0], cv2.COLOR_GRAY2BGR)
|
||||
else:
|
||||
img_bgr = self.frame_processor.process(frame)
|
||||
t_after_extract = time.perf_counter()
|
||||
|
||||
t_after_stitch = time.perf_counter()
|
||||
|
||||
Reference in New Issue
Block a user