watermark_utls.py 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import cv2
  2. import numpy as np
  3. from sorawm.configs import WATER_MARK_TEMPLATE_IMAGE_PATH
  4. tmpl = cv2.imread(WATER_MARK_TEMPLATE_IMAGE_PATH)
  5. tmpl_gray = cv2.cvtColor(tmpl, cv2.COLOR_BGR2GRAY)
  6. h_tmpl, w_tmpl = tmpl_gray.shape
  7. def detect_watermark(
  8. img: np.array,
  9. region_fraction: float = 0.25,
  10. threshold: float = 0.5,
  11. debug=False, # 添加调试参数
  12. ):
  13. """检测图像中的水印"""
  14. img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  15. h_img, w_img = img_gray.shape
  16. # 临时:先搜索全图,确认能检测到
  17. search_region = img_gray
  18. res = cv2.matchTemplate(search_region, tmpl_gray, cv2.TM_CCOEFF_NORMED)
  19. if debug:
  20. print(f"匹配结果范围: {res.min():.3f} ~ {res.max():.3f}")
  21. max_val = res.max()
  22. max_loc = np.unravel_index(res.argmax(), res.shape)
  23. print(f"最佳匹配位置: {max_loc}, 置信度: {max_val:.3f}")
  24. locs = np.where(res >= threshold)
  25. mask_full = np.zeros((h_img, w_img), dtype=np.uint8)
  26. detections = []
  27. for x, y in zip(*locs[::-1]):
  28. detections.append((x, y, w_tmpl, h_tmpl))
  29. mask_full[y : y + h_tmpl, x : x + w_tmpl] = 255
  30. kernel = np.ones((3, 3), np.uint8)
  31. mask_full = cv2.dilate(mask_full, kernel, iterations=1)
  32. return mask_full, detections
  33. def get_bounding_box(detections, w_tmpl, h_tmpl):
  34. """
  35. 计算所有检测的总边界框
  36. """
  37. if not detections:
  38. return (0, 0, 0, 0)
  39. # 检测格式: (x, y, w, h)
  40. if len(detections[0]) == 4:
  41. min_x = min(x for x, y, w, h in detections)
  42. min_y = min(y for x, y, w, h in detections)
  43. max_x = max(x + w for x, y, w, h in detections)
  44. max_y = max(y + h for x, y, w, h in detections)
  45. # 兼容旧格式: (x, y)
  46. else:
  47. min_x = min(x for x, y in detections)
  48. min_y = min(y for x, y in detections)
  49. max_x = max(x for x, y in detections) + w_tmpl
  50. max_y = max(y for x, y in detections) + h_tmpl
  51. return (min_x, min_y, max_x, max_y)