import cv2 import numpy as np import json from datetime import datetime class WatermarkAnalyzer: def __init__(self, config_path="config/default_config.json"): self.watermark_regions = [] self.selected_regions = [] self.config_path = config_path self.load_config() self._check_opencv_version() def _check_opencv_version(self): """检查OpenCV版本,确定是否支持显著性检测""" self.has_saliency = hasattr(cv2, 'saliency') if not self.has_saliency: print("警告: 当前OpenCV版本不支持显著性检测,将使用替代方法") def load_config(self): try: with open(self.config_path, 'r') as f: config = json.load(f) self.inpaint_radius = config.get("inpaint_radius", 5) self.inpaint_algorithm = config.get("inpaint_algorithm", cv2.INPAINT_TELEA) self.dilate_size = config.get("dilate_size", 3) self.use_adaptive_mask = config.get("use_adaptive_mask", True) self.text_threshold = config.get("text_threshold", 180) self.min_text_area = config.get("min_text_area", 100) self.text_color_range = tuple( tuple(c) for c in config.get("text_color_range", ((50, 50, 50), (180, 180, 180)))) self.stamp_color_range = tuple( tuple(c) for c in config.get("stamp_color_range", ((0, 0, 100), (100, 100, 255)))) self.saliency_threshold = config.get("saliency_threshold", 0.5) self.edge_threshold = config.get("edge_threshold", 100) self.use_mser = config.get("use_mser", True) self.use_color_filter = config.get("use_color_filter", True) self.use_texture_analysis = config.get("use_texture_analysis", True) except Exception as e: print(f"加载配置失败: {e}") self.reset_to_defaults() # ... 其他方法保持不变 ... def _detect_by_saliency(self, img): """基于显著性检测水印 - 兼容旧版OpenCV""" if self.has_saliency: # 使用标准显著性检测(如果支持) try: saliency = cv2.saliency.StaticSaliencySpectralResidual_create() _, saliency_map = saliency.computeSaliency(img) # 阈值处理 _, saliency_mask = cv2.threshold(saliency_map * 255, self.saliency_threshold * 255, 255, cv2.THRESH_BINARY) saliency_mask = saliency_mask.astype(np.uint8) # 形态学操作 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) closed = cv2.morphologyEx(saliency_mask, cv2.MORPH_CLOSE, kernel) # 查找轮廓 contours, _ = cv2.findContours(closed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) regions = [] for contour in contours: x, y, w, h = cv2.boundingRect(contour) area = w * h if area > self.min_text_area * 2 and area < img.shape[0] * img.shape[1] * 0.1: regions.append({ 'type': 'saliency', 'position': (x, y, w, h), 'confidence': 0.7, 'contour': contour }) return regions except Exception as e: print(f"显著性检测失败: {e}") self.has_saliency = False # 标记为不支持,下次使用替代方法 # 替代方法:使用亮度变化检测 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 高斯模糊减少噪声 blurred = cv2.GaussianBlur(gray, (15, 15), 0) # 计算拉普拉斯算子检测边缘 laplacian = cv2.Laplacian(blurred, cv2.CV2.CV_64F) laplacian = np.uint8(np.absolute(laplacian)) # 阈值处理 _, threshold = cv2.threshold(laplacian, 30, 255, cv2.THRESH_BINARY) # 形态学操作 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) closed = cv2.morphologyEx(threshold, cv2.MORPH_CLOSE, kernel) # 查找轮廓 contours, _ = cv2.findContours(closed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) regions = [] for contour in contours: x, y, w, h = cv2.boundingRect(contour) area = w * h if area > self.min_text_area * 2 and area < img.shape[0] * img.shape[1] * 0.1: # 计算轮廓的紧致度 perimeter = cv2.arcLength(contour, True) compactness = 4 * np.pi * area / (perimeter * perimeter) if perimeter > 0 else 0 # 水印通常具有中等紧致度 if 0.1 < compactness < 0.9: regions.append({ 'type': 'contrast', 'position': (x, y, w, h), 'confidence': 0.6, 'contour': contour }) return regions