Files
test/analyzer.py
2025-07-01 17:42:33 +08:00

121 lines
5.1 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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