jslmmfboom-coder commited on
Commit
8ab04fc
·
1 Parent(s): 31d7432

Fix: remove rect boxes from vis, pass per-image crop_offset, only draw lines

Browse files
Files changed (3) hide show
  1. app.py +11 -39
  2. module/config.py +1 -1
  3. module/dinov2_utils.py +4 -0
app.py CHANGED
@@ -533,11 +533,11 @@ def _build_complex_visualization(log_entry, patch_info):
533
  q_orig_size = patch_info.get('query_image_size', (orig_w1, orig_h1))
534
  h_orig_size = patch_info.get('hist_image_size', (orig_w2, orig_h2))
535
 
536
- # CenterCrop 偏移和 Resize 缩放
537
- q_crop = patch_info.get('crop_offset', (0, 0))
538
- h_crop = patch_info.get('crop_offset', (0, 0))
539
- q_resize = patch_info.get('resize_size', (518, 518))
540
- h_resize = patch_info.get('resize_size', (518, 518))
541
 
542
  q_n_h, q_n_w = q_grid
543
  h_n_h, h_n_w = h_grid
@@ -553,11 +553,8 @@ def _build_complex_visualization(log_entry, patch_info):
553
  canvas[:h1, :w1] = img1_disp
554
  canvas[:h2, w1+gap:] = img2_disp
555
 
556
- def _patch_to_orig_coords(patch_idx, n_w, n_h, crop_offset, scale_resize, display_scale, orig_size, is_right, gap_offset):
557
- """将 patch 索引转换为画布上的像素坐标
558
-
559
- 步骤:patch_idx → (row,col) → 518x518像素 → 加crop偏移 → 除缩放 → 原图像素 → 乘display_scale → 画布坐标
560
- """
561
  row = patch_idx // n_w
562
  col = patch_idx % n_w
563
 
@@ -580,44 +577,19 @@ def _build_complex_visualization(log_entry, patch_info):
580
  if is_right:
581
  cx_canvas += gap_offset
582
 
583
- # patch 在原图上的覆盖区域(用于画矩形)
584
- x1_518 = col * patch_size + crop_offset[0]
585
- y1_518 = row * patch_size + crop_offset[1]
586
- x1_orig = x1_518 / scale_resize
587
- y1_orig = y1_518 / scale_resize
588
- x2_orig = (col + 1) * patch_size + crop_offset[0] / scale_resize
589
- y2_orig = (row + 1) * patch_size + crop_offset[1] / scale_resize
590
-
591
- rx1 = int(x1_orig * display_scale)
592
- ry1 = int(y1_orig * display_scale)
593
- rx2 = int(x2_orig * display_scale)
594
- ry2 = int(y2_orig * display_scale)
595
-
596
- if is_right:
597
- rx1 += gap_offset
598
- rx2 += gap_offset
599
-
600
- return cx_canvas, cy_canvas, rx1, ry1, rx2, ry2
601
 
602
  for qi, hi, sim in matches:
603
- q_cx, q_cy, q_rx1, q_ry1, q_rx2, q_ry2 = \
604
- _patch_to_orig_coords(qi, q_n_w, q_n_h, q_crop, q_scale_resize, scale1, q_orig_size, False, 0)
605
- h_cx, h_cy, h_rx1, h_ry1, h_rx2, h_ry2 = \
606
- _patch_to_orig_coords(hi, h_n_w, h_n_h, h_crop, h_scale_resize, scale2, h_orig_size, True, w1 + gap)
607
 
608
  # 颜色:相似度越高越绿,越低越黄
609
  intensity = min(1.0, max(0.0, (sim - 0.3) / 0.7))
610
  color = (0, int(200 * intensity + 55), int(255 * (1 - intensity)))
611
 
612
- # 绘制连线
613
  cv2.line(canvas, (q_cx, q_cy), (h_cx, h_cy), color, 1, cv2.LINE_AA)
614
 
615
- # 绘制 patch 矩形(限制在图片范围内)
616
- cv2.rectangle(canvas, (max(q_rx1, 0), max(q_ry1, 0)),
617
- (min(q_rx2, w1-1), min(q_ry2, h1-1)), color, 1)
618
- cv2.rectangle(canvas, (max(h_rx1, w1+gap), max(h_ry1, 0)),
619
- (min(h_rx2, w1+gap+w2-1), min(h_ry2, h2-1)), color, 1)
620
-
621
  n_matches = len(matches)
622
  avg_sim = sum(s for _, _, s in matches) / max(n_matches, 1)
623
  cv2.putText(canvas, 'Query', (10, 25), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0,0,0), 2)
 
533
  q_orig_size = patch_info.get('query_image_size', (orig_w1, orig_h1))
534
  h_orig_size = patch_info.get('hist_image_size', (orig_w2, orig_h2))
535
 
536
+ # CenterCrop 偏移和 Resize 缩放(query 和 hist 各自独立)
537
+ q_crop = patch_info.get('query_crop_offset', (0, 0))
538
+ h_crop = patch_info.get('hist_crop_offset', (0, 0))
539
+ q_resize = patch_info.get('query_resize_size', (518, 518))
540
+ h_resize = patch_info.get('hist_resize_size', (518, 518))
541
 
542
  q_n_h, q_n_w = q_grid
543
  h_n_h, h_n_w = h_grid
 
553
  canvas[:h1, :w1] = img1_disp
554
  canvas[:h2, w1+gap:] = img2_disp
555
 
556
+ def _patch_to_center(patch_idx, n_w, crop_offset, scale_resize, display_scale, is_right, gap_offset):
557
+ """将 patch 索引转换为画布上的中心点像素坐标"""
 
 
 
558
  row = patch_idx // n_w
559
  col = patch_idx % n_w
560
 
 
577
  if is_right:
578
  cx_canvas += gap_offset
579
 
580
+ return cx_canvas, cy_canvas
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
581
 
582
  for qi, hi, sim in matches:
583
+ q_cx, q_cy = _patch_to_center(qi, q_n_w, q_crop, q_scale_resize, scale1, False, 0)
584
+ h_cx, h_cy = _patch_to_center(hi, h_n_w, h_crop, h_scale_resize, scale2, True, w1 + gap)
 
 
585
 
586
  # 颜色:相似度越高越绿,越低越黄
587
  intensity = min(1.0, max(0.0, (sim - 0.3) / 0.7))
588
  color = (0, int(200 * intensity + 55), int(255 * (1 - intensity)))
589
 
590
+ # 绘制连线
591
  cv2.line(canvas, (q_cx, q_cy), (h_cx, h_cy), color, 1, cv2.LINE_AA)
592
 
 
 
 
 
 
 
593
  n_matches = len(matches)
594
  avg_sim = sum(s for _, _, s in matches) / max(n_matches, 1)
595
  cv2.putText(canvas, 'Query', (10, 25), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0,0,0), 2)
module/config.py CHANGED
@@ -24,7 +24,7 @@ QDRANT_PATH = os.path.join(PROJECT_ROOT, 'qdrant_data')
24
  MIN_MATCHES = 20
25
  MIN_INLIER_RATIO = 0.15
26
  EDGE_MARGIN = 3
27
- DINOV2_SIM_THRESHOLD = 0.5
28
  DINOV2_HIGH_CONF_THRESHOLD = 0.7
29
  STRICT_MIN_MATCHES = 100
30
  STRICT_MIN_INLIER_RATIO = 0.50
 
24
  MIN_MATCHES = 20
25
  MIN_INLIER_RATIO = 0.15
26
  EDGE_MARGIN = 3
27
+ DINOV2_SIM_THRESHOLD = 0.45
28
  DINOV2_HIGH_CONF_THRESHOLD = 0.7
29
  STRICT_MIN_MATCHES = 100
30
  STRICT_MIN_INLIER_RATIO = 0.50
module/dinov2_utils.py CHANGED
@@ -205,4 +205,8 @@ class DINOv2Extractor:
205
  'hist_grid': feat2['patch_grid'],
206
  'query_image_size': feat1['image_size'],
207
  'hist_image_size': feat2['image_size'],
 
 
 
 
208
  }
 
205
  'hist_grid': feat2['patch_grid'],
206
  'query_image_size': feat1['image_size'],
207
  'hist_image_size': feat2['image_size'],
208
+ 'query_crop_offset': feat1.get('crop_offset', (0, 0)),
209
+ 'hist_crop_offset': feat2.get('crop_offset', (0, 0)),
210
+ 'query_resize_size': feat1.get('resize_size', (518, 518)),
211
+ 'hist_resize_size': feat2.get('resize_size', (518, 518)),
212
  }