debug images
This commit is contained in:
parent
88ffea8807
commit
b8a51dc3cf
1 changed files with 109 additions and 5 deletions
|
|
@ -9,6 +9,20 @@ FIXES:
|
|||
- Row-start alignment now checks BOTH bottom and side edges
|
||||
- Larger overlap regions for better phase correlation
|
||||
- Better strip capture with more overlap
|
||||
|
||||
DEBUG BORDER COLORS (for debugging row 2 placement):
|
||||
=================================================
|
||||
In _detect_row_start_alignment():
|
||||
- WHITE (thick): Outline of where OLD ROW 1 content is located in mosaic
|
||||
- BLUE line: Y=0 line (where NEW ROW should start)
|
||||
- ORANGE line: Y=frame_height (bottom of new frame placement area)
|
||||
- CYAN: Mosaic region used for Y alignment comparison
|
||||
- MAGENTA: Where the new frame is EXPECTED to be placed
|
||||
- YELLOW: Mosaic region used for X alignment comparison
|
||||
|
||||
In _blend_horizontal_at_y (append_left):
|
||||
- RED (thick): Where strip WOULD have been placed (ORIGINAL position before alignment)
|
||||
- GREEN: Where strip was ACTUALLY placed (ADJUSTED position after alignment)
|
||||
"""
|
||||
|
||||
import cv2
|
||||
|
|
@ -209,6 +223,19 @@ class StitchingScanner:
|
|||
self.log(f" Row-start alignment: mosaic {mw}x{mh}, frame {fw}x{fh}")
|
||||
self.log(f" Old row 1 estimated start: Y={old_row1_start}")
|
||||
|
||||
# ========== DEBUG: Draw WHITE border showing where OLD ROW 1 content is ==========
|
||||
if old_row1_start >= 0:
|
||||
cv2.rectangle(self.mosaic,
|
||||
(0, old_row1_start),
|
||||
(mw, min(old_row1_start + fh, mh)),
|
||||
(255, 255, 255), 3) # WHITE - old row 1 location
|
||||
self.log(f" DEBUG: WHITE border - OLD ROW 1 location Y={old_row1_start}:{min(old_row1_start + fh, mh)}")
|
||||
|
||||
# ========== DEBUG: Draw BLUE line at Y=0 showing where NEW ROW starts ==========
|
||||
cv2.line(self.mosaic, (0, 0), (mw, 0), (255, 0, 0), 3) # BLUE line at Y=0
|
||||
cv2.line(self.mosaic, (0, fh), (mw, fh), (255, 100, 0), 2) # ORANGE line at Y=fh (bottom of new frame area)
|
||||
self.log(f" DEBUG: BLUE line at Y=0 (new row start), ORANGE line at Y={fh} (new frame bottom)")
|
||||
|
||||
vertical_overlap = min(200, fh // 3)
|
||||
min_overlap = 50
|
||||
|
||||
|
|
@ -230,6 +257,37 @@ class StitchingScanner:
|
|||
mosaic_top_of_old = self.mosaic[old_row1_start:old_row1_start + vertical_overlap,
|
||||
expected_x:x_end]
|
||||
|
||||
# ========== DEBUG: Save frame with comparison region marked ==========
|
||||
debug_frame = frame.copy()
|
||||
# CYAN border on frame showing the region being compared
|
||||
cv2.rectangle(debug_frame,
|
||||
(0, fh - vertical_overlap),
|
||||
(x_end - expected_x, fh),
|
||||
(255, 255, 0), 2) # CYAN - frame's bottom region used for Y comparison
|
||||
self.log(f" DEBUG: Frame comparison region: Y={fh - vertical_overlap}:{fh}")
|
||||
|
||||
# Save debug frame
|
||||
try:
|
||||
cv2.imwrite('/tmp/debug_frame_row2_start.png', debug_frame)
|
||||
self.log(f" DEBUG: Saved frame to /tmp/debug_frame_row2_start.png")
|
||||
except:
|
||||
pass
|
||||
|
||||
# ========== DEBUG: Draw borders on mosaic for comparison regions ==========
|
||||
# CYAN border: Mosaic region used for Y alignment comparison
|
||||
cv2.rectangle(self.mosaic,
|
||||
(expected_x, old_row1_start),
|
||||
(x_end, old_row1_start + vertical_overlap),
|
||||
(255, 255, 0), 2) # CYAN - mosaic comparison region for Y
|
||||
self.log(f" DEBUG: CYAN border - mosaic Y comparison region X={expected_x}:{x_end}, Y={old_row1_start}:{old_row1_start + vertical_overlap}")
|
||||
|
||||
# MAGENTA border: Where frame WOULD be placed (Y=0 to fh)
|
||||
cv2.rectangle(self.mosaic,
|
||||
(expected_x, 0),
|
||||
(min(expected_x + fw, mw), fh),
|
||||
(255, 0, 255), 2) # MAGENTA - expected frame position
|
||||
self.log(f" DEBUG: MAGENTA border - expected frame position X={expected_x}:{min(expected_x + fw, mw)}, Y=0:{fh}")
|
||||
|
||||
min_w = min(frame_bottom.shape[1], mosaic_top_of_old.shape[1])
|
||||
min_h = min(frame_bottom.shape[0], mosaic_top_of_old.shape[0])
|
||||
|
||||
|
|
@ -237,6 +295,14 @@ class StitchingScanner:
|
|||
frame_bottom = frame_bottom[:min_h, :min_w]
|
||||
mosaic_top_of_old = mosaic_top_of_old[:min_h, :min_w]
|
||||
|
||||
# ========== DEBUG: Save the comparison regions as images ==========
|
||||
try:
|
||||
cv2.imwrite('/tmp/debug_frame_bottom_region.png', frame_bottom)
|
||||
cv2.imwrite('/tmp/debug_mosaic_top_region.png', mosaic_top_of_old)
|
||||
self.log(f" DEBUG: Saved comparison regions to /tmp/debug_*.png")
|
||||
except:
|
||||
pass
|
||||
|
||||
# Detect displacement: how is frame_bottom shifted relative to mosaic_top_of_old?
|
||||
dx_v, dy_v, conf_v = self._detect_displacement_with_confidence(
|
||||
mosaic_top_of_old, frame_bottom)
|
||||
|
|
@ -267,6 +333,14 @@ class StitchingScanner:
|
|||
mosaic_edge = self.mosaic[y_start:y_end, mw - horizontal_overlap:mw]
|
||||
frame_edge = frame[:mosaic_edge.shape[0], fw - horizontal_overlap:fw]
|
||||
|
||||
# ========== DEBUG: Draw border for X comparison region ==========
|
||||
# YELLOW border: Mosaic region used for X alignment comparison
|
||||
cv2.rectangle(self.mosaic,
|
||||
(mw - horizontal_overlap, y_start),
|
||||
(mw, y_end),
|
||||
(0, 255, 255), 2) # YELLOW - mosaic comparison region for X
|
||||
self.log(f" DEBUG: YELLOW border - mosaic X comparison region X={mw - horizontal_overlap}:{mw}, Y={y_start}:{y_end}")
|
||||
|
||||
min_h = min(mosaic_edge.shape[0], frame_edge.shape[0])
|
||||
min_w = min(mosaic_edge.shape[1], frame_edge.shape[1])
|
||||
|
||||
|
|
@ -296,6 +370,13 @@ class StitchingScanner:
|
|||
mosaic_edge = self.mosaic[y_start:y_end, :horizontal_overlap]
|
||||
frame_edge = frame[:min(y_end - y_start, fh), :horizontal_overlap]
|
||||
|
||||
# ========== DEBUG: Draw border for X comparison region ==========
|
||||
cv2.rectangle(self.mosaic,
|
||||
(0, y_start),
|
||||
(horizontal_overlap, y_end),
|
||||
(0, 255, 255), 2) # YELLOW - mosaic comparison region for X
|
||||
self.log(f" DEBUG: YELLOW border - mosaic X comparison region X=0:{horizontal_overlap}, Y={y_start}:{y_end}")
|
||||
|
||||
min_h = min(mosaic_edge.shape[0], frame_edge.shape[0])
|
||||
min_w = min(mosaic_edge.shape[1], frame_edge.shape[1])
|
||||
|
||||
|
|
@ -428,11 +509,9 @@ class StitchingScanner:
|
|||
|
||||
# Detect displacement with confidence
|
||||
dx, dy, confidence = self._detect_displacement_with_confidence(mosaic_region, frame_region)
|
||||
|
||||
self.log(f"Displacement dx ({dx} dy {dy}) con {confidence})")
|
||||
|
||||
# Sanity check - reject large displacements
|
||||
max_adjust = 400 # Max pixels to adjust
|
||||
max_adjust = 50 # Max pixels to adjust
|
||||
if abs(dx) > max_adjust or abs(dy) > max_adjust:
|
||||
self.log(f"Strip alignment: displacement too large ({dx:.1f}, {dy:.1f}), ignoring")
|
||||
return offset
|
||||
|
|
@ -440,7 +519,7 @@ class StitchingScanner:
|
|||
offset.x_offset = dx
|
||||
offset.y_offset = dy
|
||||
offset.confidence = confidence
|
||||
offset.valid = True #confidence > 0.1 # Require minimum confidence
|
||||
offset.valid = confidence > 0.1 # Require minimum confidence
|
||||
|
||||
if offset.valid:
|
||||
self.log(f" Strip alignment: X={dx:.1f}, Y={dy:.1f}, conf={confidence:.3f}")
|
||||
|
|
@ -542,6 +621,10 @@ class StitchingScanner:
|
|||
if x_offset is None:
|
||||
x_offset = 0
|
||||
|
||||
# Store ORIGINAL position before alignment (for debug)
|
||||
original_x_offset = x_offset
|
||||
original_y_offset = y_offset
|
||||
|
||||
# Apply alignment offsets (continuous correction)
|
||||
x_offset = x_offset + int(round(alignment_x))
|
||||
y_offset_before = y_offset
|
||||
|
|
@ -550,7 +633,7 @@ class StitchingScanner:
|
|||
self.log(f" Y offset computation: {y_offset_before} - {int(round(alignment_y))} = {y_offset}")
|
||||
|
||||
# Clamp x_offset to valid range
|
||||
x_offset = 0 - min(x_offset, w_base)
|
||||
x_offset = max(0, min(x_offset, w_base))
|
||||
|
||||
# Handle strip cropping if y_offset is negative (strip protrudes above frame)
|
||||
strip_y_start = 0 # How much to crop from top of strip
|
||||
|
|
@ -580,6 +663,8 @@ class StitchingScanner:
|
|||
self.log(f" cumulative: X={self._cumulative_align_x:.1f}, Y={self._cumulative_align_y:.1f}")
|
||||
self.log(f" row_start_y: {self._row_start_y}")
|
||||
self.log(f" Strip crop: rows [{strip_y_start}:{strip_y_end}] -> height {h_cropped}")
|
||||
self.log(f" ORIGINAL position: X={original_x_offset}, Y={original_y_offset}")
|
||||
self.log(f" ADJUSTED position: X={x_offset}, Y={y_offset}")
|
||||
|
||||
# Result is same size as base (no expansion when going left)
|
||||
result = base.copy()
|
||||
|
|
@ -592,6 +677,17 @@ class StitchingScanner:
|
|||
self.log(f" Placing strip at X={strip_x_start}:{strip_x_end}, Y={y_offset}:{y_offset + h_cropped}")
|
||||
self.log(f" Strip cols to copy: {strip_cols_to_copy}")
|
||||
|
||||
# ========== DEBUG: Draw borders BEFORE placing strip ==========
|
||||
# RED border: Where strip WOULD have been placed (original position)
|
||||
orig_x_end = min(original_x_offset + w_strip, w_base)
|
||||
orig_y_end = min(original_y_offset + h_strip, h_base)
|
||||
if original_x_offset >= 0 and original_y_offset >= 0:
|
||||
cv2.rectangle(result,
|
||||
(original_x_offset, max(0, original_y_offset)),
|
||||
(orig_x_end, orig_y_end),
|
||||
(0, 0, 255), 3) # RED - original position
|
||||
self.log(f" DEBUG: RED border at original position X={original_x_offset}:{orig_x_end}, Y={original_y_offset}:{orig_y_end}")
|
||||
|
||||
# Step 1: Copy strip content (non-blend portion) at correct position
|
||||
# For LEFT scanning, blend is on the RIGHT side of the strip
|
||||
non_blend_end = strip_cols_to_copy - blend_w
|
||||
|
|
@ -612,6 +708,14 @@ class StitchingScanner:
|
|||
result[y_offset:y_offset + h_cropped, blend_x_start:blend_x_end] = blended
|
||||
self.log(f" Step 2: Blend zone at X={blend_x_start}:{blend_x_end}")
|
||||
|
||||
# ========== DEBUG: Draw border AFTER placing strip ==========
|
||||
# GREEN border: Where strip was ACTUALLY placed (adjusted position)
|
||||
cv2.rectangle(result,
|
||||
(strip_x_start, y_offset),
|
||||
(strip_x_end, y_offset + h_cropped),
|
||||
(0, 255, 0), 2) # GREEN - actual position
|
||||
self.log(f" DEBUG: GREEN border at actual position X={strip_x_start}:{strip_x_end}, Y={y_offset}:{y_offset + h_cropped}")
|
||||
|
||||
self.log(f" Final: Strip placed at X={strip_x_start}, Y={y_offset}, mosaic size unchanged: {w_base}x{h_base}")
|
||||
return result
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue