短视频去除logo(抖音)
Video-removal -logo本代码仓库使用opencv中的图像修复技术来对视频中的每一帧进行修复,从而得到干净去除掉水印的视频,同时保留了视频的音频部分。Dependent environmentpip install opencv-pythonpip install moviepypip install pydubHow to remove1.找到水印的位置,对于视频中logo会出现
Video-removal -logo
本代码仓库使用opencv中的图像修复技术来对视频中的每一帧进行修复,从而得到干净去除掉水印的视频,同时保留了视频的音频部分。
Dependent environment
pip install opencv-python
pip install moviepy
pip install pydub
How to remove
1.找到水印的位置,对于视频中logo会出现在相对固定位置的去除方法。比如抖音,快手,logo会出现在视频的左上角或者视频的右下角的时候,我们使用图像处理的基本知识来定位找到水印的位置。
2.读取视频的每一帧图像,创建一个和原图大小的mask,使得找到的水印的标识显现在mask图像中。
3.使用形态学膨胀操作,将找到的logo标识进行膨胀处理。
4.使用opencv中cv.inpant图像修复技术来对图像进行修复,去除logo。
5.处理视频中需要裁剪的视频帧数,并且计算得到裁剪时间,同步裁剪视频的音频文件,对视频中的音频文件进行裁剪处理,减掉片尾。
6.裁剪后的视频和裁剪后的音频进行合成视频,得到去除logo后的视频。
image display
Code usage
1.先执行remove_logo.py文件来去除水印和得到裁剪掉片尾的音频文件。
python remove_logo.py
2.运行Combine-audio-video.py来对去除logo的视频和音频文件进行合并。合并的视频文件保存在save_path文件夹中
python Combine-audio-video.py
The video address after removing the logo
链接:https://pan.baidu.com/s/1jB_-ES_JyIq-Bfu4H82Phg
提取码:hnr9
remove_logo.py如下:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import cv2
import os
import sys
import numpy as np
import math
import time
# 捕获音频
from moviepy.editor import *
from pydub import AudioSegment
from get_crop_time import get_time
'''
1.读取视频
2.读取视频的音频
3.找到视频的切分点
4.对视频进行切分
5.对音频进行切分
6.对视频调用去水印函数
7.去完水印的视频和音频合成
'''
def get_img_mask(im,file):
shape = im.shape
w = shape[1]
h = shape[0]
# print('shape[0]',shape[0])
# print('shape[1]',shape[1])
if int(h) > int(w):
rect = (math.ceil(0.086 * h), math.ceil(0.41 * w)) # (H, W) 水印框大。 图像高宽为720,1280时为(110,300)
# 左上角的位置 (15,15)
pos1 = (math.ceil(0.02 * w), math.ceil(0.011 * h))
# 右下角的位置 (405,1150)
pos2 = (math.ceil(0.5625 * w), math.ceil(0.9 * h))
nim = np.zeros((shape[0], shape[1]), dtype=np.uint8)
st_lt = 0
# x先遍历高,y遍历宽
for x in range(pos1[1], pos1[1] + rect[0]):
for y in range(pos1[0], pos1[0] + rect[1]):
px = im[x, y] # im[0,1] 0代表图像的高,1代表图像的宽
if sum(px) > 640:
nim[x, y] = 255
st_lt = st_lt + 1 # 像素超过一定数量就判定为右下角, 否则水印在左上角
# st_lt = st_lt + 1 # 像素超过一定数量就判定为右下角, 否则水印在左上角
#print('st_lt', st_lt)
# 左上角logo的像素点为三千多,当低于1000个像素的时候,就认为logo移动到右下角了
if st_lt < 1000:
nim = np.zeros((shape[0], shape[1]), dtype=np.uint8) # clear
# 先遍历宽,高
for x in range(pos2[0], pos2[0] + rect[1]):
for y in range(pos2[1], pos2[1] + rect[0] + 3):
px = im[y, x]
if sum(px) > 700:
nim[y, x] = 255
# for x in range(400, 720):
else:
nim = np.zeros((shape[0], shape[1]), dtype=np.uint8)
st_lt = 0
'''
对于1280*720的图片,左上角坐标为(10,10)(350,125)
右下角的坐标为(940,580)(1270,710)
'''
# x先遍历高,y遍历宽
for x in range(math.ceil(0.0078125 * h), math.ceil(0.0977 * h)):
for y in range(math.ceil(0.0139 * w), math.ceil(0.486 * w)):
px = im[x, y] # im[0,1] 0代表图像的高,1代表图像的宽
if sum(px) > 640:
nim[x, y] = 255
st_lt = st_lt + 1 # 像素超过一定数量就判定为右下角, 否则水印在左上角
#print('st_lt', st_lt)
# 左上角logo的像素点为三千多,当低于1000个像素的时候,就认为logo移动到右下角了
if st_lt < 1000:
nim = np.zeros((shape[0], shape[1]), dtype=np.uint8) # clear
# 先遍历宽,高
for x in range(math.ceil(0.7344 * w), math.ceil(0.9921 * w)):
for y in range(math.ceil(0.805 * h), math.ceil(0.986 * h)):
px = im[y, x]
if sum(px) > 700:
nim[y, x] = 255
# 这里提取的水印的灰度图
# if not os.path.exists("filter"):
# os.makedirs("filter")
# cv2.imwrite("filter/" + file, nim)
return nim
# 传进来一张
def remove_logo(image,file):
mask = get_img_mask(image,file)
kernel = np.ones((3, 3), np.uint8)
dilate = cv2.dilate(mask, kernel, iterations=3)
kernel_2 = np.ones((5, 5), np.uint8)
dilate = cv2.dilate(dilate, kernel_2, iterations=1)
# cv2.imwrite("delate/" + file, dilate)
sp = cv2.inpaint(image, dilate, 7, flags=cv2.INPAINT_TELEA)
#滤波操作
sp = cv2.bilateralFilter(sp, 5, 280, 50)
return sp
if __name__ == '__main__':
input_pa = r'D:\person_work\github\video-qushuiyin\watermark-master\1\input_path'
print('input_pa',input_pa)
filenames = os.listdir(input_pa)
# 遍历每个文件
for fn in filenames:
t0 =time.time()
# 每个文件的完整路径
input_path = os.path.join(input_pa, fn)
print('input_path',input_path)
cap = cv2.VideoCapture(input_path)
# # 读视频文件
videoclip_1 = VideoFileClip(input_path)
vidio_id = os.path.basename(input_path).split('.')[0]
vidio_id_audio = vidio_id + '.wav'
# c=os.path.splitext(input_path)[0]
# 保存去除logo的视频文件
vidio_id_save = vidio_id + '.mp4'
if not os.path.exists("out_path"):
os.makedirs("out_path")
outpath = os.path.join("out_path", vidio_id_save)
tm = get_time(input_path)
print('tm',tm)
# 对视频画面进行截取
# 获取视频分辨率
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
#图片名称
frame_png = vidio_id+'.png'
# 输出文件编码,Linux下可选X264
fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
# 视频帧率
fps = cap.get(cv2.CAP_PROP_FPS)
print('fps', fps)
success, image = cap.read()
count = 0
success = True
# 输出
out = cv2.VideoWriter(outpath, fourcc, fps, size)
while (count < tm):
success, image = cap.read()
# 去水印,在写入视频
re_logo = remove_logo(image,frame_png)
out.write(re_logo)
count += 1
cap.release()
print('time_all',time.time()-t0)
# # 提取原始视频文件的音频部分
audio_1 = videoclip_1.audio
if not os.path.exists("audio_1_path"):
os.makedirs("audio_1_path")
save_audio_1 = os.path.join("audio_1_path", vidio_id_audio)
audio_1.write_audiofile(save_audio_1)
# 使用剪切音频的方法来对音频剪辑
# 读取音频文件
print('save_audio_1',save_audio_1)
music = AudioSegment.from_wav(save_audio_1)
t = tm/30
# 截取前20秒,tm是求得的秒数
clip = music[:t * 1000]
if not os.path.exists("crop_music"):
os.makedirs("crop_music")
crop_id = vidio_id + '.mp3'
print('crop_id',crop_id)
crop_path = os.path.join('crop_music',crop_id)
print('crop_path',crop_path)
# 保存文件为clip.mp3,格式为mp3
clip.export(crop_path, format='mp3')
get_crop_time.py文件如下
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import cv2
import numpy as np
def is_gray(image):
height, width = image.shape[:2]
size = (int(width * 0.2), int(height * 0.2))
shrink = cv2.resize(image, size, interpolation=cv2.INTER_AREA)
# img.ravel() 将图像转成一维数组,这里没有中括号。
hist, bins = np.histogram(shrink.ravel(), 256, [0, 256])
# print(hist)
no_zero = []
sta = 0
for i in range(len(hist)):
if hist[i] > 1:
sta += 1
return sta
# 获取截取视频的时间点
def get_time(videopath):
cap = cv2.VideoCapture(str(videopath))
success, frame = cap.read()
end_frame = 0
# print('keyframe_id_set',keyframe_id_set)
while (success):
# 如果当前帧的图像是全灰度图,则中断程序,跳出循环
t = is_gray(frame)
if t < 10:
break
else:
# 获取截取帧的视频帧数
end_frame = end_frame + 1
success, frame = cap.read()
return end_frame
Combine-audio-video.py如下
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import cv2
import os
import sys
import numpy as np
import math
# 捕获音频
from moviepy.editor import *
from pydub import AudioSegment
#去除水印后的视频
video_path = r'D:\person_work\github\video-qushuiyin\watermark-master\1\out_path'
#裁剪后的音频文件
music_path =r'D:\person_work\github\video-qushuiyin\watermark-master\1\crop_music'
filenames = os.listdir(video_path)
# 遍历每个文件
for fn in filenames:
# 每个文件的完整路径
vidio_path_name = os.path.join(video_path, fn)
vid = os.path.basename(vidio_path_name).split('.')[0]
#音频文件完整路径
music_name = vid+'.mp3'
music_path_name = os.path.join(music_path, music_name)
# 读取音频
audio_end = AudioFileClip(music_path_name)
videoclip_logo = VideoFileClip(vidio_path_name)
# 将提取的音频和第二个视频文件进行合成
videoclip_3 = videoclip_logo.set_audio(audio_end)
if not os.path.exists("save_path"):
os.makedirs("save_path")
vidio_id_end = vid + ".mp4"
save_video = os.path.join("save_path", vidio_id_end)
print('save_video',save_video)
# 输出新的视频文件
videoclip_3.write_videofile(save_video)
更多推荐
所有评论(0)