Python - 提取和保存视频帧

时间:2015-10-23 20:48:20

标签: python python-2.7 opencv

所以我跟着this tutorial,但它似乎没有做任何事情。什么都没有。它等待几秒钟然后关闭程序。这段代码有什么问题?

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

另外,在评论中它说这会将帧限制为1000?为什么呢?

编辑: 我先尝试success = True,但这没有用。它只创建了一个0字节的图像。

12 个答案:

答案 0 :(得分:128)

here下载此video,以便我们为测试提供相同的视频文件。确保将该mp4文件放在python代码的同一目录中。然后还要确保从同一目录运行python解释器。

然后修改代码,抛出浪费时间的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

这是怎么回事?

答案 1 :(得分:34)

所以这是最终的代码:

import cv2
print(cv2.__version__)
vidcap = cv2.VideoCapture('big_buck_bunny_720p_5mb.mp4')
success,image = vidcap.read()
count = 0
success = True
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

所以要做到这一点,你必须得到一些东西。首先,download OpenCV2。然后是install this for Python 2.7.x.转到第三方文件夹内的ffmpeg文件夹(类似C:\OpenCV\3rdparty\ffmpeg,但我不确定)。复制opencv_ffmpeg.dll(如果您的python版本是x64,则复制x64版本)并将其粘贴到Python文件夹中(可能是C:\Python27)。如果您的opencv版本是3.0.0(您可以找到它here),请将其重命名为opencv_ffmpeg300.dll,并根据您的版本进行相应更改。顺便说一句,你必须拥有python folder in your environment path

答案 2 :(得分:19)

如果有人不想提取每一帧但想要每秒提取一次帧,那么要扩展这个问题(和@ user2700065的答案)稍微不同的情况。因此,1分钟的视频将提供60帧(图像)。

select  cast(CAST(435468867990778789.89 as decimal(35, 2))as float) as APPARENTWACTIMP
select  CAST(43546886799090787 as decimal(35, 2))as APPARENTWACTIMP
select  CAST(43546886799090787 as decimal(35, 2))as APPARENTWACTIMP
select CAST(43546886799090787.89 as float)

答案 3 :(得分:6)

经过大量关于如何将帧转换为视频的研究后,我创建了这个函数希望这会有所帮助。我们需要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)

根据您自己的本地位置更改fps(每秒帧数)的值,输入文件夹路径和输出文件夹路径

答案 4 :(得分:6)

这是来自@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)

答案 5 :(得分:5)

此代码从视频中提取帧并将帧保存在.jpg formate中

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

答案 6 :(得分:4)

之前的答案已经丢失​​了第一帧。将图像存储在一个文件夹中会很好。

# 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))

顺便说一句,您可以通过VLC检查帧鼠 e。转到窗口 - >媒体信息 - >编解码器详细信息

答案 7 :(得分:4)

这是将大多数视频格式转换为视频中的帧数的功能。它适用于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)

它支持.mts和普通文件,例如.mp4.avi。在.mts文件上试用和测试。奇迹般有效。

答案 8 :(得分:3)

此功能以1 fps从视频中提取图像,IN ADDITION它识别最后一帧并停止阅读:

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

答案 9 :(得分:2)

我通过Anaconda的Spyder软件使用Python。使用@Gshocked在该线程问题中列出的原始代码,代码不起作用(python不会读取mp4文件)。所以我下载了OpenCV 3.2并从“bin”文件夹中复制了“opencv_ffmpeg320.dll”和“opencv_ffmpeg320_64.dll”。我将这两个dll文件粘贴到Anaconda的“Dlls”文件夹中。

Anaconda还有一个“pckgs”文件夹...我复制并粘贴了我下载到Anaconda“pckgs”文件夹的整个“OpenCV 3.2”文件夹。

最后,Anaconda有一个“Library”文件夹,它有一个“bin”子文件夹。我将“opencv_ffmpeg320.dll”和“opencv_ffmpeg320_64.dll”文件粘贴到该文件夹​​中。

关闭并重新启动Spyder后,代码工作正常。我不确定这三种方法中哪一种有效,而且我懒得回去搞清楚。但它的确如此,欢呼!

答案 10 :(得分:1)

以下脚本将每半秒提取一次文件夹中所有视频的帧。 (适用于python 3.7)

import cv2
import os
listing = os.listdir(r'D:/Images/AllVideos')
count=1
for vid in listing:
    vid = r"D:/Images/AllVideos/"+vid
    vidcap = cv2.VideoCapture(vid)
    def getFrame(sec):
        vidcap.set(cv2.CAP_PROP_POS_MSEC,sec*1000)
        hasFrames,image = vidcap.read()
        if hasFrames:
            cv2.imwrite("D:/Images/Frames/image"+str(count)+".jpg", image) # Save frame as JPG file
        return hasFrames
    sec = 0
    frameRate = 0.5 # Change this number to 1 for each 1 second
    
    success = getFrame(sec)
    while success:
        count = count + 1
        sec = sec + frameRate
        sec = round(sec, 2)
        success = getFrame(sec)

答案 11 :(得分:0)

从视频演示中提取幻灯片/框架的原因有很多,尤其是在教育或会议相关视频的情况下。它使您无需观看整个视频即可访问学习笔记。 我已经多次遇到这个问题,所以我决定自己使用 python 为它创建一个解决方案。我已将代码开源,您可以轻松设置此工具并通过几个简单的步骤运行它。 请参阅此youtube video tutorial. 如何使用此工具的步骤。

  • 克隆 this project video2pdfslides
  • 通过运行“pip install -r requirements.txt”设置您的环境
  • 复制您的视频路径
  • 运行“python video2pdfslides.py ” 繁荣! pdf 幻灯片将在输出文件夹中可用 做笔记并享受!