OpenCV 是一个跨平台的计算机视觉库,提供了很多图像处理能力。
FFmpeg 则是一个强大的视频处理工具,很多视频软件的基础功能都依赖于他。
我们可以用 OpenCV 和 FFmpeg 组合起来,来去除视频中的水印。
我们旨在解决不同视频中水印大小和位置会变化,但是水印样式一致的视频。另外,单个视频中的水印大小和位置会变化的视频不适合本方案。
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 的报错
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)
# 根据水印所在图片的大小,调整当前水印的大小,比如说我的水印是从宽度 540 的图片上处理出来的,如果当前图片的宽度是 480,就要进行缩放,比例为 480/540=0.889
w, h = img_template.shape[::-1]
w, h = int(w * img_w / 540), int(h * img_w / 540) # 540 换成你的原始水印所在图片的宽度
pic = cv2.resize(img_template, (w, h))
# 进行水印匹配,使用了 TM_CCOEFF_NORMED 算法
res = cv2.matchTemplate(img_gray, pic, cv2.TM_CCOEFF_NORMED)
# 阈值,根据匹配的情况进行调整,如果匹配不到调小,如果匹配的过多了调大,阈值范围 (-1, 1)
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,输出
$ 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 来安装。
执行
ffmpeg -y -i 1.mp4 -vf "delogo=x=375:y=900:w=149:h=37" new_1.mp4
去水印后效果
这样水印就被去除了。
本文仅为技术尝试,切勿用于非法用途,谨记谨记。
暂时没有留言