我們再搬運視頻的時候常常會遇到視頻有水印的問題 如下 下面就通過python來實現(xiàn)對視頻水印的去除
在pycharm新建一個項目,創(chuàng)建image,video目錄其他不用 必要條件
在終端下載相關依賴包
pip install moviepy==1.0.3 pip installnumpy==1.21.5 pip install opencv_python==4.5.5.62
將要去除水印的視頻放在video目錄下,運行一下????????
用鼠標操作去除的部分,回車即可
去除了水印的視頻輸出到了output文件夾下
查看效果,還不錯?文章來源:http://www.zghlxwxcb.cn/news/detail-595240.html
?文章來源地址http://www.zghlxwxcb.cn/news/detail-595240.html
代碼實現(xiàn)
import os import sys import cv2 import numpy from moviepy import editor VIDEO_PATH = 'video' OUTPUT_PATH = 'output' TEMP_VIDEO = 'temp.mp4' class WatermarkRemover(): def __init__(self, threshold: int, kernel_size: int): self.threshold = threshold #閾值分割所用閾值 self.kernel_size = kernel_size #膨脹運算核尺寸 def select_roi(self, img: numpy.ndarray, hint: str) -> list: ''' 框選水印或字幕位置,SPACE或ENTER鍵退出 :param img: 顯示圖片 :return: 框選區(qū)域坐標 ''' COFF = 0.7 w, h = int(COFF * img.shape[1]), int(COFF * img.shape[0]) resize_img = cv2.resize(img, (w, h)) roi = cv2.selectROI(hint, resize_img, False, False) cv2.destroyAllWindows() watermark_roi = [int(roi[0] / COFF), int(roi[1] / COFF), int(roi[2] / COFF), int(roi[3] / COFF)] return watermark_roi def dilate_mask(self, mask: numpy.ndarray) -> numpy.ndarray: ''' 對蒙版進行膨脹運算 :param mask: 蒙版圖片 :return: 膨脹處理后蒙版 ''' kernel = numpy.ones((self.kernel_size, self.kernel_size), numpy.uint8) mask = cv2.dilate(mask, kernel) return mask def generate_single_mask(self, img: numpy.ndarray, roi: list, threshold: int) -> numpy.ndarray: ''' 通過手動選擇的ROI區(qū)域生成單幀圖像的水印蒙版 :param img: 單幀圖像 :param roi: 手動選擇區(qū)域坐標 :param threshold: 二值化閾值 :return: 水印蒙版 ''' #區(qū)域無效,程序退出 if len(roi) != 4: print('NULL ROI!') sys.exit() #復制單幀灰度圖像ROI內(nèi)像素點 roi_img = numpy.zeros((img.shape[0], img.shape[1]), numpy.uint8) start_x, end_x = int(roi[1]), int(roi[1] + roi[3]) start_y, end_y = int(roi[0]), int(roi[0] + roi[2]) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) roi_img[start_x:end_x, start_y:end_y] = gray[start_x:end_x, start_y:end_y] #閾值分割 _, mask = cv2.threshold(roi_img, threshold, 255, cv2.THRESH_BINARY) return mask def generate_watermark_mask(self, video_path: str) -> numpy.ndarray: ''' 截取視頻中多幀圖像生成多張水印蒙版,通過邏輯與計算生成最終水印蒙版 :param video_path: 視頻文件路徑 :return: 水印蒙版 ''' video = cv2.VideoCapture(video_path) success, frame = video.read() roi = self.select_roi(frame, 'select watermark ROI') mask = numpy.ones((frame.shape[0], frame.shape[1]), numpy.uint8) mask.fill(255) step = video.get(cv2.CAP_PROP_FRAME_COUNT) // 5 index = 0 while success: if index % step == 0: mask = cv2.bitwise_and(mask, self.generate_single_mask(frame, roi, self.threshold)) success, frame = video.read() index += 1 video.release() return self.dilate_mask(mask) def generate_subtitle_mask(self, frame: numpy.ndarray, roi: list) -> numpy.ndarray: ''' 通過手動選擇ROI區(qū)域生成單幀圖像字幕蒙版 :param frame: 單幀圖像 :param roi: 手動選擇區(qū)域坐標 :return: 字幕蒙版 ''' mask = self.generate_single_mask(frame, [0, roi[1], frame.shape[1], roi[3]], self.threshold) #僅使用ROI橫坐標區(qū)域 return self.dilate_mask(mask) def inpaint_image(self, img: numpy.ndarray, mask: numpy.ndarray) -> numpy.ndarray: ''' 修復圖像 :param img: 單幀圖像 :parma mask: 蒙版 :return: 修復后圖像 ''' telea = cv2.inpaint(img, mask, 1, cv2.INPAINT_TELEA) return telea def merge_audio(self, input_path: str, output_path: str, temp_path: str): ''' 合并音頻與處理后視頻 :param input_path: 原視頻文件路徑 :param output_path: 封裝音視頻后文件路徑 :param temp_path: 無聲視頻文件路徑 ''' with editor.VideoFileClip(input_path) as video: audio = video.audio with editor.VideoFileClip(temp_path) as opencv_video: clip = opencv_video.set_audio(audio) clip.to_videofile(output_path) def remove_video_watermark(self): ''' 去除視頻水印 ''' if not os.path.exists(OUTPUT_PATH): os.makedirs(OUTPUT_PATH) filenames = [os.path.join(VIDEO_PATH, i) for i in os.listdir(VIDEO_PATH)] mask = None for i, name in enumerate(filenames): if i == 0: #生成水印蒙版 mask = self.generate_watermark_mask(name) #創(chuàng)建待寫入文件對象 video = cv2.VideoCapture(name) fps = video.get(cv2.CAP_PROP_FPS) size = (int(video.get(cv2.CAP_PROP_FRAME_WIDTH)), int(video.get(cv2.CAP_PROP_FRAME_HEIGHT))) video_writer = cv2.VideoWriter(TEMP_VIDEO, cv2.VideoWriter_fourcc(*'mp4v'), fps, size) #逐幀處理圖像 success, frame = video.read() while success: frame = self.inpaint_image(frame, mask) video_writer.write(frame) success, frame = video.read() video.release() video_writer.release() #封裝視頻 (_, filename) = os.path.split(name) output_path = os.path.join(OUTPUT_PATH, filename.split('.')[0] + '_no_watermark.mp4')#輸出文件路徑 self.merge_audio(name, output_path, TEMP_VIDEO) if os.path.exists(TEMP_VIDEO): os.remove(TEMP_VIDEO) def remove_video_subtitle(self): ''' 去除視頻字幕 ''' if not os.path.exists(OUTPUT_PATH): os.makedirs(OUTPUT_PATH) filenames = [os.path.join(VIDEO_PATH, i) for i in os.listdir(VIDEO_PATH)] roi = [] for i, name in enumerate(filenames): #創(chuàng)建待寫入文件對象 video = cv2.VideoCapture(name) fps = video.get(cv2.CAP_PROP_FPS) size = (int(video.get(cv2.CAP_PROP_FRAME_WIDTH)), int(video.get(cv2.CAP_PROP_FRAME_HEIGHT))) video_writer = cv2.VideoWriter(TEMP_VIDEO, cv2.VideoWriter_fourcc(*'mp4v'), fps, size) #逐幀處理圖像 success, frame = video.read() if i == 0: roi = self.select_roi(frame, 'select subtitle ROI') while success: mask = self.generate_subtitle_mask(frame, roi) frame = self.inpaint_image(frame, mask) video_writer.write(frame) success, frame = video.read() video.release() video_writer.release() #封裝視頻 (_, filename) = os.path.split(name) output_path = os.path.join(OUTPUT_PATH, filename.split('.')[0] + '_no_sub.mp4')#輸出文件路徑 self.merge_audio(name, output_path, TEMP_VIDEO) if os.path.exists(TEMP_VIDEO): os.remove(TEMP_VIDEO) if __name__ == '__main__': #去除視頻水印 remover = WatermarkRemover(threshold=80, kernel_size=5) remover.remove_video_watermark() #去除視頻字幕 remover = WatermarkRemover(threshold=80, kernel_size=10) remover.remove_video_subtitle()
到了這里,關于基于python實現(xiàn)去除視頻的水印的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!