20250701
This commit is contained in:
121
analyzer.py
Normal file
121
analyzer.py
Normal file
@ -0,0 +1,121 @@
|
||||
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
|
||||
Reference in New Issue
Block a user