水印搜索算法
发布时间:2025-09-28
公开文章
水印搜索算法
🧠 优化策略一:使用边缘特征匹配(Canny + 模板匹配)
灰黑色水印在灰度图中对比度不高,但其边缘轮廓非常清晰,可以通过边缘检测提取出来:
# 灰度处理
gray_original = cv2.cvtColor(original, cv2.COLOR_BGR2GRAY)
gray_watermark = cv2.cvtColor(watermark, cv2.COLOR_BGR2GRAY)
# 边缘提取
edges_original = cv2.Canny(gray_original, 50, 150)
edges_watermark = cv2.Canny(gray_watermark, 50, 150)
# 模板匹配
result = cv2.matchTemplate(edges_original, edges_watermark, cv2.TM_CCOEFF_NORMED)
threshold = 0.3
locations = np.where(result >= threshold)
coordinates = list(zip(*locations[::-1]))
这种方式对灰黑色文字水印非常有效,因为它忽略了颜色,仅关注结构。
🧠 优化策略二:多尺度匹配(适应缩放)
如果水印在原图中被缩放或压缩过,可以尝试不同尺寸的模板:
scales = [0.8, 1.0, 1.2]
for scale in scales:
resized = cv2.resize(gray_watermark, None, fx=scale, fy=scale)
result = cv2.matchTemplate(gray_original, resized, cv2.TM_CCOEFF_NORMED)
# 记录最大匹配值和位置
你可以记录每个 scale
下的最大匹配值,选出最优的。
🧠 优化策略三:使用 ORB 特征匹配 + 单应性定位
你之前已经成功用 ORB 得到 81 个匹配点,这说明水印图与原图之间确实存在结构上的相似性。你可以继续使用 ORB 来定位水印区域:
orb = cv2.ORB_create(5000)
kp1, des1 = orb.detectAndCompute(gray_original, None)
kp2, des2 = orb.detectAndCompute(gray_watermark, None)
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(des1, des2)
matches = sorted(matches, key=lambda x: x.distance)
# 单应性定位
src_pts = np.float32([kp2[m.trainIdx].pt for m in matches]).reshape(-1,1,2)
dst_pts = np.float32([kp1[m.queryIdx].pt for m in matches]).reshape(-1,1,2)
M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
然后你可以用 cv2.perspectiveTransform
得到水印区域,并进行修复或反色中和。
✅ 总结推荐方案
方法 | 适用场景 | 推荐程度 |
---|---|---|
Canny边缘匹配 | 灰黑色文字水印 | ⭐⭐⭐⭐ |
多尺度匹配 | 水印被缩放 | ⭐⭐⭐ |
ORB特征匹配 | 结构清晰、位置不定 | ⭐⭐⭐⭐⭐ |