Fixing mosaic

This commit is contained in:
2ManyProjects 2026-01-08 00:41:30 -06:00
parent 5cf6ec0794
commit 4e11c851e7

View file

@ -41,6 +41,8 @@ class StitchState:
direction: str = ''
cumulative_x: float = 0.0
cumulative_y: float = 0.0
current_x: float = 0.0
current_y: float = 0.0
last_displacement: Tuple[float, float] = (0.0, 0.0)
current_row: int = 0
total_rows: int = 0
@ -194,6 +196,49 @@ class StitchingScanner:
result[:, w_strip - blend_w:w_strip] = blended
result[:, w_strip:] = base[:, blend_w:]
return result
def _blend_vertical_at_x(self, base: np.ndarray, strip: np.ndarray,
blend_height: int, append_below: bool) -> np.ndarray:
mh, mw = base.shape[:2]
sh, sw = strip.shape[:2]
# Match widths
if sw > mw:
strip = strip[:, :mw]
elif sw < mw:
pad = np.zeros((sh, mw - sw, 3), dtype=np.uint8)
strip = np.hstack([strip, pad])
blend_h = min(blend_height, sh, mh)
if blend_h <= 0:
if append_below:
return np.vstack([base, strip])
return np.vstack([strip, base])
if append_below:
alpha = np.linspace(1, 0, blend_h, dtype=np.float32)[:, np.newaxis, np.newaxis]
base_overlap = base[-blend_h:].astype(np.float32)
strip_overlap = strip[:blend_h].astype(np.float32)
blended = (base_overlap * alpha + strip_overlap * (1 - alpha)).astype(np.uint8)
result_h = mh + sh - blend_h
result = np.zeros((result_h, mw, 3), dtype=np.uint8)
result[:mh - blend_h] = base[:-blend_h]
result[mh - blend_h:mh] = blended
result[mh:] = strip[blend_h:]
return result
else:
alpha = np.linspace(0, 1, blend_h, dtype=np.float32)[:, np.newaxis, np.newaxis]
strip_overlap = strip[-blend_h:].astype(np.float32)
base_overlap = base[:blend_h].astype(np.float32)
blended = (strip_overlap * (1 - alpha) + base_overlap * alpha).astype(np.uint8)
result_h = mh + sh - blend_h
result = np.zeros((result_h, mw, 3), dtype=np.uint8)
result[:sh - blend_h] = strip[:-blend_h]
result[sh - blend_h:sh] = blended
result[sh:] = base[blend_h:]
return result
def _blend_vertical(self, base: np.ndarray, strip: np.ndarray,
blend_height: int, append_below: bool) -> np.ndarray:
@ -291,13 +336,13 @@ class StitchingScanner:
if direction == ScanDirection.DOWN:
strip_end = min(h, append_height + BLEND_WIDTH)
new_strip = frame[:strip_end:, :]
self.mosaic = self._blend_vertical(
self.mosaic, new_strip, BLEND_WIDTH, append_below=False)
self.mosaic = self._blend_vertical_at_x(
self.mosaic, new_strip, BLEND_WIDTH, append_below=False, x_offset=int(self.state.current_x))
else:
strip_start = max(0, h - append_height - BLEND_WIDTH)
new_strip = frame[:strip_start, :]
self.mosaic = self._blend_vertical(
self.mosaic, new_strip, BLEND_WIDTH, append_below=True)
self.mosaic = self._blend_vertical_at_x(
self.mosaic, new_strip, BLEND_WIDTH, append_below=True, x_offset=int(self.state.current_x))
self._displacement_since_append_x = 0.0
self._displacement_since_append_y = fractional_remainder
@ -438,6 +483,7 @@ class StitchingScanner:
threshold_pixels = h * self.config.displacement_threshold
max_dim = self.config.max_mosaic_height
current_dim = lambda: self.state.mosaic_height
total_x = 0 if direction == ScanDirection.DOWN else self.config.max_mosaic_width
start_cmd = 'S' if direction == ScanDirection.DOWN else 'N'
stop_cmd = 's' if direction == ScanDirection.DOWN else 'n'
@ -449,8 +495,11 @@ class StitchingScanner:
no_movement_count = 0
max_no_movement = 50
stop_reason = 'stopped'
total_x = 0
if direction == ScanDirection.RIGHT:
self.state.current_x = self.state.mosaic_width - w # At right edge
elif direction == ScanDirection.LEFT:
self.state.current_x = 0
while self.running and not self.paused:
if time.time() - start_time > self.config.max_scan_time:
self.log("Scan timeout")
@ -479,6 +528,7 @@ class StitchingScanner:
self._displacement_since_append_x += dx
self._displacement_since_append_y += dy
total_x += dx
self.state.current_x += dx
with self._state_lock:
self.state.cumulative_x = self._displacement_since_append_x
@ -556,6 +606,7 @@ class StitchingScanner:
self._displacement_since_append_y += dy
total_y += dy
self.state.current_y += dy
with self._state_lock:
self.state.cumulative_y = total_y