From 961e828adc05589bcf964b26447656e5508a149f Mon Sep 17 00:00:00 2001 From: 2ManyProjects Date: Thu, 8 Jan 2026 00:49:02 -0600 Subject: [PATCH] X offset --- src/stitching_scanner.py | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/src/stitching_scanner.py b/src/stitching_scanner.py index 471ae0c..9179ad8 100644 --- a/src/stitching_scanner.py +++ b/src/stitching_scanner.py @@ -196,50 +196,56 @@ 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: + blend_height: int, append_below: bool, + x_offset: int = 0) -> 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]) + # Clamp x_offset to valid range + x_offset = max(0, min(x_offset, mw - 1)) + # Calculate how much of strip fits in mosaic + available_width = mw - x_offset + strip_width = min(sw, available_width) + + # Create full-width strip with strip placed at x_offset + full_strip = np.zeros((sh, mw, 3), dtype=np.uint8) + full_strip[:, x_offset:x_offset + strip_width] = strip[:, :strip_width] + + # Now blend using existing logic blend_h = min(blend_height, sh, mh) if blend_h <= 0: if append_below: - return np.vstack([base, strip]) - return np.vstack([strip, base]) + return np.vstack([base, full_strip]) + return np.vstack([full_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) + strip_overlap = full_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:] + result[mh:] = full_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) + strip_overlap = full_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] = full_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: mh, mw = base.shape[:2]