所以我遵循这个教程,但它似乎没有做任何事情。只是没有。它等待几秒钟并关闭程序。这段代码有什么问题?

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字节的图像。


当前回答

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

蟒蛇也有一个“pckgs”文件夹…我复制并粘贴了整个“OpenCV 3.2”文件夹,我下载到Anaconda“pckgs”文件夹。

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

关闭并重新启动Spyder后,代码正常工作。我不确定这三种方法中哪一种有效,我也懒得回去研究。但它确实有效,干杯!

其他回答

这个函数以1帧/秒的速度从视频中提取图像,此外,它还识别最后一帧并停止读取:

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

从这里下载这个视频,这样我们就有了相同的测试视频文件。确保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

这是怎么回事?

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

蟒蛇也有一个“pckgs”文件夹…我复制并粘贴了整个“OpenCV 3.2”文件夹,我下载到Anaconda“pckgs”文件夹。

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

关闭并重新启动Spyder后,代码正常工作。我不确定这三种方法中哪一种有效,我也懒得回去研究。但它确实有效,干杯!

下面的脚本将提取帧每半秒的所有视频在文件夹。(适用于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)

在稍微不同的情况下扩展这个问题(@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)