как сделать видео из извлеченных кадров? - PullRequest
5 голосов
/ 30 мая 2020

Я извлек видеокадры в папку под названием «изображения». После сохранения изображений в моей папке я снова использую следующий код для создания видео. Я получаю видео, но кадры расположены в случайном порядке, как я могу расположить их в последовательном порядке? спасибо за пост

import cv2
import os


image_folder = 'images'
video_name = 'video.avi'

images = [img for img in os.listdir(image_folder) if img.endswith(".jpg")]
frame = cv2.imread(os.path.join(image_folder, images[0]))
height, width, layers = frame.shape

video = cv2.VideoWriter(video_name, 0, 1, (width,height))

for image in images:
    video.write(cv2.imread(os.path.join(image_folder, image)))

cv2.destroyAllWindows()
video.release()

посоветуйте пожалуйста, как это исправить? Я бы хотел, чтобы видео были с той же скоростью, что и исходное видео, а кадры были в последовательном порядке.

Ответы [ 6 ]

3 голосов
/ 08 июня 2020
  1. Распечатайте список images и посмотрите, в каком порядке размещены ваши изображения? Они отсортированы?
  2. Какое имя файла у ваших изображений? Полезно выбирать увеличивающееся число, например 00001.jpg и 00002.jpg вместо 1.jpg и 2.jpg, это может испортить сортировку.

  3. Сортировка изображений после чтения из os.listdir ('.'): Это пример с библиотекой pathlib.
for filename in sorted([e for e in path.iterdir() if e.is_file() and str(e).endswith(".png")]):
    print(filename)
    img = cv2.imread(str(filename))
    img_array.append(img)

Или просто используя: for filename in sorted(os.listdir(path))

0 голосов
/ 06 июня 2020

Это отлично работает со мной

import cv2
import os


image_folder = 'c:\\m\\'
video_name = 'c:\\m\\avideo.avi'

images = [img for img in os.listdir(image_folder) if img.endswith(".jpg")]


frame = cv2.imread(os.path.join(image_folder, images[0]))
height, width, layers = frame.shape

#1 fps
#video = cv2.VideoWriter(video_name, 0, 1, (width,height))


#25 fps
video = cv2.VideoWriter(video_name, 0, 25, (width,height))

for image in images:
    video.write(cv2.imread(os.path.join(image_folder, image)))

cv2.destroyAllWindows()
video.release()

материалы и результат Здесь

0 голосов
/ 02 июня 2020

Кажется, вам нужна естественная сортировка, поэтому попробуйте natsort library:

from natsort import natsorted

images = natsorted(images)

Установить с помощью pip:

pip install natsort
0 голосов
/ 01 июня 2020

Попробуйте glob для вывода списка файлов и сортировки списка. Я отредактировал ваш код с помощью glob. (Предполагая, что ваши имена файлов изображений находятся в нужной последовательности)

import cv2
import os
import glob

video_name = 'video.avi'

images = glob.glob('images/*.jpg')
images.sort()

frame = cv2.imread(images[0])
height, width, layers = frame.shape

video = cv2.VideoWriter(video_name, 0, 1, (width,height))

for image in images:
    video.write(cv2.imread(image))

cv2.destroyAllWindows()
video.release() 
0 голосов
/ 30 мая 2020

Если по вашему требованию вы должны хранить фреймы, попробуйте это

import cv2
import os


image_folder = 'images'
video_name = 'video.avi'

images = [img for img in os.listdir(image_folder) if img.endswith(".jpg")]
frame = cv2.imread(os.path.join(image_folder, images[0]))
height, width, layers = frame.shape

video = cv2.VideoWriter(video_name, 0, 1, (width,height))

for i in range(len(images)):
    video.write(cv2.imread(os.path.join(image_folder, 'a'+str(i)+'.jpg')))

cv2.destroyAllWindows()
video.release()
0 голосов
/ 30 мая 2020

Может быть, вы могли бы попробовать вместо сохранения изображений и их повторной загрузки, сделать захват видео из исходного видео и передать его объекту out (demo_output.avi в данном случае) ... что-то вроде этого:

import cv2

cap = cv2.VideoCapture('path to video/video.mp4')

fourcc = cv2.VideoWriter_fourcc(*'XVID')
ret, frame = cap.read()
fps_video=cap.get(cv2.CAP_PROP_FPS)
height,width = frame.shape[:2]
out = cv2.VideoWriter('demo_output.avi',fourcc, fps_video, (width,height)) ##can be set with your width,height values




while ret:
    frame = cv2.resize(frame, None, fx=1.0, fy=1.0, interpolation=cv2.INTER_AREA)

    out.write(frame)
    ret, frame = cap.read()

cap.release()
out.release()
cv2.destroyAllWindows()      

ОБНОВЛЕНИЕ:

Если вам нужны изображения, а затем сохранить видео файл:

import cv2
import os
import numpy as np

vidcap = cv2.VideoCapture('path to video/video.mp4')
success,image = vidcap.read()
fps_video = vidcap.get(cv2.CAP_PROP_FPS)
height,width = image.shape[:2]
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

vidcap.release()
lista = [[x[5:-4],x] for x in os.listdir() if x.endswith('jpg')]

result=[]
for x in lista:
    t1,t2 = np.int(x[0]),x[1]
    result.append([t1,t2])

result.sort()

#recording video back
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('demo_output.avi',fourcc, fps_video, (width,height)) ##can be set with your width,height values

for img in result:
    frame = cv2.imread(img[1])
    out.write(frame)
out.release()
...