AI視覺算法中的OpenCV API (二)

視頻寫入 (FourCC,?VideoWriter)?

1.?VideoWriter_fourcc?- 視頻編碼器四字符代碼

# OpenCV 3.x, 4.x
fourcc = cv2.VideoWriter_fourcc('M','J','P','G')fourcc = cv2.VideoWriter_fourcc(*'H264')fourcc = cv2.VideoWriter_fourcc(*'MJPG')
  • ?FourCC?: 代表 ?Four ?Character ?Code,是一個4字節的代碼,用于指定視頻流的編碼格式(Codec)?。它決定了視頻數據如何被壓縮。
  • 定義一個視頻編碼器(Codec)。視頻編碼器負責將連續的圖像幀壓縮成視頻流,顯著減小文件大小。

常用 FourCC 代碼

  • Video Codecs by FOURCC - fourcc.org
  • ?**'XVID'?: MPEG-4 編碼器。兼容性好,文件大小適中,是最常用**的選擇之一。
  • ?**'MJPG'**?: Motion-JPEG 編碼器。質量高,但文件非常大。
  • ?**'H264'?: H.264/AVC 編碼器。壓縮效率極高(文件小),質量好。?需要系統安裝 H.264 編碼器支持**?(如 Windows 上的 OpenH264 或 x264)。
  • ?**'MP4V'**?: MPEG-4 視頻編碼器。常用于?.mp4?文件。
  • ?**'AVC1'**?: 另一種表示 H.264 的方式。
  • ?**'DIVX'**?: DivX 編碼器(基于 MPEG-4)。

常用 FourCC 代碼與推薦的文件擴展名對應表

  • 文件擴展名?: 如?.avi,?.mp4,?.mov,用于指定容器格式(Container)?。容器是一個“包裝盒”,里面可以存放由特定編碼器壓縮的視頻流、音頻流、字幕等信息。
  • ?關鍵點在于:FourCC 編碼器和文件擴展名容器之間并沒有嚴格的、一對一的強制綁定關系,但存在廣泛認可和兼容的“最佳實踐”組合。?
  • 選擇一個不常見的組合(例如,在?.mp4?文件里使用?XVID?編碼)可能會導致某些播放器無法識別或播放。
FourCC 代碼推薦文件擴展名說明與常見用途
?**'XVID'**?.avi?最常用、兼容性最好的組合之一。XVID 是一個開源的 MPEG-4 視頻編碼器,生成的?.avi?文件可以在絕大多數設備和播放器上播放。文件大小和質量平衡得很好。
?**'MJPG'**?.aviMotion-JPEG 編碼,將每一幀都壓縮為一張 JPEG 圖片。?視頻質量很高,但文件體積非常大。常用于對質量要求極高且不介意文件大小的場景。
?**'H264'**?.mp4H.264/AVC 編碼,?當今最流行的編碼標準。壓縮效率極高(在相同質量下文件更小)。?注意?:OpenCV 可能需要系統安裝額外的開源庫(如 OpenH264 或 x264)才能使用此編碼器。
?**'AVC1'**?.mp4本質上是 H.264 編碼的另一種表示方法。行為與?'H264'?類似。
?**'MP4V'**?.mp4代表 MPEG-4 視頻(Part 2),與 H.264(Part 10)不同。壓縮效率通常不如 H.264,但兼容性可能更好。
?**'DIVX'**?.aviDivX 編碼器(也是基于 MPEG-4)。曾非常流行,現在多用于歷史遺留項目。
?**'FMP4'**?.mp4FFmpeg 的 MPEG-4 編碼器。如果你的 OpenCV 編譯時包含了 FFmpeg 支持,可能會用到。
?**'PIM1'**?.aviMPEG-1 編碼。非常老的格式,文件大,質量一般,現較少使用。
?**'X264'**?.mp4特指使用 x264 庫(一個優秀的開源 H.264 編碼器實現)。這通常需要從源碼自定義編譯 OpenCV 才能直接使用。

?選擇建議?:

  • ?為了最大兼容性?:使用 ?**'XVID'? + ?.avi**。這是 OpenCV 中最可靠、問題最少的輸出組合,幾乎總能成功。
  • ?為了更小的文件?:使用 ?**'H264'? 或'AVC1'?+ ?.mp4**。這是目前網絡傳輸和存儲的標準格式。但需要確保你的 OpenCV 環境支持它(否則會寫入失敗或生成空文件)。
  • 高質量,不介意文件大小:'MJPG' +??.avi**。

最重要的步驟?:

在編寫代碼時,始終檢查?VideoWriter?對象是否通過?isOpened()?方法成功打開。如果首選的高效編碼器(如 H.264)不可用,則回退到兼容性更好的編碼器(如 XVID)。這是一種良好的編程實踐,可以增強代碼的健壯性。

fourcc = cv2.VideoWriter_fourcc(*'H264')
out = cv2.VideoWriter('test.mp4', fourcc, 20.0, (640, 480))
if not out.isOpened():print("錯誤:無法使用 H264 編碼器!將回退到 XVID。")fourcc = cv2.VideoWriter_fourcc(*'XVID')out = cv2.VideoWriter('test.avi', fourcc, 20.0, (640, 480))

2.?VideoWriter?- 視頻寫入器

  • 創建一個對象,用于將連續的圖像幀寫入視頻文件。
out = cv2.VideoWriter(filename, fourcc, fps, frame_size[, isColor])

語法:

  • filename: 要保存的視頻文件路徑(包括擴展名,如?'output.avi'?或?'result.mp4')。
  • fourcc: 由?VideoWriter_fourcc?創建的編碼器對象。
  • fps: 視頻的幀率(每秒幀數)。應與輸入源(如攝像頭或視頻文件)的幀率匹配或根據需求設定。
  • frame_size: 視頻幀的尺寸,以元組形式表示?(width, height)。?必須與你要寫入的每一幀圖像的尺寸完全一致!??
  • isColor?(可選): 指定是否為彩色視頻。默認為?True。如果寫入灰度幀,設為?False?可能更高效。

?核心方法?:

  • ?**out.write(frame)**?: 將一幀圖像(frame,一個 NumPy 數組)寫入視頻文件。這是循環中最常用的方法。
  • ?**out.release()?: ?非常重要!?**? 在完成所有幀的寫入后,必須調用此方法來正確關閉視頻文件,釋放資源并確保文件完整可播。忘記調用會導致視頻文件損壞或無法播放。

3. 完整工作流程示例

import cv2# 1. 打開攝像頭 (輸入源)
cap = cv2.VideoCapture(0)  # 0 表示默認攝像頭# 2. 獲取攝像頭參數 (用于設置VideoWriter)
fps = cap.get(cv2.CAP_PROP_FPS)  # 獲取攝像頭幀率
# 如果攝像頭返回0,設置一個合理的幀率 (如20)
if fps <= 0:fps = 20.0
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))  # 獲取幀寬度
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))  # 獲取幀高度
frame_size = (width, height)# 3. 定義視頻編碼器 (FourCC) 和創建 VideoWriter 對象 (輸出)
fourcc = cv2.VideoWriter_fourcc(*'XVID')  # 使用XVID編碼器, 注意 '*' 解包
# 創建輸出文件 'output.avi'
out = cv2.VideoWriter('output.avi', fourcc, fps, frame_size)# 4. 循環處理每一幀
while cap.isOpened():# 讀取一幀ret, frame = cap.read()if not ret:print("無法從攝像頭讀取幀!")break# 例如:將幀轉換為灰度圖 (實際項目中替換為你的AI模型推理)processed_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)# 5. 將處理后的幀寫入輸出視頻文件out.write(processed_frame)  # 寫入處理后的幀# 6. (可選) 在本地顯示結果cv2.imshow('Processed Video', processed_frame)# 按 'q' 鍵退出if cv2.waitKey(1) & 0xFF == ord('q'):break# 7. 釋放資源 (非常重要!)
cap.release()  # 釋放攝像頭
out.release()  # 釋放VideoWriter,確保文件正確關閉
cv2.destroyAllWindows()  # 關閉所有窗口
print("視頻已保存為 'output.avi'")

4.詳解?cv2.waitKey(1):圖像刷新與鍵盤輸入的完美結合

  • cv2.waitKey(1)?是 OpenCV 圖像處理中一個看似簡單但極其重要的函數,它在實時應用中扮演著關鍵角色。
  • 函數原型:
  • retval = cv2.waitKey([, delay])
  • 參數:
  • delay: 等待鍵盤事件的時間(以毫秒為單位)。默認值為0。
  • 返回值:
  • retval: 返回按下的鍵的ASCII碼值。如果沒有按鍵被按下,則返回-1。

4.1 ?圖像窗口刷新機制?

  • cv2.waitKey()?是 OpenCV 窗口系統的事件處理核心
  • 調用此函數會強制刷新所有通過?cv2.imshow()?顯示的窗口?
  • 沒有這個調用,窗口會顯示為灰色或顯示舊內容,無法更新為最新圖像幀

4.2???鍵盤事件檢測?

  • 函數會檢測并返回最近按下的按鍵的 ASCII 碼值?
  • 參數?1?表示等待時間為 ?1 毫秒,這是一個非阻塞式等待
  • 在等待期間,它會檢查是否有按鍵事件發生

4.3?waitKey(0)?- 無限等待

  • 程序會暫停,直到用戶按下任意鍵
  • 常用于靜態圖像顯示場景
  • 示例:顯示一張圖片后等待用戶按鍵關閉窗口

4.4?waitKey(1)?- 短時等待(推薦用于實時應用)

  • 等待 ?1 毫秒后繼續執行
  • 在等待期間檢查按鍵事件
  • 保持程序流暢運行的同時響應按鍵
  • ?最佳實踐?:在視頻處理循環中使用

4.4??waitKey(25)?- 控制幀率

  • 等待 25 毫秒 ≈ 40 FPS (1000ms/25ms)
  • 可用于控制視頻播放速度

4.5?& 0xFF

  • waitKey()?返回的是 ?32 位整數?
  • 在 64 位系統上,高位可能包含無關數據
  • & 0xFF?操作只保留最低的 8 位(一個字節)
  • 確保我們只獲取有效的 ASCII 碼值

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

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

相關文章

分享| 2025年版AIGC數字人實驗室解決方案教學資源解析

AIGC數字人實驗室解決方案構建了涵蓋基礎層、平臺環境層與資源層的多層次教學架構&#xff0c;依托150平方米的實體空間與60人并行授課的規模化支持&#xff0c;為學生提供了技術實踐與創新的高效平臺。其教學資源體系覆蓋AIGC文本生成、圖像生成、數字人應用與智能體開發四大核…

內存大(巨)頁

一、大&#xff08;巨&#xff09;頁 大&#xff08;巨&#xff09;頁&#xff0c;很好理解&#xff0c;就是的大的頁。說這個大頁前&#xff0c;得先把計算機中內存的管理簡單說明一下&#xff0c;否則可能對于一些新手或者把操作系統中內存管理的方法的開發者不太友好。最早的…

langgraph astream使用詳解

langgraph中graph的astream&#xff08;stream&#xff09;方法分別實現異步&#xff08;同步&#xff09;流式應答&#xff0c;在langgraph-api服務也是核心方法&#xff0c;實現與前端的對接&#xff0c;必須要把這個方法弄明白。該方法中最重要的參數是stream_mode&#xff…

【C++】模板進階:非類型參數、模板特化與分離編譯

目錄 1. 非類型模板參數 2. 模板的特化 3. 分離編譯 1. 非類型模板參數 模板參數分類類型形參與非類型形參。 類型形參即&#xff1a;出現在模板參數列表中&#xff0c;跟在class或者typename之類的參數類型名稱。 非類型形參&#xff0c;就是用一個常量作為類(函數)模板…

棧-1047.刪除字符串中的所有相鄰重復項-力扣(LeetCode)

一、題目解析 1、反復執行重復項刪除操作 2、s僅由小寫英文字母組成 二、算法原理 該題并不難&#xff0c;難的是能不能想到用棧這個數據結構解題 解法&#xff1a;棧模擬 橫著看起來不好理解&#xff0c;我們把它豎起來&#xff0c;是不是和消消樂很類似&#xff0c;兩兩消…

【每日算法】移除元素 LeetCode

雙指針方法是解決數組或鏈表問題中非常高效的技巧之一&#xff0c;尤其適用于原地修改數組或減少時間復雜度的場景。以下是對雙指針方法的詳細講解。1. 雙指針方法的核心思想雙指針方法通常使用兩個指針&#xff08;或索引&#xff09;在數組或鏈表中協同工作&#xff0c;通過一…

Android 項目:畫圖白板APP開發(六)——分頁展示

本篇將介紹如何為我們的畫板應用添加分頁展示功能&#xff0c;讓用戶可以創建多個畫布并在它們之間輕松切換。這章沒有啥知識點的講解&#xff0c;主要介紹一下每頁保存的數據結構是什么樣的。 一、ListView 多頁數據的管理我們使用ListView。之前有文章講過ListView這里就不多…

智能眼鏡產品成熟度分析框架與評估

引言 當前(2025年9月12日),智能眼鏡(Smart Glasses)市場正處于快速演進階段,從早期的新奇設備向主流消費電子轉型。AI整合、AR顯示和多模態交互的進步推動了這一轉變。根據最新數據,2025年AI眼鏡發貨量預計達686萬臺,同比增長265%,全球市場規模從2024年的約19.3億美元…

(網絡編程)網絡編程套接字 UDP的socket API 代碼解析

網絡編程基礎 為什么需要網絡編程?--豐富的網絡資源 用戶在瀏覽器中,打開在線視頻網站,如優酷看視頻,實質是通過網絡,獲取到網絡上的一個視頻資源。與本地打開視頻文件類似,只是視頻文件這個資源的來源是網絡。 相比本地資源來說,網絡提供了更為豐富的網絡資源:所謂的網絡資源…

【STM32】狀態機(State Machine)

這篇博客介紹 狀態機&#xff08;State Machine&#xff09;&#xff0c;適合用于嵌入式開發、驅動開發、協議解析、按鍵識別等多種場景。 一、什么是狀態機&#xff08;State Machine&#xff09;&#xff1f; 狀態機&#xff08;State Machine&#xff09;是一種用于描述系統…

深度學習在離崗檢測中的應用

離崗檢測技術正逐步成為現代企業精細化管理和安全生產的重要工具。這項基于計算機視覺和人工智能的應用&#xff0c;通過自動化、實時化的監測方式&#xff0c;有效提升了工作紀律性和運營效率&#xff0c;為項目管理者和企業提供了創新的監管解決方案。在許多工作場景中&#…

Spring緩存(二):解決緩存雪崩、擊穿、穿透問題

1. 緩存穿透問題與解決方案 1.1 什么是緩存穿透 緩存穿透是指查詢一個不存在的數據&#xff0c;由于緩存中沒有這個數據&#xff0c;每次請求都會直接打到數據庫。 如果有惡意用戶不斷請求不存在的數據&#xff0c;就會給數據庫帶來巨大壓力。 這種情況下&#xff0c;緩存失去了…

PHP 與 WebAssembly 的 “天然隔閡”

WebAssembly&#xff08;簡稱 WASM&#xff09;是一種低級二進制指令格式&#xff0c;旨在為高級語言提供高性能的編譯目標&#xff0c;尤其在瀏覽器環境中實現接近原生的執行效率。它主要用于前端性能密集型場景&#xff08;如游戲引擎、視頻編解碼、3D 渲染等&#xff09;&am…

unity中通過拖拽,自定義scroll view中子物體順序

1.在每個content的子物體上掛載DragHandler腳本&#xff0c;并且添加Canvs Group組件&#xff0c;設置見圖2.DragHandler腳本內容&#xff1a;using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; using System.Collections.Generic; using System.Coll…

用 Matplotlib 繪制餅圖:從基礎語法到實戰美化,全面掌握分類數據可視化技巧

用 Matplotlib 繪制餅圖:從基礎語法到實戰美化,全面掌握分類數據可視化技巧 在數據分析與可視化的世界里,**“圖勝千言”**早已成為共識。而在眾多圖表類型中,餅圖(Pie Chart)以其直觀的比例展示方式,成為展示分類數據分布的常見選擇。無論是業務報表、用戶畫像,還是市…

基礎算法之二分算法 --- 2

大家好&#xff0c;不同的時間&#xff0c;相同的地點&#xff0c;時隔多日我們又見面了。繼上次的二分算法后&#xff0c;我們這次要來學習的是二分答案了。這個部分相較于前面的二分算法難度有相當的提升&#xff0c;希望大家有所準備。雖然難度增加了&#xff0c;但是博主還…

發揮nano banana的最大能力

1. 概述Nano Banana 簡介&#xff1a;Nano Banana 是 Google DeepMind 開發的 AI 圖像生成與編輯模型&#xff0c;集成在 Google Gemini 平臺中&#xff08;具體為 Gemini 2.5 Flash 版本&#xff09;。它以高效的圖像編輯能力聞名&#xff0c;尤其在角色一致性、光影理解和快速…

leetcode 面試題01.02判定是否互為字符重排

一、問題描述二、解題思路解法一&#xff1a;對s1和s2進行sort排序&#xff0c;返回s1是否等于s2&#xff1b;解法二&#xff1a;用哈希表分別來記錄s1和s2中字符出現的次數&#xff0c;統計完后&#xff0c;判斷兩個哈希表是否相等;三、代碼實現解法一&#xff1a;時間復雜度&…

Python Yolo8 物體識別

支持單張圖片/圖片目錄批量預標注 默認使用cuda GPU .env HTTP_PROXYhttp://192.168.2.109:10808 HTTPS_PROXYhttp://192.168.2.109:10808pyproject.toml [project] name "yolo-test" version "0.1.0" description "Add your description here&quo…

LeetCode100-234回文鏈表

本文基于各個大佬的文章上點關注下點贊&#xff0c;明天一定更燦爛&#xff01;前言Python基礎好像會了又好像沒會&#xff0c;所有我直接開始刷leetcode一邊抄樣例代碼一邊學習吧。本系列文章用來記錄學習中的思考&#xff0c;寫給自己看的&#xff0c;也歡迎大家在評論區指導…