【干貨】視頻文件抽幀(opencv和ffmpeg方式對比)

1 廢話不多說,直接上代碼

opencv方式

import time
import subprocess
import cv2, os
from math import ceildef extract_frames_opencv(video_path, output_folder, frame_rate=1):"""使用 OpenCV 從視頻中抽取每秒指定幀數的幀,并保存到指定文件夾。如果視頻長度不是整數秒,則會在最后一幀時補充空白圖像。參數:video_path (str): 輸入視頻文件的路徑。output_folder (str): 輸出幀圖像文件的文件夾路徑。frame_rate (int): 每秒抽取的幀數,默認為 1。返回:None"""start_time = time.time()# 創建輸出文件夾os.makedirs(output_folder, exist_ok=True)# 打開視頻文件cap = cv2.VideoCapture(video_path)# 獲取視頻長度和幀率fps = cap.get(cv2.CAP_PROP_FPS)total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))duration = total_frames / fps# 計算需要抽取的總幀數target_frames = int(duration * frame_rate)# 逐幀抽取圖像frame_idx = 0for i in range(target_frames):cap.set(cv2.CAP_PROP_POS_FRAMES, int(i * fps / frame_rate))ret, frame = cap.read()if ret:cv2.imwrite(os.path.join(output_folder, f"frame_{frame_idx:06d}.jpg"), frame)frame_idx += 1else:break# 如果最后一幀不是完整的一幀,則補充空白圖像if frame_idx < target_frames:for i in range(frame_idx, target_frames):blank_image = 255 * np.ones((int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)), int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), 3), dtype=np.uint8)cv2.imwrite(os.path.join(output_folder, f"frame_{i:06d}.jpg"), blank_image)# 釋放視頻捕獲對象cap.release()print(f"成功從視頻中抽取了 {target_frames} 幀, 一共耗時{time.time() - start_time}s")

ffmpeg方式

def extract_frames_ffmpeg(video_path, output_folder, frame_rate=1):"""使用 FFmpeg 從視頻中抽取每秒指定幀數的幀,并保存到指定文件夾。如果視頻長度不是整數秒,則會拋出異常。參數:video_path (str): 輸入視頻文件的路徑。output_folder (str): 輸出幀圖像文件的文件夾路徑。frame_rate (int): 每秒抽取的幀數,默認為 1。返回:None"""start_time = time.time()# 創建輸出文件夾os.makedirs(output_folder, exist_ok=True)# 獲取視頻長度command = ["ffprobe", "-v", "error", "-show_entries", "format=duration", "-of","default=nokey=1:noprint_wrappers=1", video_path]result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)if result.returncode != 0:raise ValueError("Failed to get video duration.")duration = float(result.stdout.decode().strip())# 四舍五入視頻長度到最接近的整數秒duration = round(duration)# 構建 FFmpeg 命令command = ["ffmpeg","-i", video_path,"-vf", f"fps={frame_rate}","-frames:v", "%d" % (ceil(duration * frame_rate)),os.path.join(output_folder, "frame_%06d.jpg")]# 執行 FFmpeg 命令subprocess.run(command, check=True)print(f"成功從視頻中抽取了 {ceil(duration * frame_rate)} 幀, 一共耗時{time.time() - start_time}s")

2 測試實驗對比

測試一個56s的mp4文件

extract_frames_opencv(video_path, output_folder, 1)
# 成功從視頻中抽取了 55 幀, 一共耗時10.131151914596558s
extract_frames_ffmpeg(video_path, output_folder, 1)
# 成功從視頻中抽取了 56 幀, 一共耗時8.075150966644287s

?1幀/s時,ffmpeg稍快2s

extract_frames_opencv(video_path, output_folder1, 5)
# 成功從視頻中抽取了 278 幀, 一共耗時54.822526931762695s
extract_frames_ffmpeg(video_path, output_folder2, 5)
# 成功從視頻中抽取了 280 幀, 一共耗時8.546468019485474s

5幀/s時,ffmpeg方式只增加0.5s,opencv增加了5倍時長

在大文件抽幀、或者抽幀頻率較高時,ffmpeg效率更高。

3 ffmpeg抽幀圖片更小?

對比了下抽幀圖片,分辨率一致,但是ffmpeg抽幀圖片好像小很多,為什么呢?

搜了下官方解釋:

FFmpeg 和 OpenCV 在抽取視頻幀并保存圖像時,可能會產生不同的結果,包括文件大小和圖像質量等。出現這種差異的原因主要有以下幾點:

  1. 編碼器選擇:

    • FFmpeg 默認使用 JPEG 編碼器,這種編碼方式通常可以生成較小的文件大小,但可能會略有些圖像質量損失。
    • OpenCV 默認使用無損的 PNG 編碼器,生成的文件通常會更大,但圖像質量更好。
  2. 色彩空間轉換:

    • FFmpeg 在抽取幀時,可能會將視頻的色彩空間轉換為更適合 JPEG 編碼的格式,例如 YUV 420。這種轉換可以進一步減小文件大小。
    • OpenCV 則可能會保留視頻原有的色彩空間,如 RGB,在保存為 PNG 時不進行額外的轉換。
  3. 圖像縮放和重采樣:

    • FFmpeg 在抽取幀時,可能會根據輸出分辨率對圖像進行縮放和重采樣,從而進一步優化文件大小。
    • OpenCV 則可能會直接保存原始分辨率的圖像,不進行任何縮放處理。

綜上所述,FFmpeg 在抽取視頻幀并保存為圖像時,通常會采取一些優化措施,如使用 JPEG 編碼、色彩空間轉換和圖像縮放等,從而生成相對較小的文件大小。而 OpenCV 則更傾向于保留原始的視覺質量,因此生成的圖像文件會相對更大。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/23635.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/23635.shtml
英文地址,請注明出處:http://en.pswp.cn/web/23635.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

linux系統使用達夢數據庫

在Linux系統中使用達夢數據庫&#xff0c;首先需要確保已經正確安裝了達夢數據庫軟件。以下是一個基本的使用示例&#xff0c;假設您已經安裝了達夢數據庫并且配置好了相關環境變量。 連接到數據庫&#xff1a; 使用 dsql 命令連接到數據庫 dsql -h hostname -u username -p…

寶貝,帶上WebAssembly,換個姿勢來優化你的前端應用

在你沒崛起之前,臉是用來丟的 大家好,我是柒八九。一個專注于前端開發技術/Rust及AI應用知識分享的Coder 此篇文章所涉及到的技術有 WebAssemblyRustWeb Worker(comlink)wasm-packPhotonffmpeg.wasm腳手架生成前端項目因為,行文字數所限,有些概念可能會一帶而過亦或者提供對…

BOM是什么東西

BOM&#xff08;Byte Order Mark&#xff0c;字節順序標記&#xff09;是一個Unicode字符&#xff0c;通常出現在文本文件的開頭。它的作用包括以下幾個方面&#xff1a; 1. 指示文件的編碼方式 BOM可以幫助軟件識別文本文件使用的字符編碼。不同的編碼方式可能會使用不同的B…

經濟與安全兼顧:茶飲店購買可燃氣體報警器的價格考量

可燃氣體報警器在如今的社會中扮演著至關重要的角色。它們用于檢測環境中的可燃氣體濃度&#xff0c;及早發現潛在的火災隱患&#xff0c;保護人們的生命和財產安全。 在這篇文章中&#xff0c;佰德將介紹可燃氣體報警器的安裝、檢定以及價格&#xff0c;通過實際案例和數據&a…

PCL 生成空間橢圓點云

目錄 一、算法原理二、代碼實現三、結果展示本文由CSDN點云俠原創,原文鏈接。如果你不是在點云俠的博客中看到該文章,那么此處便是不要臉的爬蟲。 一、算法原理 設橢圓在 X O Y XOY XOY平面上,參數方程為:

怎么保障TikTok直播網絡穩定?

TikTok&#xff0c;這個近年來風靡全球的社交媒體平臺&#xff0c;已成為電商引流的新方向&#xff0c;尤其是其直播功能。然而&#xff0c;對于打算進軍TikTok直播領域的商家和主播而言&#xff0c;確保網絡穩定無疑是首要任務。那么&#xff0c;TikTok直播專線究竟是什么呢&a…

牛啊后續:如何一行C#代碼實現解析類型的Summary注釋(可用于數據字典快速生成)...

前言&#xff1a;下午有小伙伴要求&#xff0c;讓我繼續做個解析實體類注釋信息的內容。所以我也順便加入進來。以下開始正文實戰操作&#xff1a; 項目需要勾選輸出api文檔文件。這樣就可以讓所有實體類的summary信息被寫入到輸出目錄下。如果有多個xml文件也沒關系&#xff0…

小程序 UI 風格美不勝收

小程序 UI 風格美不勝收 小程序 UI 風格美不勝收

PostgreSQL的視圖pg_stat_replication

PostgreSQL的視圖pg_stat_replication pg_stat_replication 是 PostgreSQL 提供的一個系統視圖&#xff0c;用于顯示主服務器上當前正在進行的復制會話的信息。它可以幫助數據庫管理員監控和管理主從復制的狀態&#xff0c;確保數據的正確同步和高可靠性。 pg_stat_replicati…

MyEclipse中properties文件中文亂碼(Unicode字符)解決辦法

程序代碼園發文地址&#xff1a;MyEclipse中properties文件中文亂碼&#xff08;Unicode字符&#xff09;解決辦法-程序代碼園小說,Java,HTML,Java小工具,程序代碼園,http://www.byqws.com/ ,MyEclipse中properties文件中文亂碼&#xff08;Unicode字符&#xff09;解決辦法htt…

Django學習三:views業務層中通過models對實體對象進行的增、刪、改、查操作。

文章目錄 前言一、Django ORM介紹二、項目快速搭建三、操作1、view.pya、增加操作b、刪除操作c、修改操作d、查詢操作 2、urls.py 前言 上接博文&#xff1a;Django學習二&#xff1a;配置mysql&#xff0c;創建model實例&#xff0c;自動創建數據庫表&#xff0c;對mysql數據…

一周發文9篇!MIMIC-IV數據庫周報(5.22~5.28)

重癥醫學數據庫&#xff08;MIMIC&#xff09;是由計算生理學實驗室開發的公開數據集&#xff0c;其中包括與數千個重癥監護病房入院相關的去識別化健康數據&#xff0c;致力于推動臨床信息學、流行病學和機器學習的研究。 MIMIC數據庫于2003年在美國國立衛生研究院的資助下&am…

2024上海初中生古詩文大會倒計時4個半月:單選題真題示例和獨家解析

現在距離2024年初中生古詩文大會還有4個半月時間&#xff0c;我們來看10道選擇題真題和詳細解析&#xff0c;了解古詩文大會的考察方式和知識點&#xff0c;從而更好地備考。 以下題目截取自我獨家制作的在線真題集&#xff0c;都是來自于歷屆真題&#xff0c;去重、合并后&am…

數據倉庫緩慢變化維介紹

緩慢變化維&#xff08;Slowly Changing Dimensions, SCD&#xff09;是數據倉庫設計中的一個重要概念&#xff0c;用于處理維度表中隨時間緩慢變化的屬性。維度表中的數據通常描述業務實體&#xff08;如客戶、產品、員工等&#xff09;&#xff0c;而這些實體的某些屬性&…

面試成功的不二法門:詳解Vue3答題章法

前言 面試題在網絡上有如海洋之深&#xff0c;對于同一知識點&#xff0c;每個人的理解也各有千秋。我們在面試中常常會遇到一個瞬息間腦海里一片空白的情況&#xff0c;其實這并不是因為我們不懂&#xff0c;而是因為我們在回答的時候缺乏一個清晰的思路。那么問題來了&#x…

《魔法與科技的融合:SpringBoot運維的現代傳說》

揭開了SpringBoot應用部署的神秘面紗。從云平臺的選型到Docker的容器化魔法&#xff0c;再到Kubernetes的集群力量&#xff0c;每一步都充滿了奇幻色彩。文章以輕松幽默的筆觸&#xff0c;帶領讀者穿梭于現代應用部署的各個角落&#xff0c;探索自動化部署的奧秘&#xff0c;學…

關于圖像過曝問題的排查思路

1、問題背景 讀者提問&#xff0c;圖像在室外遇到過曝的問題&#xff0c;有什么排查思路和改善方法。 2、問題分析 1&#xff09;先檢查一下sensor驅動&#xff0c;對照 sensor datasheet 確認下最小曝光行設置的是否正確&#xff0c; 因為室外高亮場景一般曝光行走的都比較…

【深度學習】PuLID: Pure and Lightning ID Customization via Contrastive Alignment

論文&#xff1a;https://arxiv.org/abs/2404.16022 代碼&#xff1a;https://github.com/ToTheBeginning/PuLID 文章目錄 AbstractIntroductionRelated WorkMethods Abstract 我們提出了一種新穎的、無需調整的文本生成圖像ID定制方法——Pure and Lightning ID customizatio…

微信好友朋友圈的三天、半年可見怎么破?方法拿走不謝

『Code掘金』問大家&#xff0c;有沒有這種經歷&#xff0c;當你想去翻某人的朋友圈時&#xff0c;對方設置成了3天可見&#xff0c;之前的內容沒法看到了。 不過沒關系&#xff01;今天『Code掘金』給大家分享一款導出朋友圈的工具&#xff0c;讓大家留住痕跡。 WechatMomen…

PostgreSQL中有沒有類似Oracle的dba_objects系統視圖

PostgreSQL中有沒有類似Oracle的dba_objects系統視圖 在PostgreSQL中&#xff0c;沒有一個完全集成了所有對象信息的視圖&#xff08;類似于Oracle中的DBA_OBJECTS&#xff09;。但是&#xff0c;PostgreSQL提供了一些系統目錄表和視圖&#xff0c;可以用來獲取數據庫對象的信…