如何在python中使用opencv将视频的特定部分保存到单独的视频中?

cod*_*exx 0 python opencv video-editing

我有一个视频,我想使用帧号获取该视频的特定部分并保存它们。

例如,如果有一个视频,总共有 200 帧,我想提取视频的一些特定部分,例如从第 15 帧到第 30 帧、第 50 帧到第 79 帧等,并且我想单独保存每个部分。

cap= cv2.VideoCapture('Trademill.mp4')
video_length = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) 
print ("Number of frames: ", video_length)

success,image = cap.read()
count = 0
while success:
cv2.imwrite("frame%d.jpg" % count, image)          
success,image = cap.read()
count += 1
Run Code Online (Sandbox Code Playgroud)

我如何使用 python 和 OpenCV 来做到这一点?

Ann*_*Zen 7

我将这样做:

import cv2

file = "video.avi"
parts = [(15, 30), (50, 79)]

cap = cv2.VideoCapture(file)
ret, frame = cap.read()
h, w, _ = frame.shape

fourcc = cv2.VideoWriter_fourcc(*"XVID")
writers = [cv2.VideoWriter(f"part{start}-{end}.avi", fourcc, 20.0, (w, h)) for start, end in parts]

f = 0
while ret:
    f += 1
    for i, part in enumerate(parts):
        start, end = part
        if start <= f <= end:
            writers[i].write(frame)
    ret, frame = cap.read()

for writer in writers:
    writer.release()

cap.release()
Run Code Online (Sandbox Code Playgroud)

解释:

  1. 导入cv2模块,定义视频文件的名称以及要保存到不同视频文件中的文件部分:
import cv2

file = "video.avi"
parts = [(15, 30), (50, 79)]
Run Code Online (Sandbox Code Playgroud)
  1. 定义一个视频捕获设备从视频文件中读取帧并从中读取一次以获得视频帧的形状:
cap = cv2.VideoCapture(file)
ret, frame = cap.read()
h, w, _ = frame.shape
Run Code Online (Sandbox Code Playgroud)
  1. 定义一个fourcc (四字符代码),并定义一个视频作者列表;对应您要生成的每个视频:
fourcc = cv2.VideoWriter_fourcc(*"XVID")
writers = [cv2.VideoWriter(f"part{start}-{end}.avi", fourcc, 20.0, (w, h)) for start, end in parts]
Run Code Online (Sandbox Code Playgroud)
  1. 定义一个while循环,但在此之前,定义一个变量来跟踪 while 循环位于捕获设备中的哪一帧:
f = 0
while ret:
    f += 1
Run Code Online (Sandbox Code Playgroud)
  1. for在循环内使用循环while,循环遍历部件的开始帧和结束帧,使用该enumerate方法允许程序在需要时访问每次迭代所在部件的索引。如果循环之前定义的变量while位于该部分的开始和结束之间(包括),则将该帧写入相应的视频编写器(使用该方法提供的索引enumerate
    for i, (start, end) in enumerate(parts):
        if start <= f <= end:
            writers[i].write(frame)
    ret, frame = cap.read()
Run Code Online (Sandbox Code Playgroud)
  1. 最后,释放所有视频编写器和捕获设备:
for writer in writers:
    writer.release()

cap.release()
Run Code Online (Sandbox Code Playgroud)