1、VideoCapture播放視頻
#include <opencv2/opencv.hpp>
#include <iostream>using namespace std;
using namespace cv;int main()
{// 定義相關VideoCapture對象VideoCapture capture;// 打開視頻文件capture.open("1.avi");// 判斷視頻流讀取是否正確if (!capture.isOpened()){std::cout << "fail to open video!" << std::endl;return -1;}// 獲取視頻相關信息-幀像素寬高 int frameWidth = capture.get(cv::CAP_PROP_FRAME_WIDTH);int frameHeight = capture.get(cv::CAP_PROP_FRAME_HEIGHT);std::cout << "視頻中圖像的寬度為:" << frameWidth << std::endl;std::cout << "視頻中圖像的高度為: " << frameHeight << std::endl;// 獲取視頻相關信息-幀率double FrameRate = capture.get(cv::CAP_PROP_FPS);std::cout << "視頻幀率為:" << FrameRate << std::endl;// 獲取視頻相關信息-幀數long nTotalFrame = capture.get(cv::CAP_PROP_FRAME_COUNT);std::cout << "視頻總幀數為:" << nTotalFrame << std::endl;// 如果視頻讀取成功則創建視頻流cv::Mat frameImg;long nCount = 1;while (true){capture >> frameImg;//獲取當前幀圖像// 顯示當前幀if (!frameImg.empty()){imshow("frameImg", frameImg);if (char(waitKey(int(1000 / FrameRate)) == 'q')) // 按下鍵盤上q鍵退出break;}else{break;}nCount++;}// 視頻釋放capture.release();return 0;
}
waitKey(int(1000 / FrameRate)) 是用于在每一幀顯示后等待一定時間的語句。它的作用是在視頻播放時限制幀率,以使視頻以正常速度播放。
具體來說:
FrameRate 是視頻的幀率,表示每秒播放的幀數。
1000 / FrameRate 計算出每一幀需要顯示的時間(以毫秒為單位),即每幀之間的間隔時間。
waitKey 是一個 OpenCV 函數,它等待用戶在鍵盤上按鍵的時間。如果在指定的時間內按下鍵盤上的鍵,它會返回按鍵的 ASCII 值,否則返回 -1。
因此,waitKey(int(1000 / FrameRate)) 的作用是等待足夠的時間,以保持視頻的實際幀率接近指定的 FrameRate。這有助于以正常速度播放視頻,而不是以計算機能夠處理的最大速度。
如果把waitKey 換成Sleep延時會導致視頻卡死,因為Sleep僅僅只是簡單的延時,延時期間直接阻塞當前線程,而waitKey在延時的同時能夠使當前線程保持持續的響應,類似Qt中QCoreApplication::processEvents();防止界面假死操作。
當我們等待的時間小于int(1000 / FrameRate)能實現視頻快放的效果,當我們等待的時間大于int(1000 / FrameRate)能實現視頻慢放的效果。
2、VideoCapture調用攝像頭
#include <opencv2/opencv.hpp>
#include <iostream>using namespace std;
using namespace cv;int main()
{// 定義相關VideoCapture對象VideoCapture capture(0);// 判斷攝像頭是否打開if (!capture.isOpened()){std::cout << "fail to open video!" << std::endl;return -1;}// 獲取攝像頭相關信息-幀像素寬高 int frameWidth = capture.get(cv::CAP_PROP_FRAME_WIDTH);int frameHeight = capture.get(cv::CAP_PROP_FRAME_HEIGHT);std::cout << "攝像頭中圖像的寬度為:" << frameWidth << std::endl;std::cout << "攝像頭中圖像的高度為: " << frameHeight << std::endl;// 獲取攝像頭相關信息-幀率double FrameRate = capture.get(cv::CAP_PROP_FPS);std::cout << "攝像頭幀率為:" << FrameRate << std::endl;// 如果攝像頭打開成功則創建視頻流cv::Mat frameImg;long nCount = 1;while (true){capture >> frameImg;//獲取當前幀圖像// 顯示當前幀if (!frameImg.empty()){imshow("frameImg", frameImg);if (char(waitKey(30) == 'q')) // 按下鍵盤上q鍵退出break;}else{break;}nCount++;}// capture釋放capture.release();return 0;
}
上面代碼中獲取的攝像頭的幀率為0,可能的遠因如下:
攝像頭不支持幀率查詢:
不是所有的攝像頭都支持通過 cv::CAP_PROP_FPS 查詢幀率。在這種情況下,OpenCV 可能無法正確獲取幀率信息,返回0。
幀率信息尚未初始化:
在有些攝像頭中,幀率信息可能在攝像頭開始捕獲幀之前不可用。在你的代碼中,你可以嘗試在開始捕獲幀之后再獲取幀率信息。
攝像頭不支持固定幀率:
有些攝像頭可能不以固定的幀率工作,因此 OpenCV 無法準確地獲取幀率信息。
如果無法獲取攝像頭的幀率,那么waitKey需要設置一個固定的等待時間,一般為30Ms
