如何使用 OpenCV 保存视频?

How can save the video with OpenCV?

我想使用 OpenCV 的创建背景减法方法处理和提取视频。但是,写了下面的代码后,视频没有播放。

import numpy as np
import time
video_path = 'aaa.mp4'
output_path = 'aaa_test.mp4'
video = cv2.VideoCapture(video_path)
w=round(video.get(cv2.CAP_PROP_FRAME_WIDTH))
h=round(video.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = video.get(cv2.CAP_PROP_FPS)
fourcc = cv2.VideoWriter_fourcc(*'MP4v')
out = cv2.VideoWriter('aaa_1_1.mp4', fourcc, fps, (w,h)) 
fgbg = cv2.createBackgroundSubtractorMOG2(history=200,varThreshold=32,detectShadows=False)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(1,1))
while(1):
    start = time.time()
    return_value, frame = video.read()
    if return_value:
        pass
    else : 
        print('END')
        break
    background_extraction_mask = fgbg.apply(frame)
    background_extraction_mask = cv2.dilate(background_extraction_mask,kernel,iterations=1)

    background_extraction_mask = np.stack((background_extraction_mask,)*3, axis=-1)
    concat_image = np.concatenate((frame,background_extraction_mask), axis=1)
    cv2.imshow('background extraction video', concat_image)
    out.write(concat_image)
cv2.waitKey(1)
video.release()
out.release()
cv2.destroyAllWindows()

我发现了两个问题:

  • FOURCC 代码区分大小写 - 它应该是 'mp4v' 而不是 'MP4v'.
  • 由于水平拼接,写入的视频帧是原始视频帧宽度的两倍。
    cv2.VideoWriter('aaa_1_1.mp4', fourcc, fps, (w, h)) 替换为 cv2.VideoWriter('aaa_1_1.mp4', fourcc, fps, (w*2, h))

完整代码示例:

import cv2
import numpy as np
import time

video_path = 'aaa.mp4'
output_path = 'aaa_test.mp4'
video = cv2.VideoCapture(video_path)
w = int(video.get(cv2.CAP_PROP_FRAME_WIDTH))
h = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = video.get(cv2.CAP_PROP_FPS)
fourcc = cv2.VideoWriter_fourcc(*'mp4v')  # fourcc = cv2.VideoWriter_fourcc(*'MP4v')  # FOURCC is case sensitive
out = cv2.VideoWriter('aaa_1_1.mp4', fourcc, fps, (w*2, h))  # Size must match the actual frame size, so use (w*2, h) instead of (w, h) because written frame is two concatenated frames.
fgbg = cv2.createBackgroundSubtractorMOG2(history=200, varThreshold=32, detectShadows=False)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (1, 1))

while True:
    start = time.time()
    return_value, frame = video.read()

    if not return_value:
        print('END')
        break

    background_extraction_mask = fgbg.apply(frame)
    background_extraction_mask = cv2.dilate(background_extraction_mask, kernel, iterations=1)

    background_extraction_mask = np.stack((background_extraction_mask,)*3, axis=-1)
    concat_image = np.concatenate((frame, background_extraction_mask), axis=1)
    cv2.imshow('background extraction video', concat_image)
    cv2.waitKey(1)
    out.write(concat_image)

video.release()
out.release()
cv2.destroyAllWindows()