Linux:如何從影片中提取幀? (無損)

Linux:如何從影片中提取幀? (無損)

我讀過一些關於使用VLCMPlayerffmpeg等程序的答案和文章,但我見過的方法都不是「無損的」。他們不會捕捉每一幀。我想從影片中提取每一幀作為圖像(100% 質量,我不想丟失任何細節),因此理論上可以拍攝這些圖像並重新創建視頻文件,而無法區分原版(當然不包括缺少音頻的情況)。

如果我可以指定抓取畫面的開始和結束時間,那就加分了,這樣我就不必事先裁剪視訊檔案。

答案1

您可以將幀提取為 PNG(一種無損圖片壓縮格式)。例如,要擷取從 5 分鐘標記到 10 分鐘標記的影格:

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

答案2

有幾種工具應該能夠從電影檔案中提取所有幀:

AV轉換
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 -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).

當提取為 BMP 而不是 PNG 時,VLC 的性能也好得多

答案3

當使用 ffmpeg 執行此操作時,我發現經常需要使用該-vsync 0選項(例如,在處理 DVD 中的某些 VOB 檔案時):

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}'.")

相關內容