Linux: Как извлечь кадры из видео? (без потерь)

Linux: Как извлечь кадры из видео? (без потерь)

Я прочитал несколько ответов и статей об использовании таких программ, как VLC, MPlayer, ffmpeg, и т. д., но ни один из методов, которые я видел, не является "без потерь". Они не захватывают каждый отдельный кадр. Я хочу извлечь каждый кадр из видео как изображение (100% качество, я не хочу терять ни одной детали), поэтому теоретически можно взять эти изображения и воссоздать видеофайл, не имея возможности заметить разницу с оригиналом (исключая отсутствие звука, конечно).

Бонусным моментом будет то, что я могу указать начальное и конечное время захвата кадров, чтобы мне не пришлось заранее обрезать видеофайл.

решение1

Вы можете извлечь кадры как PNG, формат сжатия изображений без потерь. Например, чтобы извлечь кадры с отметки 5 мин до отметки 10 мин:

ffmpeg -ss 05:00 -i <input> -t 05:00 filename%05d.png

решение2

Существует несколько инструментов, которые могут извлечь все кадры из файла фильма:

авконв
avconv -i file.avi -f image2 Out%00d.jpg

ffmpeg
ffmpeg -i input.file thumb%04d.png -hide_banner

Также возможен экспорт в формат BMP, обработка которого занимает гораздо меньше времени, чем обработка PNG или JPG.

Также есть скрипт bash, который называетсяmov2frame.shкоторый пытается автоматизировать процесс извлечения FFMPEG.

Mplayer
mplayer -ao null -vo png input.file

или другой вариант:

mplayer -nosound -vo png:z=9 my_file.mp4

ВЛК Этот медиаплеер, судя по всему, может экспортировать наборы изображений с помощью своих фильтров, но это может вызвать проблемы, если только вы не используете его только один раз или у вас нет портативной версии.

  1. Создайте папку для хранения ваших кадров и скопируйте путь к ней. Для пользователей Mac OSX/Linux это должен быть полный путь (без ~).

  2. Нажмите «Инструменты» / «Настройки» в VLC.

  3. В разделе «Показать настройки» нажмите «все».

  4. В разделе «Видео» выберите «Фильтры». Отметьте «Фильтр видео сцены».

  5. Разверните «Фильтры» и выберите «Фильтр сцены»,

  6. Вставьте указанный ранее путь в «префикс пути к каталогу».

  7. Выберите долю кадров для кодирования в поле «коэффициент записи». 1/12 с выводом каждые 12, 1/1 экспортирует их все

  8. Нажмите «сохранить».

  9. Нажмите «Медиа» / «Открыть видео» и найдите свое видео. Терпеливо дождитесь, пока все это проиграется.

  10. Нажмите «Инструменты / Настройки». В разделе «Показать настройки» нажмите «Все». В разделе «Видео» выберите «Фильтры». Снимите флажок «Фильтр видео сцены». Нажмите «Сохранить». Это необходимо для того, чтобы VLC не создавал миниатюры при следующем воспроизведении видео. ссылка

Также, по-видимому, могут возникнуть некоторые потенциальные проблемы с правами администратора при первом запуске программы:

sudo vlc [sudo] password for mint16: VLC is not supposed to be run as root. Sorry. If you need to use real-time priorities and/or privileged TCP ports you can use vlc-wrapper (make sure it is Set-UID root and cannot be run by non-trusted users first).

VLC также работает намного лучше при извлечении в BMP вместо PNG.

решение3

При работе с ffmpeg я обнаружил, что мне часто приходится использовать эту -vsync 0опцию (например, при работе с некоторыми файлами VOB с DVD):

ffmpeg -i video.VOB -vsync 0 %06d.bmp

Если вы хотите также задать время начала и окончания, это будет выглядеть примерно так:

ffmpeg -i video.VOB -vsync 0 -ss 01:30 -to 01:40 %06d.bmp

решение4

Ниже представлен код в OpenCV, который помог мне извлечь кадры из видео.

import cv2
import os

# Replace 'your_video_file.mp4' with the path to your video file
video_path = 'your_video_file.mp4'

# Create a VideoCapture object
cap = cv2.VideoCapture(video_path)

# Check if the video file is opened successfully
if not cap.isOpened():
    print("Error: Could not open video file.")
    exit()

# Create a directory to store the frames
output_directory = 'frames'
os.makedirs(output_directory, exist_ok=True)

# Loop to read frames from the video
frame_count = 0
while True:
    # Read a frame from the video
    ret, frame = cap.read()

    # Check if the frame is read successfully
    if not ret:
        print("End of video.")
        break

    # Save the frame as an image file
    frame_filename = os.path.join(output_directory, f'frame_{frame_count:04d}.png')
    cv2.imwrite(frame_filename, frame)

    frame_count += 1

# Release the VideoCapture object
cap.release()

print(f"{frame_count} frames saved in '{output_directory}'.")

Связанный контент