zoukankan      html  css  js  c++  java
  • 使用ffmpeg混合两个视频并用opencv增强视觉效果

    使用ffmpeg混合两个视频并增强视觉效果

    由于远程容器的ffmpeg版本不包括mix功能,使用的是从网盘下的本地代码和本地的ffmpeg,仅上传了有改动的部分。

    代码在code/notebook/_video.ipynb,视频在code/video/outputxxx.mp4

    由于播放视频的功能在容器中,所以在本地复制了一份notebook_helpers.py,稍微修改了代码确保正确导入。

    给定的输入为两个完全看不出内容的视频,如下:

    开始处理吧!

    • code/video/output.mp4为直接使用ffmpeg混合两个输入得到的视频。可以看出视频内容为从8开始的倒计时,但不是很清楚。

    • 首先观察到直接合成的视频对比度很低,先使用ffmpeg提高了对比度得到code/video/output2.mp4

    • 然后注意到视频中的噪点非常多,使用中值滤波和非局部平均去噪进行降噪,得到code/video/output3.mp4
      • 该步骤非常耗时
      • 如果跳过前一步增加对比度的操作直接降噪,会使得画面几乎完全看不清,再增加对比度也只能得到马赛克图像

    也可以使用ffmpeg带的BM3D算法


    • 视频经过滤波后,画面变得比较模糊,我希望通过锐化的方式让数字边缘看起来更清楚一些,得到code/video/output4.mp4

    • 锐化后噪点也看的更清楚了,使用中值滤波再处理一次,得到code/video/output5.mp4。由于最开始的噪声太强,如果不使用形状特征匹配,基本也就是这个效果了。

    注意: opencv保存的mp4文件需要跟原视频一样使用avci编码才可以,然而需要额外下载openh264.dll文件放在目录中,直接使用的话会报错

    Failed to load OpenH264 library: openh264-1.8.0-win64.dll
    		Please check environment and/or download library: https://github.com/cisco/openh264/releases
    
    [libopenh264 @ 0000019f375b3cc0] Incorrect library version loaded
    Could not open codec 'libopenh264': Unspecified error

    为了展示每一步的效果,在jupyter里每次操作都是重新读写视频

    In [1]:
    import subprocess
    from notebook_helpers import play_video
    import cv2
    import numpy as np
    In [2]:
    # play video 1
    play_video('../video/video_1.mp4')
    Out[2]:
    In [3]:
    # play video 2
    play_video('../video/video_2.mp4')
    Out[3]:
    In [4]:
    # use ffmpeg to mix 2 videos
    subprocess.run(["ffmpeg", "-y","-i", "../video/video_1.mp4", "-i", "../video/video_2.mp4", "-filter_complex", "mix", "../video/output.mp4"])
    Out[4]:
    CompletedProcess(args=['ffmpeg', '-y', '-i', '../video/video_1.mp4', '-i', '../video/video_2.mp4', '-filter_complex', 'mix', '../video/output.mp4'], returncode=0)
    In [5]:
    # play output video
    play_video('../video/output.mp4')
    Out[5]:
    In [6]:
    # change the contrast
    subprocess.run(["ffmpeg", "-y","-i", "../video/output.mp4", "-vf", "eq=contrast=9", "../video/output2.mp4"])
    Out[6]:
    CompletedProcess(args=['ffmpeg', '-y', '-i', '../video/output.mp4', '-vf', 'eq=contrast=9', '../video/output2.mp4'], returncode=0)
    In [7]:
    # play output2 video
    play_video('../video/output2.mp4')
    Out[7]:
    In [8]:
    #中值滤波&非局部平均去噪
    video_path = "../video/output2.mp4"
    cap = cv2.VideoCapture(video_path )
    
    fps = cap.get(cv2.CAP_PROP_FPS) #获取视频的帧率
    size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),
            int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))#获取视频的大小
    fourcc = cv2.VideoWriter_fourcc(*'avc1')  #要保存的视频编码
    #把处理过的视频保存下来
    output_viedo = cv2.VideoWriter()
    #保存的视频地址
    video_save_path = '../video/output3.mp4'
    output_viedo.open(video_save_path , fourcc, fps, size, True)
    while True:
        ret, image_np = cap.read()
        if not(ret):
            break
        image_np = cv2.medianBlur(image_np,7) #中值滤波
        image_np = cv2.fastNlMeansDenoising(image_np, 15, 8, 25) #非局部平均去噪
        output_viedo.write(image_np) #把帧写入到视频中
    output_viedo.release()#释放
    cap.release()#释放
    In [9]:
    # play output3 video
    play_video('../video/output3.mp4')
    Out[9]:
    In [10]:
    #锐化
    video_path = "../video/output3.mp4"
    cap = cv2.VideoCapture(video_path )
    
    fps = cap.get(cv2.CAP_PROP_FPS) #获取视频的帧率
    size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),
            int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))#获取视频的大小
    fourcc = cv2.VideoWriter_fourcc(*'avc1')  #要保存的视频编码
    #把处理过的视频保存下来
    output_viedo = cv2.VideoWriter()
    #保存的视频地址
    video_save_path = '../video/output4.mp4'
    output_viedo.open(video_save_path , fourcc, fps, size, True)
    while True:
        ret, image_np = cap.read()
        if not(ret):
            break
        kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]],dtype=np.float32) #锐化
        image_np = cv2.filter2D(image_np, -1, kernel=kernel)
        output_viedo.write(image_np) #把帧写入到视频中
    output_viedo.release()#释放
    cap.release()#释放
    In [11]:
    # play output4 video
    play_video('../video/output4.mp4')
    Out[11]:
    In [12]:
    #再一次中值滤波
    video_path = "../video/output4.mp4"
    cap = cv2.VideoCapture(video_path )
    
    fps = cap.get(cv2.CAP_PROP_FPS) #获取视频的帧率
    size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),
            int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))#获取视频的大小
    fourcc = cv2.VideoWriter_fourcc(*'avc1')  #要保存的视频编码
    #把处理过的视频保存下来
    output_viedo = cv2.VideoWriter()
    #保存的视频地址
    video_save_path = '../video/output5.mp4'
    output_viedo.open(video_save_path , fourcc, fps, size, True)
    while True:
        ret, image_np = cap.read()
        if not(ret):
            break
        image_np = cv2.medianBlur(image_np,7) #中值滤波
        output_viedo.write(image_np) #把帧写入到视频中
    output_viedo.release()#释放
    cap.release()#释放
    In [13]:
    # play output5 video
    play_video('../video/output5.mp4')
    Out[13]:

    notebook_helpers.py提供了在jupyter中播放视频的功能。

    from IPython.display import HTML
    
    
    def play_video(path, width=320, height=240, format='mp4'):
        html = """
            <video width="{width}" height="{height}" controls>
            <source src="{path}" type="video/{format}">
            </video>
            """.format(path=path, width=width, height=height, format=format)
    
        return HTML(html)
  • 相关阅读:
    防盗链(三)nginx实现图片防盗链(referer指令)
    防盗链(二)nginx secure_link下载防盗链
    防盗链(一)资料整理
    如何实现 token 加密
    Socket编程(三)demo举例
    Socket编程-(二)tcp三次握手与四次挥手
    Spring的事务控制,注解和xml配置以及解释
    SpringAop的核心概念和使用,表达式匹配刨析,xml配置通知和环绕通知
    SpringAop的简介
    Spring整合JUnit测试单元
  • 原文地址:https://www.cnblogs.com/smileglaze/p/13943236.html
Copyright © 2011-2022 走看看