Python - 提取和保存视频帧
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33311153/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python - Extracting and Saving Video Frames
提问by GShocked
So I've followed this tutorialbut it doesn't seem to do anything. Simply nothing. It waits a few seconds and closes the program. What is wrong with this code?
所以我遵循了本教程,但它似乎没有做任何事情。简直没什么。它等待几秒钟并关闭程序。这段代码有什么问题?
import cv2
vidcap = cv2.VideoCapture('Compton.mp4')
success,image = vidcap.read()
count = 0
success = True
while success:
success,image = vidcap.read()
cv2.imwrite("frame%d.jpg" % count, image) # save frame as JPEG file
if cv2.waitKey(10) == 27: # exit if Escape is hit
break
count += 1
Also, in the comments it says that this limits the frames to 1000? Why?
另外,在评论中说这将帧数限制为 1000?为什么?
EDIT:
I tried doing success = True
first but that didn't help. It only created one image that was 0 bytes.
编辑:我尝试先做,success = True
但这没有帮助。它只创建了一个 0 字节的图像。
采纳答案by GShocked
So here was the final code that worked:
所以这是最终有效的代码:
import cv2
print(cv2.__version__)
vidcap = cv2.VideoCapture('big_buck_bunny_720p_5mb.mp4')
success,image = vidcap.read()
count = 0
while success:
cv2.imwrite("frame%d.jpg" % count, image) # save frame as JPEG file
success,image = vidcap.read()
print ('Read a new frame: ', success)
count += 1
So for this to work, you'll have to get some stuff. First, download OpenCV2. Then install this for Python2.7.x. Go to the FFmpeg folder inside the 3rd party folder (something like C:\OpenCV\3rdparty\ffmpeg
, but I'm not sure). Copy opencv_ffmpeg.dll
(or the x64 version if your python version is x64) and paste it into your Python folder (probably C:\Python27
). Rename it opencv_ffmpeg300.dll
if your OpenCV version is 3.0.0 (you can find it here), and change accordingly to your version. Btw, you must have your python folder in your environment path.
所以要让它起作用,你必须得到一些东西。首先,下载 OpenCV2。然后为 Python2.7.x安装它。转到第 3 方文件夹内的 FFmpeg 文件夹(类似于C:\OpenCV\3rdparty\ffmpeg
,但我不确定)。复制opencv_ffmpeg.dll
(或 x64 版本,如果您的 python 版本是 x64)并将其粘贴到您的 Python 文件夹中(可能是C:\Python27
)。opencv_ffmpeg300.dll
如果您的 OpenCV 版本是 3.0.0(您可以在此处找到),请重命名它,并根据您的版本进行相应更改。顺便说一句,你必须在你的环境路径中有你的python 文件夹。
回答by fireant
From heredownload this videoso we have the same video file for the test. Make sure to have that mp4 file in the same directory of your python code. Then also make sure to run the python interpreter from the same directory.
从这里下载此视频,以便我们获得相同的测试视频文件。确保该 mp4 文件位于 Python 代码的同一目录中。然后还要确保从同一目录运行 python 解释器。
Then modify the code, ditch waitKey
that's wasting time also without a window it cannot capture the keyboard events. Also we print the success
value to make sure it's reading the frames successfully.
然后修改代码,waitKey
浪费时间也没有窗口它无法捕获键盘事件。我们还打印该success
值以确保它成功读取帧。
import cv2
vidcap = cv2.VideoCapture('big_buck_bunny_720p_5mb.mp4')
success,image = vidcap.read()
count = 0
while success:
cv2.imwrite("frame%d.jpg" % count, image) # save frame as JPEG file
success,image = vidcap.read()
print('Read a new frame: ', success)
count += 1
How does that go?
这是怎么回事?
回答by Puja Sharma
After a lot of research on how to convert frames to video I have created this function hope this helps. We require opencv for this:
在对如何将帧转换为视频进行了大量研究后,我创建了此功能,希望对您有所帮助。为此,我们需要 opencv:
import cv2
import numpy as np
import os
def frames_to_video(inputpath,outputpath,fps):
image_array = []
files = [f for f in os.listdir(inputpath) if isfile(join(inputpath, f))]
files.sort(key = lambda x: int(x[5:-4]))
for i in range(len(files)):
img = cv2.imread(inputpath + files[i])
size = (img.shape[1],img.shape[0])
img = cv2.resize(img,size)
image_array.append(img)
fourcc = cv2.VideoWriter_fourcc('D', 'I', 'V', 'X')
out = cv2.VideoWriter(outputpath,fourcc, fps, size)
for i in range(len(image_array)):
out.write(image_array[i])
out.release()
inputpath = 'folder path'
outpath = 'video file path/video.mp4'
fps = 29
frames_to_video(inputpath,outpath,fps)
change the value of fps(frames per second),input folder path and output folder path according to your own local locations
根据自己的本地位置更改fps(每秒帧数),输入文件夹路径和输出文件夹路径的值
回答by Yuchao Jiang
The previous answers have lost the first frame. And it will be nice to store the images in a folder.
之前的答案已经丢失了第一帧。将图像存储在文件夹中会很好。
# create a folder to store extracted images
import os
folder = 'test'
os.mkdir(folder)
# use opencv to do the job
import cv2
print(cv2.__version__) # my version is 3.1.0
vidcap = cv2.VideoCapture('test_video.mp4')
count = 0
while True:
success,image = vidcap.read()
if not success:
break
cv2.imwrite(os.path.join(folder,"frame{:d}.jpg".format(count)), image) # save frame as JPEG file
count += 1
print("{} images are extacted in {}.".format(count,folder))
By the way, you can check the frame rate by VLC. Go to windows -> media information -> codec details
顺便说一下,您可以通过 VLC检查帧速率e。转到 windows -> 媒体信息 -> 编解码器详细信息
回答by SpaceFarmer2020
I am using Python via Anaconda's Spyder software. Using the original code listed in the question of this thread by @Gshocked, the code does not work (the python won't read the mp4 file). So I downloaded OpenCV 3.2 and copied "opencv_ffmpeg320.dll" and "opencv_ffmpeg320_64.dll" from the "bin" folder. I pasted both of these dll files to Anaconda's "Dlls" folder.
我通过 Anaconda 的 Spyder 软件使用 Python。使用@Gshocked 在该线程的问题中列出的原始代码,该代码不起作用(python 不会读取 mp4 文件)。所以我下载了 OpenCV 3.2 并从“bin”文件夹中复制了“opencv_ffmpeg320.dll”和“opencv_ffmpeg320_64.dll”。我将这两个 dll 文件都粘贴到 Anaconda 的“Dlls”文件夹中。
Anaconda also has a "pckgs" folder...I copied and pasted the entire "OpenCV 3.2" folder that I downloaded to the Anaconda "pckgs" folder.
Anaconda 也有一个“pckgs”文件夹……我将下载的整个“OpenCV 3.2”文件夹复制并粘贴到 Anaconda 的“pckgs”文件夹中。
Finally, Anaconda has a "Library" folder which has a "bin" subfolder. I pasted the "opencv_ffmpeg320.dll" and "opencv_ffmpeg320_64.dll" files to that folder.
最后,Anaconda 有一个“Library”文件夹,其中有一个“bin”子文件夹。我将“opencv_ffmpeg320.dll”和“opencv_ffmpeg320_64.dll”文件粘贴到该文件夹中。
After closing and restarting Spyder, the code worked. I'm not sure which of the three methods worked, and I'm too lazy to go back and figure it out. But it works so, cheers!
关闭并重新启动 Spyder 后,代码工作正常。我不确定这三种方法中的哪一种有效,我也懒得回去弄清楚。但它确实如此,干杯!
回答by XRarach
This is a tweak from previous answer for python 3.x from @GShocked, I would post it to the comment, but dont have enough reputation
这是对@GShocked 之前对python 3.x 的回答的调整,我会将其发布到评论中,但没有足够的声誉
import sys
import argparse
import cv2
print(cv2.__version__)
def extractImages(pathIn, pathOut):
vidcap = cv2.VideoCapture(pathIn)
success,image = vidcap.read()
count = 0
success = True
while success:
success,image = vidcap.read()
print ('Read a new frame: ', success)
cv2.imwrite( pathOut + "\frame%d.jpg" % count, image) # save frame as JPEG file
count += 1
if __name__=="__main__":
print("aba")
a = argparse.ArgumentParser()
a.add_argument("--pathIn", help="path to video")
a.add_argument("--pathOut", help="path to images")
args = a.parse_args()
print(args)
extractImages(args.pathIn, args.pathOut)
回答by Bhushan Babar
To extend on this question (& answer by @user2700065) for a slightly different cases, if anyone does not want to extract every frame but wants to extract frame every one second. So a 1-minute video will give 60 frames(images).
对于稍微不同的情况,扩展这个问题(@user2700065 的回答),如果有人不想提取每一帧但想要每秒提取一帧。所以 1 分钟的视频将提供 60 帧(图像)。
import sys
import argparse
import cv2
print(cv2.__version__)
def extractImages(pathIn, pathOut):
count = 0
vidcap = cv2.VideoCapture(pathIn)
success,image = vidcap.read()
success = True
while success:
vidcap.set(cv2.CAP_PROP_POS_MSEC,(count*1000)) # added this line
success,image = vidcap.read()
print ('Read a new frame: ', success)
cv2.imwrite( pathOut + "\frame%d.jpg" % count, image) # save frame as JPEG file
count = count + 1
if __name__=="__main__":
a = argparse.ArgumentParser()
a.add_argument("--pathIn", help="path to video")
a.add_argument("--pathOut", help="path to images")
args = a.parse_args()
print(args)
extractImages(args.pathIn, args.pathOut)
回答by Harsh Patel
This is Function which will convert most of the video formats to number of frames there are in the video. It works on Python3
with OpenCV 3+
这是将大多数视频格式转换为视频中的帧数的功能。它的工作原理上Python3
与OpenCV 3+
import cv2
import time
import os
def video_to_frames(input_loc, output_loc):
"""Function to extract frames from input video file
and save them as separate frames in an output directory.
Args:
input_loc: Input video file.
output_loc: Output directory to save the frames.
Returns:
None
"""
try:
os.mkdir(output_loc)
except OSError:
pass
# Log the time
time_start = time.time()
# Start capturing the feed
cap = cv2.VideoCapture(input_loc)
# Find the number of frames
video_length = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) - 1
print ("Number of frames: ", video_length)
count = 0
print ("Converting video..\n")
# Start converting the video
while cap.isOpened():
# Extract the frame
ret, frame = cap.read()
# Write the results back to output location.
cv2.imwrite(output_loc + "/%#05d.jpg" % (count+1), frame)
count = count + 1
# If there are no more frames left
if (count > (video_length-1)):
# Log the time again
time_end = time.time()
# Release the feed
cap.release()
# Print stats
print ("Done extracting frames.\n%d frames extracted" % count)
print ("It took %d seconds forconversion." % (time_end-time_start))
break
if __name__=="__main__":
input_loc = '/path/to/video/00009.MTS'
output_loc = '/path/to/output/frames/'
video_to_frames(input_loc, output_loc)
It supports .mts
and normal files like .mp4
and .avi
. Tried and Tested on .mts
files. Works like a Charm.
它支持.mts
和普通文件,如.mp4
和.avi
。对.mts
文件进行了尝试和测试。奇迹般有效。
回答by Bence K?vári
This function extracts images from video with 1 fps, IN ADDITION it identifies the last frame and stops reading also:
此功能以 1 fps 从视频中提取图像,此外,它还识别最后一帧并停止读取:
import cv2
import numpy as np
def extract_image_one_fps(video_source_path):
vidcap = cv2.VideoCapture(video_source_path)
count = 0
success = True
while success:
vidcap.set(cv2.CAP_PROP_POS_MSEC,(count*1000))
success,image = vidcap.read()
## Stop when last frame is identified
image_last = cv2.imread("frame{}.png".format(count-1))
if np.array_equal(image,image_last):
break
cv2.imwrite("frame%d.png" % count, image) # save frame as PNG file
print '{}.sec reading a new frame: {} '.format(count,success)
count += 1
回答by Rejoice T J
This code extract frames from the video and save the frames in .jpg formate
此代码从视频中提取帧并将帧保存为 .jpg 格式
import cv2
import numpy as np
import os
# set video file path of input video with name and extension
vid = cv2.VideoCapture('VideoPath')
if not os.path.exists('images'):
os.makedirs('images')
#for frame identity
index = 0
while(True):
# Extract images
ret, frame = vid.read()
# end of frames
if not ret:
break
# Saves images
name = './images/frame' + str(index) + '.jpg'
print ('Creating...' + name)
cv2.imwrite(name, frame)
# next frame
index += 1