Извлечение кадров из нескольких видео в течение цикла - PullRequest
1 голос
/ 23 марта 2020

Я пытаюсь извлечь кадры из нескольких видеофайлов в течение l oop, используя OpenCV. В Интернете я нашел несколько способов извлечения кадров из одного видео, но я изо всех сил пытаюсь запустить извлечение кадров в течение 1 oop.

Рабочий код для извлечения кадров из одного видео (видео Переменная):

cap=cv2.VideoCapture(video)
i=0
while (cap.isOpened()):    #
    ret, frame=cap.read()
    if ret == False:
        break
    cv2.imwrite(str(i) + '.jpg', frame)
    i+=1

cap.release()
cv2.destroyAllWindows()

Я хотел бы расширить это, чтобы включить для l oop, чтобы я мог перебирать несколько видео (переменные пути в видео) и извлекать все кадры. Я бы хотел, чтобы номер кадра из путей прохождения видео запускался один за другим, т. Е. Если в Видео 1 извлечено 30 кадров, кадры Видео 2 будут сохранены как 31, 32, 33 и др. c.

I. попытался поместить приведенный выше код в a для l oop, но, кажется, он работает вечно и ничего не сохраняет:

i=0 #place i outside of for-loop so it doesn't reset each iteration
for v in videos:
    cap=cv2.VideoCapture(v)
    while (cap.isOpened()):    #
        ret, frame=cap.read()
        if ret == False:
        break
        cv2.imwrite(str(i) + '.jpg', frame)
        i+=1

cap.release()
cv2.destroyAllWindows()

Кто-нибудь может помочь? Thankyou!

1 Ответ

1 голос
/ 23 марта 2020

Итерирование нескольких видеофайлов не настолько отличается от вашей реализации:

  • Используйте cap = cv2.VideoCapture(intput_filename) в начале каждой «итерации видеофайла». Как и вы.
  • Используйте cap.release() в конце каждой «итерации видеофайла».
    В размещенном вами коде похоже, что вы поставили cap.release() в неправильном месте.
  • Продолжайте показывать счетчик изображений (для указания последовательных имен файлов).
    Как и вы.

Я не уверен в вашем коде:

    if ret == False:
    break

Похоже, разрыв не имеет правильного отступа.


Я создал «автономный» пример кода, который:

  • Создает два синтетических c видеофайла (используется в качестве входных данных).
  • Перебор имен файлов видео (во внешнем l oop).
    • чтение кадров из видеофайла (во внутреннем l oop).
    • Запись кадров в файлы изображений JPEG.
    • Отображение видеокадров во время чтения (для тестирования).

Вот код:

import numpy as np
import cv2
import os

intput_filename1 = 'input_vid1.avi'
intput_filename2 = 'input_vid2.avi'

# List of video file names
intput_filenames = [intput_filename1, intput_filename2]

# Generate two synthetic video files to be used as input:
###############################################################################
width, height, n_frames = 640, 480, 30  # 30 frames, resolution 640x480

# Use motion JPEG codec (for testing)
synthetic_out = cv2.VideoWriter(intput_filename1, cv2.VideoWriter_fourcc(*'MJPG'), 25, (width, height))

for i in range(n_frames):
    img = np.full((height, width, 3), 60, np.uint8)
    cv2.putText(img, str(i+1), (width//2-100*len(str(i+1)), height//2+100), cv2.FONT_HERSHEY_DUPLEX, 10, (30, 255, 30), 20)  # Green number
    synthetic_out.write(img)

synthetic_out.release()

width, height, n_frames = 320, 240, 20 # 20 frames, resolution 320x240
synthetic_out = cv2.VideoWriter(intput_filename2, cv2.VideoWriter_fourcc(*'MJPG'), 25, (width, height))

for i in range(n_frames):
    img = np.full((height, width, 3), 60, np.uint8)
    cv2.putText(img, str(i+1), (width//2-50*len(str(i+1)), height//2+50), cv2.FONT_HERSHEY_DUPLEX, 5, (255, 30, 30), 10)  # Blue number
    synthetic_out.write(img)

synthetic_out.release()
###############################################################################


i = 1  # Images file counter

# Iterate file names:
for intput_filename in intput_filenames:
    cap = cv2.VideoCapture(intput_filename)

    # Keep iterating break
    while True:
        ret, frame = cap.read()  # Read frame from first video

        if ret:
            cv2.imwrite(str(i) + '.jpg', frame)  # Write frame to JPEG file (1.jpg, 2.jpg, ...)
            cv2.imshow('frame', frame)  # Display frame for testing
            i += 1 # Advance file counter
        else:
            # Break the internal loop when res status is False.
            break

        cv2.waitKey(100) #Wait 100msec (for debugging)

    cap.release() #Release must be inside the outer loop

cv2.destroyAllWindows()

Обновление:

Включите это в функцию:

def extract_multiple_videos(intput_filenames):
    """Extract video files into sequence of images.
       Intput_filenames is a list for video file names"""

    i = 1  # Counter of first video

    # Iterate file names:
    for intput_filename in intput_filenames:
        cap = cv2.VideoCapture(intput_filename)

        # Keep iterating break
        while True:
            ret, frame = cap.read()  # Read frame from first video

            if ret:
                cv2.imwrite(str(i) + '.jpg', frame)  # Write frame to JPEG file (1.jpg, 2.jpg, ...)
                cv2.imshow('frame', frame)  # Display frame for testing
                i += 1 # Advance file counter
            else:
                # Break the interal loop when res status is False.
                break

            cv2.waitKey(100) #Wait 100msec (for debugging)

        cap.release() #Release must be inside the outer loop
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...