1. 引言
大家都來寫OpenCV😊,學的好開心!
2. 視頻基礎與OpenCV簡介
2.1 視頻的定義
視頻(Video)是由一系列靜態圖像(幀)以一定速率連續播放形成的動態影像。其本質是利用人眼的視覺暫留效應,將靜止的畫面轉化為連續的動態內容。視頻通常包含畫面、音頻軌道,有時還包括字幕、特效等信息。
視頻的主要應用領域
- 影視娛樂
- 教育培訓
- 安防監控
- 通信與直播
- 自動駕駛與智能交通
2.2 OpenCV簡介
OpenCV(Open Source Computer Vision Library)是一個跨平臺的計算機視覺和機器學習軟件庫,支持C++、Python等多種語言。它為視頻處理、圖像分析、機器學習等任務提供了高效的算法和接口。
3. 視頻讀寫
3.1 視頻的基本操作
圖片轉視頻
將多張圖片按順序和時間間隔組合,添加轉場、音樂、字幕等,生成視頻。例如旅游紀念視頻、照片合成動畫等。
視頻轉圖片
從視頻中提取特定幀作為圖片,用于精彩瞬間捕捉、視頻封面、畫面分析等。例如電影劇照、運動分析等。
3.2 OpenCV讀取視頻詳解
OpenCV通過
cv::VideoCapture
類實現視頻文件或攝像頭流的讀取。
代碼示例
#include?<opencv2/opencv.hpp>#include?<iostream>using?namespace?cv;using?namespace?std;int?main(){//1?指定視頻文件路徑創建VideoCapture?VideoCapture?cap("C:/Users/Administrator/Desktop/video/cat.mp4");//2?判斷是否成功打開視頻if?(!cap.isOpened()){cout?<<?"視頻打開失敗!"?<<?endl;return?-1;}//3?獲取視頻基本信息double?width?=?cap.get(CAP_PROP_FRAME_WIDTH);double?height?=?cap.get(CAP_PROP_FRAME_HEIGHT);double?count?=?cap.get(CAP_PROP_FRAME_COUNT);double?fps?=?cap.get(CAP_PROP_FPS);cout?<<?"視頻的寬="?<<?width?<<?endl;cout?<<?"視頻的高="?<<?height?<<?endl;cout?<<?"視頻的總幀數="?<<?count?<<?endl;cout?<<?"視頻的fps="?<<?fps?<<?endl;//4?逐幀讀取視頻并展示Mat?frame;width?=?width?*?0.2;height?=?height?*?0.2;while?(true){cap?>>?frame;if?(frame.empty()){break;}Mat?dst;resize(frame,?dst,?Size(width,height));Mat?gray;cvtColor(dst,?gray,?COLOR_BGR2GRAY);imshow("video",?dst);imshow("gray?video",?gray);if?(waitKey(1000/fps)?==?27){break;}}//5?釋放資源cap.release();destroyAllWindows();return?0;}
視頻屬性表
屬性名 說明 類型 示例值 CAP_PROP_FRAME_WIDTH 視頻幀寬度(像素) double 1920 CAP_PROP_FRAME_HEIGHT 視頻幀高度(像素) double 1080 CAP_PROP_FPS 視頻幀率(幀/秒) double 30.0 CAP_PROP_FRAME_COUNT 視頻總幀數 double 2500 CAP_PROP_POS_FRAMES 當前幀索引(從0開始) double 100 CAP_PROP_POS_MSEC 當前時間戳(毫秒) double 3500.0 CAP_PROP_FOURCC 編解碼器FourCC代碼 double 1196444237 CAP_PROP_BRIGHTNESS 攝像頭亮度(僅攝像頭有效) double 0.5 CAP_PROP_CONTRAST 攝像頭對比度 double 0.3 CAP_PROP_SATURATION 攝像頭飽和度 double 0.8 CAP_PROP_EXPOSURE 攝像頭曝光值 double -4.0 CAP_PROP_AUTOFOCUS 自動對焦是否開啟 double 1.0
3.3 視頻保存與編碼格式
OpenCV通過
cv::VideoWriter
類實現視頻錄制與保存。FourCC編碼格式
'MJPG'
:Motion-JPEG,常用于.avi文件'XVID'
:XVID編碼,適用于.avi文件'H264'
:H.264編碼,適用于.mp4文件(需安裝OpenH264庫)
視頻保存代碼示例
void?writeVideo(VideoCapture&?cap){cv::String?fileName?=?"C:/Users/Administrator/Desktop/video/temp.avi";int?fourcc?=?VideoWriter::fourcc('M',?'J',?'P',?'G');double?width?=?cap.get(CAP_PROP_FRAME_WIDTH);double?height?=?cap.get(CAP_PROP_FRAME_HEIGHT);double?fps?=?cap.get(CAP_PROP_FPS);VideoWriter?writer(fileName,fourcc,fps,Size(width,height),false);if?(!writer.isOpened()){cout?<<?"視頻文件打開失敗!"?<<?endl;return;}Mat?src;while?(true){cap?>>?src;if?(src.empty()){break;}Mat?gray;cvtColor(src,?gray,?COLOR_BGR2GRAY);writer.write(gray);if?(waitKey(30)?==?27){break;}}cout?<<?"已經成功保存視頻"?<<?endl;writer.release();}
視頻保存流程
- 創建VideoWriter對象,指定文件名、編碼格式、幀率、分辨率、是否彩色
- 判斷文件是否成功打開
- 逐幀寫入視頻
- 釋放資源
4. 視頻追蹤
4.1 視頻追蹤定義與應用
視頻追蹤(Video Tracking)是指在連續的視頻幀中定位并跟蹤特定目標(如人臉、車輛)的運動軌跡。廣泛應用于:
- 安防監控
- 自動駕駛
- 人機交互
- 運動分析
視頻追蹤流程
- 目標檢測:識別并定位目標
- 特征提取:提取目標特征(顏色、形狀、紋理等)
- 模型更新:適應目標外觀變化
- 位置預測與校正:預測目標位置并校正
4.2 Meanshift算法原理與實現
Meanshift算法定義
Meanshift是一種基于密度估計的非參數化聚類算法,廣泛用于目標追蹤。其核心思想是通過迭代將搜索窗口向目標區域的顏色直方圖分布中心移動,實現目標定位。
直方圖反向投影
直方圖反向投影是指將目標區域的顏色分布映射到整幅圖像,得到每個像素屬于目標的概率圖。
反向投影流程
- 選定目標區域,計算HSV直方圖
- 對每一幀計算直方圖
- 對比直方圖,得到相似度
- 生成概率圖,作為Meanshift輸入
Meanshift代碼解析
void?meanshiftTest(VideoCapture&?cap){Mat?frame;cap?>>?frame;if?(frame.empty()){cout?<<?"無法讀取視頻幀"?<<?endl;return;}Rect?roi?=?selectROI("請選擇追蹤目標",frame,false);if?(roi.width?<=?0?||?roi.height?<=?0){cout?<<?"已取消選擇roi區域"?<<?endl;return;}Mat?target?=?frame(roi).clone();imshow("target",?target);Mat?hsv_target;cvtColor(target,?hsv_target,?COLOR_BGR2HSV);Mat?mask;inRange(hsv_target,?Scalar(0,?30,?0),?Scalar(180,?255,?255),?mask);int?histSize?=?180;float?range[]?=?{?0,180?};const?float*?histRange?=?{?range?};Mat?hist_target;int?channels[]?=?{?0?};calcHist(&hsv_target,?1,?channels,?mask,?hist_target,?1,?&histSize,?&histRange);normalize(hist_target,?hist_target,?0,255,?NORM_MINMAX);TermCriteria?criteria(TermCriteria::EPS?|?TermCriteria::COUNT,?10,?1);while?(true){cap?>>?frame;if?(frame.empty()){break;}Mat?hsvFrame;cvtColor(frame,?hsvFrame,?COLOR_BGR2HSV);Mat?back;calcBackProject(&hsvFrame,?1,?channels,?hist_target,?back,&histRange);meanShift(back,?roi,?criteria);rectangle(frame,?roi,?Scalar(0,?255,?0));imshow("視頻追蹤",?frame);if?(waitKey(30)?==?27){break;}}}
關鍵函數說明
selectROI
:手動選擇目標區域calcHist
:計算目標區域顏色直方圖normalize
:歸一化直方圖calcBackProject
:計算反向投影概率圖meanShift
:執行Meanshift迭代,更新目標位置
TermCriteria參數說明
參數類型 說明 TermCriteria::EPS 收斂到指定精度時終止 TermCriteria::COUNT 達到最大迭代次數時終止 10 最大迭代次數 1 精度閾值(像素)
4.3 Camshift算法原理與實現
Camshift算法定義
Camshift(Continuously Adaptive Mean Shift)是Meanshift的改進版,能自適應調整搜索窗口的大小和方向,適合目標尺度和方向變化明顯的場景。
Camshift實現流程
- 初始化目標模型,計算顏色直方圖
- 定義搜索窗口
- 執行Meanshift迭代
- 根據目標分布調整窗口大小和方向
- 更新窗口位置,輸出最佳擬合橢圓
Camshift代碼解析
void?camshiftTest(VideoCapture&?cap){Mat?frame;cap?>>?frame;if?(frame.empty()){cout?<<?"無法讀取視頻幀"?<<?endl;return;}Rect?roi?=?selectROI("請選擇追蹤目標",?frame,?false);if?(roi.width?<=?0?||?roi.height?<=?0){cout?<<?"已取消選擇roi區域"?<<?endl;return;}Mat?target?=?frame(roi).clone();imshow("target",?target);Mat?hsv_target;cvtColor(target,?hsv_target,?COLOR_BGR2HSV);Mat?mask;inRange(hsv_target,?Scalar(0,?60,?32),?Scalar(180,?255,?255),?mask);int?histSize?=?180;float?range[]?=?{?0,180?};const?float*?histRange?=?{?range?};Mat?hist_target;int?channels[]?=?{?0?};calcHist(&hsv_target,?1,?channels,?mask,?hist_target,?1,?&histSize,?&histRange);normalize(hist_target,?hist_target,?0,?255,?NORM_MINMAX);TermCriteria?criteria(TermCriteria::EPS?|?TermCriteria::COUNT,?10,?1);while?(true){cap?>>?frame;if?(frame.empty()){break;}Mat?hsvFrame;cvtColor(frame,?hsvFrame,?COLOR_BGR2HSV);Mat?back;calcBackProject(&hsvFrame,?1,?channels,?hist_target,?back,?&histRange);RotatedRect?trackBox?=?CamShift(back,?roi,?criteria);rectangle(frame,?roi,?Scalar(0,?255,?0));//ellipse(frame,?trackBox,?Scalar(0,?0,?255),?2);imshow("視頻追蹤",?frame);if?(waitKey(30)?==?27){break;}}}
Camshift返回值說明
RotatedRect
:最佳擬合橢圓,包含中心位置、大小、旋轉角度
4.4 Meanshift與Camshift對比分析
算法 窗口大小 適應目標變化 適用場景 實時性 輸出信息 Meanshift 固定 不適應 目標大小不變 極高 位置 Camshift 自適應 適應 目標尺度/方向變化 較高 位置+大小+方向
選擇建議
- 優先Meanshift:目標大小和方向基本不變,對實時性要求極高
- 優先Camshift:目標尺度或方向變化明顯,需要輸出目標朝向信息
5. 攝像頭實時處理
5.1 實時處理定義與應用
攝像頭實時處理是指通過攝像頭捕獲視頻流,對每一幀圖像進行即時處理和分析,并實時顯示或反饋結果。應用包括:
- 實時人臉檢測
- 運動物體追蹤
- 增強現實(AR)效果
5.2 攝像頭實時捕獲與處理流程
- 打開攝像頭(
cv::VideoCapture
)- 逐幀讀取視頻流
- 對每一幀進行處理(如灰度化、邊緣檢測等)
- 實時顯示處理結果(
cv::imshow
)- 釋放資源
攝像頭實時處理代碼解析
void?cameraTest(){VideoCapture?cap(0);cap.set(CAP_PROP_FRAME_WIDTH,680);cap.set(CAP_PROP_FRAME_HEIGHT,?480);Mat?frame;while?(true){cap?>>?frame;if?(frame.empty()){cout?<<?"無法讀取攝像頭幀"?<<?endl;break;}Mat?gray;cvtColor(frame,?gray,?COLOR_BGR2GRAY);imshow("實時幀",?frame);imshow("灰度幀",?gray);if?(waitKey(30)?==?27){break;}}cap.release();destroyAllWindows();}
5.3 實時視頻處理應用舉例
5.3.1 實時跟蹤
利用Meanshift或Camshift算法對攝像頭捕獲內容進行實時目標跟蹤。
void?camShiftCameraTest(){VideoCapture?cap(0);Mat?frame;cap?>>?frame;if?(frame.empty()){cout?<<?"無法讀取視頻幀"?<<?endl;return;}Rect?roi?=?selectROI("請選擇追蹤目標",?frame,?false);if?(roi.width?<=?0?||?roi.height?<=?0){cout?<<?"已取消選擇roi區域"?<<?endl;return;}Mat?target?=?frame(roi).clone();imshow("target",?target);Mat?hsv_target;cvtColor(target,?hsv_target,?COLOR_BGR2HSV);Mat?mask;inRange(hsv_target,?Scalar(0,?60,?32),?Scalar(180,?255,?255),?mask);int?histSize?=?180;float?range[]?=?{?0,180?};const?float*?histRange?=?{?range?};Mat?hist_target;int?channels[]?=?{?0?};calcHist(&hsv_target,?1,?channels,?mask,?hist_target,?1,?&histSize,?&histRange);normalize(hist_target,?hist_target,?0,?255,?NORM_MINMAX);TermCriteria?criteria(TermCriteria::EPS?|?TermCriteria::COUNT,?10,?1);while?(true){cap?>>?frame;if?(frame.empty()){break;}Mat?hsvFrame;cvtColor(frame,?hsvFrame,?COLOR_BGR2HSV);Mat?back;calcBackProject(&hsvFrame,?1,?channels,?hist_target,?back,?&histRange);RotatedRect?trackBox?=?CamShift(back,?roi,?criteria);rectangle(frame,?roi,?Scalar(0,?255,?0));//ellipse(frame,?trackBox,?Scalar(0,?0,?255),?2);imshow("視頻追蹤",?frame);if?(waitKey(30)?==?27){break;}}destroyAllWindows();}
5.3.2 實時邊緣檢測
通過攝像頭實時捕獲視頻,使用Canny算法提取圖像邊緣。
?????
void?cameraCannyTest(){VideoCapture?cap(0);cap.set(CAP_PROP_FRAME_WIDTH,?680);cap.set(CAP_PROP_FRAME_HEIGHT,?480);Mat?frame;while?(true){cap?>>?frame;if?(frame.empty()){cout?<<?"無法讀取攝像頭幀"?<<?endl;break;}Mat?gray;cvtColor(frame,?gray,?COLOR_BGR2GRAY);Mat?blur;GaussianBlur(gray,?blur,?Size(3,?3),1.5);Mat?dst;Canny(blur,?dst,?50,?150);imshow("實時幀",?frame);imshow("邊緣檢測",?dst);if?(waitKey(30)?==?27){break;}}cap.release();destroyAllWindows();}
5.3.3 其他應用
攝像頭實時捕獲內容不僅能做跟蹤和邊緣檢測,還可用于:
- 實時人臉識別
- 實時手勢識別
- 實時目標分割
- 實時AR效果疊加
6. 總結與展望
好學,愛學,還得學!