语言选择: 简体中文简体中文 line EnglishEnglish

公司动态

视频去水印的Python代码

最近有个视频想要去除水印,搜索了下市面上的产品,用了一圈发现效果都很拉跨。。大部分都是直接高斯模糊处理

另外,都只能处理矩形框的水印,对于我这种斜斜的布满整个视频的水印无法处理;

所以想自己试试用代码去水印看看是否可以更好。



处理的过程如下:

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()


如果想要处理图片稍微调整下代码就行了。

不过这个代码缺点也很明显,那就是非常慢。。。哈哈哈

平台注册入口