最近有个视频想要去除水印,搜索了下市面上的产品,用了一圈发现效果都很拉跨。。大部分都是直接高斯模糊处理
另外,都只能处理矩形框的水印,对于我这种斜斜的布满整个视频的水印无法处理;
所以想自己试试用代码去水印看看是否可以更好。
处理的过程如下:
1 先把图片转到 HSV 色彩空间下,手动提取水印的 HSV 值范围;
2 提取多张水印模板,合成一张比较好的水印蒙版;
3 对视频的每帧水印进行处理,有2种方法,一种是opencv 自带的 inpaint ,一种是我自己写的随机替换水印的值为附近点的值,对比了下我的方法效果好一些;
下面的提取到的多个mask :
合成的mask,效果非常好:
当然也可以手动挑选单张效果比较好的mask:
最后效果对比:
OpenCV的inpaint方法
我的方法,自我感觉效果略好:
代码如下:
# coding:utf-8
import numpy as np
import cv2
path = r'23.mp4'
def get_mask(src, count):
rows, cols, channels = src.shape
hsv = cv2.cvtColor(src, cv2.COLOR_BGR2HSV)
low_hsv = np.array([0, 0, 99])
high_hsv = np.array([0, 0, 128])
# high_hsv=np.array([0, 0, 145])
mask = cv2.inRange(hsv, low_hsv, high_hsv)
mask = cv2.erode(mask, None, iterations=2) # 1,然后叠加多张图片会导致很多噪点, 3会导致没有有用信息
# mask=cv2.erode(mask, None, iterations=1) # 1,然后叠加多张图片会导致很多噪点, 3会导致没有有用信息
# mask=cv2.dilate(mask, None, iterations=3)
mask = cv2.dilate(mask, None, iterations=4)
# 保存蒙版图片 每帧的mask 效果不一样,取十次的值
cv2.imwrite("https://zhuanlan.zhihu.com/p/mask_" + str(count)+".png", mask)
np.save('https://zhuanlan.zhihu.com/p/mask_'+ str(count), mask)
return mask
def delete_l(src, mask):
# 自定义替换随机附近点色彩值
for i in range(src.shape[0]):
for j in range(src.shape[1]):
if mask[i, j] == 255: # mask像素点255表示白色
rgb = pick_random_p(src, mask, i, j)
# src[i, j]=(255, 255, 255) # 此处替换颜色,为BGR通道,不是RGB通道
src[i, j] = rgb # 此处替换颜色,为BGR通道,不是RGB通道
return src
def get_hsv_mouse(src):
# 获取 hsv 数值
rows, cols, channels = src.shape
hsv = cv2.cvtColor(src, cv2.COLOR_BGR2HSV)
def getpos(event, x, y, flags, param):
if event == cv2.EVENT_LBUTTONDOWN: # 定义一个鼠标左键按下去的事件
print("HSV is ",hsv[y, x])
cv2.imshow('imageHSV', hsv)
cv2.setMouseCallback("imageHSV", getpos)
cv2.waitKey(0)
cv2.destroyAllWindows()
def read_mp4(gen_hsv=False, gen_mask=False):
cap = cv2.VideoCapture(path)
if not gen_hsv and not gen_mask:
try:
mask = np.load('mask.npy')
# mask=np.load('https://zhuanlan.zhihu.com/p/data/mask_1400.npy')
except:
print(" 蒙版还未生成 mask ")
return
fps = 60
fourcc = cv2.VideoWriter_fourcc(*'mp4v') # 用于mp4格式的生成
videowriter = cv2.VideoWriter("result.mp4", fourcc, fps, (mask.shape[1], mask.shape[0]))
# 创建一个写入视频对象 w,h
count = 0
mask_list = []
while True:
ret, frame = cap.read()
count += 1
if not gen_hsv and not gen_mask:
print("count frame ", count)
cv2.imshow('video0', frame)
# 处理每一帧
frame = delete_l(frame, mask)
cv2.imshow('video1', frame)
videowriter.write(frame)
elif gen_hsv:
# 生成样例图片
cv2.imwrite('result.jpg', frame)
cv2.waitKey(10)
print('视频宽为', frame.shape[1],'视频高为', frame.shape[0])
get_hsv_mouse(frame)
elif gen_mask:
if count%100 == 0:
mask = get_mask(frame, count) # 必须先读取一次视频,保存了再处理
print(np.max(mask))
mask_list.append(mask)
if len(mask_list) > 40:
break
if cv2.waitKey(2) & 0xff == ord('q'):
break
if gen_mask: # 混合多个蒙版
temp = np.zeros(mask_list[0].shape, np.uint8) # 创建一张空图像用于保存
for m in mask_list:
temp += m
np.clip(temp, 0, 255)
cv2.imwrite("mask.png", temp)
np.save('mask', temp)
cap.release()
cv2.destroyAllWindows()
if not gen_hsv and not gen_mask:
videowriter.release()
# 依次运行下面三个函数就行了
# 第一步 获取hsv值范围,以及视频高宽
# read_mp4(True, False)
# 第二步 获取合成mask
# read_mp4(False, True)
# 第三步 处理视频
# read_mp4()
如果想要处理图片稍微调整下代码就行了。
不过这个代码缺点也很明显,那就是非常慢。。。哈哈哈
电 话:400-123-4567
传 真:+86-123-4567
手 机:13800000000
邮 箱:admin@eyoucms.com
地 址:广东省广州市天河区88号