Подтвердить что ты не робот

Python - Извлечение и сохранение видеокадров

Итак, я следовал этому уроку, но он, похоже, ничего не делает. Просто ничего. Он ждет несколько секунд и закрывает программу. Что не так с этим кодом?

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 сначала success = True но это не помогло. Он создал только одно изображение размером 0 байт.

4b9b3361

Ответ 1

Итак, вот последний код, который работал:

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

Так что, чтобы это сработало, вам нужно получить кое-что. Сначала загрузите OpenCV2. Затем установите это для Python 2.7.x. Перейдите в папку ffmpeg внутри сторонней папки (что-то вроде C:\OpenCV\3rdparty\ffmpeg, но я не уверен). Скопируйте opencv_ffmpeg.dll (или версию x64, если у вас версия Python x64) и вставьте ее в папку Python (вероятно, C:\Python27). Переименуйте его в opencv_ffmpeg300.dll если ваша версия opencv 3.0.0 (вы можете найти ее здесь), и измените ее в соответствии с вашей версией. Кстати, у вас должна быть папка python в вашем пути к среде.

Ответ 2

Отсюда загрузите это видео, чтобы у нас был тот же видеофайл для теста. Убедитесь, что этот файл 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

Как это происходит?

Ответ 3

Чтобы расширить этот вопрос (& answer by @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__":
    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)

Ответ 4

Это трюк из предыдущего ответа для python 3.x из @GShocked, я бы разместил его в комментарии, но не имел достаточной репутации

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

После много исследований о том, как конвертировать фреймы в видео, я создал эту функцию, надеюсь, что это поможет. Для этого нам требуется 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 (кадров в секунду), введите путь к папке и путь к папке вывода в соответствии с вашими локальными местоположениями

Ответ 6

Это функция, которая преобразует большинство видеоформатов в количество кадров в видео. Работает на 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 файлы .mts. Работает как Шарм.

Ответ 7

Предыдущие ответы потеряли первый кадр. И будет удобно хранить изображения в папке.

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

Кстати, вы можете проверить флажок фрейма крыла e от VLC. Перейти к окну → информация о мультимедиа → сведения о кодеке

Ответ 8

Этот код извлекает кадры из видео и сохраняет кадры в формате .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

Ответ 9

Эта функция извлекает изображения из видео со скоростью 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

Ответ 10

Я использую Python через программное обеспечение Anaconda Spyder. Используя исходный код, указанный в вопросе этого потока @Gshocked, код не работает (питон не будет читать файл mp4). Поэтому я загрузил OpenCV 3.2 и скопировал "opencv_ffmpeg320.dll" и "opencv_ffmpeg320_64.dll" из папки "bin". Я вставил оба эти файла dll в папку "Dlls" в Anaconda.

В Anaconda также есть папка "pckgs"... Я скопировал и вложил всю папку "OpenCV 3.2", которую я загрузил в папку "pckgs" Anaconda.

Наконец, у Anaconda есть папка "Библиотека", в которой есть подпапка "bin". Я вставил файлы "opencv_ffmpeg320.dll" и "opencv_ffmpeg320_64.dll" в эту папку.

После закрытия и перезапуска Spyder код работал. Я не уверен, какой из трех методов работал, и я слишком ленив, чтобы вернуться и понять это. Но он работает так, приветствует!