美文网首页
用OpenCV制作VHS复古风格老视频

用OpenCV制作VHS复古风格老视频

作者: zjam9333 | 来源:发表于2019-06-21 14:20 被阅读0次

    不用Premiere,不用PhotoShop,不用App,也可以用OpenCV制作视频滤镜!
    最近流行起一股复古风,于是不懂剪辑视频的我也想搞一搞这种复古风格老视频。

    处理前 处理后
    首先看看有什么特点:
    • 标清分辨率(大约480)
    • 既有模糊又有锐化
    • 色彩饱和度低
    • 紫边(镜头色散)
    • 色调偏黄(索尼大法黄?)
    那么一步一步来
    • 首先读取一张图片,或视频里的每一帧
    img = cv2.imread('test.jpg')
    
    • 调整图片大小
    copy = cv2.resize(img, (640, 480))
    
    • 高斯模糊,然后锐化
    # blur
    copy = cv2.GaussianBlur(copy, (3, 3), 0)
    # sharpen 
    kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]])
    copy = cv2.filter2D(copy, -1, kernel)
    
    模糊再锐化
    • 降低色彩饱和度

    这里的思路是将图片转成HSV色彩空间,降低S的值即可降低色彩饱和度,最后再转回默认的BGR色彩空间

    HSV = cv2.cvtColor(copy, cv2.COLOR_BGR2HSV)
    S = HSV[:, :, 1]
    S[:, :] = S[:, :] * 0.8
    copy = cv2.cvtColor(HSV, cv2.COLOR_HSV2BGR)
    

    可以看见原本的鲜艳红色变得暗淡了

    降低色彩饱和度
    • 制作紫边

    紫边的出现是因为镜头对不同颜色的折射率不同而导致的色散现象,老的摄影机镜头对色散的处理都不是很好,因此紫边是老视频里最重要的特点之一!

    主要思路是让R、G、B分别上下左右移动若干像素。
    例如让所有的红色向左移动5像素

    cols = copy.shape[1]
    move = 5
    # pick one channel to translate, 0:B 1:G 2:R
    toLeft = copy[:, :, 2]
    toLeft[:, :cols - move] = toLeft[:, move:]
    
    红色左移5像素

    如上图,可以看见移动5像素太过于夸张了,那么移动1或2像素就比较像了
    那么将B左移1,G上移1,R右移1,得到下面的效果

    move = 1
    cols = copy.shape[1]
    toLeft = copy[:, :, 0]
    toLeft[:, :cols - move] = toLeft[:, move:]
    toRight = copy[:, :, 2]
    toRight[:, move:] = toRight[:, :cols - move]
        
    rows = copy.shape[0]
    toUp = copy[:, :, 1]
    toUp[:rows - move:] = toUp[move:, :]
    
    RGB各移动1像素
    • 让图片变黄(如果不喜欢黄色可以跳过这一步)

    直接让减小B和G的值就行了

    B = copy[:, :, 0]
    B[:, :] = B[:, :] * 0.94
    G = copy[:, :, 1]
    G[:, :] = G[:, :] * 0.99
    
    变黄的图片
    • 其他

    也许还有一些例如黑线、随机噪点等操作,看个人口味

    将上述操作用于视频
    • 首先将上述操作封装成一个函数:
    def VHSImage(src):
        # blablabla
        return result
    
    • 读取原视频,处理每一帧,写入新视频,最后合并新视频和旧音频
    def doWithVideo(src, output = 'out.mp4'):
        cap = cv2.VideoCapture(src)
        width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
        height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
        fps = cap.get(cv2.CAP_PROP_FPS)
        framecount = cap.get(cv2.CAP_PROP_FRAME_COUNT)
        print('total frame: {}'.format(framecount))
    
        videoheight = int(480)
        videowidth = int(float(videoheight) / float(height) * float(width))
        videosize = (videowidth, videoheight)
    
        cachePrefixName = time.strftime('%Y%m%d_%H%M%S')
        cacheVideoName = "{}.cachevideo.mp4".format(cachePrefixName)
        cacheAudioName = "{}.cacheaudio.mp3".format(cachePrefixName)
    
        cc = cv2.VideoWriter_fourcc(*'mp4v')
        out = cv2.VideoWriter(cacheVideoName, cc, fps, videosize)
        if out.isOpened() == False:
            print('fail to open video writer')
            return False
    
        currentframeindex = 0
        while cap.isOpened():
            ret, frame = cap.read()
            if ret == False:
                break
            frame = cv2.resize(frame, videosize)
            frame = VHSImage(frame)
            # cv2.imshow('frame', frame)
            # cv2.waitKey(1)
            out.write(frame)
            print('progress:{}/{}'.format(currentframeindex, framecount))
            currentframeindex += 1
        cap.release()
        out.release()
        print('finish progress')
        
        # ffmpeg -i INPUT_VIDEO -f mp3 -vn OUTPUT_AUDIO
        # ffmpeg -i INPUT_VIDEO -i INPUT_AUDIO -c:v copy OUTPUT_VIDEO
        print('remix audio and video')
        os.system("ffmpeg -i {} -f mp3 -vn {}".format(src, cacheAudioName))
        # check audio file if exists
        if os.path.exists(cacheAudioName):
            # remix audio and video
            os.system("ffmpeg -i {} -i {} -c:v copy {}".format(cacheVideoName, cacheAudioName, output))
            print("cleaning cache")
            os.system("rm -rf {} {}".format(cacheAudioName, cacheVideoName))
        else :
            # rename this no-audio video
            os.system("mv {} {}".format(cacheVideoName, output))
        print("finish remix")
        print("done")
    

    最后上源码地址:https://gayhub.com/ZJamm1993/VHS_STYLE_VIDEO

    相关文章

      网友评论

          本文标题:用OpenCV制作VHS复古风格老视频

          本文链接:https://www.haomeiwen.com/subject/ghqyqctx.html