.png)
Я прочитал несколько ответов и статей об использовании таких программ, как 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
ВЛК Этот медиаплеер, судя по всему, может экспортировать наборы изображений с помощью своих фильтров, но это может вызвать проблемы, если только вы не используете его только один раз или у вас нет портативной версии.
Создайте папку для хранения ваших кадров и скопируйте путь к ней. Для пользователей Mac OSX/Linux это должен быть полный путь (без ~).
Нажмите «Инструменты» / «Настройки» в VLC.
В разделе «Показать настройки» нажмите «все».
В разделе «Видео» выберите «Фильтры». Отметьте «Фильтр видео сцены».
Разверните «Фильтры» и выберите «Фильтр сцены»,
Вставьте указанный ранее путь в «префикс пути к каталогу».
Выберите долю кадров для кодирования в поле «коэффициент записи». 1/12 с выводом каждые 12, 1/1 экспортирует их все
Нажмите «сохранить».
Нажмите «Медиа» / «Открыть видео» и найдите свое видео. Терпеливо дождитесь, пока все это проиграется.
Нажмите «Инструменты / Настройки». В разделе «Показать настройки» нажмите «Все». В разделе «Видео» выберите «Фильтры». Снимите флажок «Фильтр видео сцены». Нажмите «Сохранить». Это необходимо для того, чтобы 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}'.")