OpenCV 是一个跨平台的计算机视觉库,提供了很多图像处理能力。
FFmpeg 则是一个强大的视频处理工具,很多视频软件的基础功能都依赖于他。
我们可以用 OpenCV 和 FFmpeg 组合起来,来去除视频中的水印。
我们旨在解决不同视频中水印大小和位置会变化,但是水印样式一致的视频。另外,单个视频中的水印大小和位置会变化的视频不适合本方案。
从视频中截取首帧截图
1
| ffmpeg -i example.mp4 -y -f image2 -ss 0 -vframes frame1.jpg
|
处理首帧截图拿到水印
这一步需要让你们的 UI 使用 PhotoShop 操作,获取水印并将水印外的部分中透明处理。水印图片应该为 PNG 格式。

水印
匹配水印
匹配水印需要使用 OpenCV 库,本来我是准备用 Golang 的OpenCV 库 gocv.io/x/gocv 来完成操作,但是由于 CGo 模块的报错超出我的能力范围无法解决,所以只能用 python 来完成这部分工作。

golang 下使用 opencv 的报错
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| def has_watermark(img_name, watermark_name): img_rgb = cv2.imread(img_name) img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
img_w, img_h = img_gray.shape[::-1]
img_template = cv2.imread(watermark_name, 0)
w, h = img_template.shape[::-1] w, h = int(w * img_w / 540), int(h * img_w / 540) pic = cv2.resize(img_template, (w, h))
res = cv2.matchTemplate(img_gray, pic, cv2.TM_CCOEFF_NORMED) threshold = 0.4
loc = np.where(res >= threshold) x = loc[0] y = loc[1]
if len(x) and len(y): for pt in zip(*loc[::-1]): print("x=" + str(pt[0]) + ":y=" + str(pt[1]) + ":w=" + str(w + 2) + ":h=" + str(h + 2)) cv2.rectangle(img_rgb, pt, (pt[0] + w + 2, pt[1] + h + 2), (0, 255, 255), 2, 4) break
new_name = os.path.dirname(os.path.abspath(img_name)) + "/" + "new" + os.path.basename(img_name) cv2.imwrite(new_name, img_rgb) return True else: return False
|
执行 python watermark.py 1.jpg
,输出
1 2 3
| $ python3.7 watermark.py 1.jpg x=375:y=900:w=149:h=37 Found
|

1.jpg

new_1.jpg
去除水印
使用 ffmpeg 来去除水印,Mac 上你可以执行 brew install ffmpeg
来安装。
执行
1
| ffmpeg -y -i 1.mp4 -vf "delogo=x=375:y=900:w=149:h=37" new_1.mp4
|

去水印后效果
这样水印就被去除了。
⚠️警告
本文仅为技术尝试,切勿用于非法用途,谨记谨记。