一、視頻讀取
cv::VideoCapture既支持視頻文件的讀取,也支持從攝像機(jī)中視頻的讀取。cv::VideoCapture對(duì)象的創(chuàng)建方式有以下三種:
方式一:
?? ?cv::VideoCapture capture(
?? ?const string& filename, // 輸入視頻文件路徑名
?? ?);
方式二:
?? ?cv::VideoCapture capture(
?? ?int device // 輸入攝像機(jī)視頻捕捉設(shè)備 id
?? ?);
從攝像機(jī)中讀取視頻,這種情況下,我們會(huì)給出一個(gè)標(biāo)識(shí)符,用于表示我們想要訪問的攝像機(jī),及其與操作系統(tǒng)的握手方式。對(duì)于攝像機(jī)而言,這個(gè)標(biāo)志符就是一個(gè)標(biāo)志數(shù)字——如果只有1個(gè)攝像機(jī),那么就是0(cv::CAP_ANY),如果系統(tǒng)中有多個(gè)攝像機(jī),那么只要將其向上增加即可。
enum ??? ?cv::VideoCaptureAPIs {
? cv::CAP_ANY = 0,
? cv::CAP_VFW = 200,
? cv::CAP_V4L = 200,
? cv::CAP_V4L2 = CAP_V4L,
? cv::CAP_FIREWIRE = 300,
? cv::CAP_FIREWARE = CAP_FIREWIRE,
? cv::CAP_IEEE1394 = CAP_FIREWIRE,
? cv::CAP_DC1394 = CAP_FIREWIRE,
? cv::CAP_CMU1394 = CAP_FIREWIRE,
? cv::CAP_QT = 500,
? cv::CAP_UNICAP = 600,
? cv::CAP_DSHOW = 700,
? cv::CAP_PVAPI = 800,
? cv::CAP_OPENNI = 900,
? cv::CAP_OPENNI_ASUS = 910,
? cv::CAP_ANDROID = 1000,
? cv::CAP_XIAPI = 1100,
? cv::CAP_AVFOUNDATION = 1200,
? cv::CAP_GIGANETIX = 1300,
? cv::CAP_MSMF = 1400,
? cv::CAP_WINRT = 1410,
? cv::CAP_INTELPERC = 1500,
? cv::CAP_REALSENSE = 1500,
? cv::CAP_OPENNI2 = 1600,
? cv::CAP_OPENNI2_ASUS = 1610,
? cv::CAP_GPHOTO2 = 1700,
? cv::CAP_GSTREAMER = 1800,
? cv::CAP_FFMPEG = 1900,
? cv::CAP_IMAGES = 2000,
? cv::CAP_ARAVIS = 2100,
? cv::CAP_OPENCV_MJPEG = 2200,
? cv::CAP_INTEL_MFX = 2300,
? cv::CAP_XINE = 2400
}
比如: cv::VideoCapture capture(cv::CAP_IEEE1394 + 1); ?表示將嘗試打開第2個(gè)(編號(hào)從0開始)1394攝像機(jī)。
方式三:先創(chuàng)建一個(gè)捕獲對(duì)象,然后通過成員函數(shù)open()來設(shè)定打開的信息。
?? ?cv::VideoCapture capture;
?? ?capture.open( "my_video.avi" );
cv::VideoCapture的成員函數(shù)isOpened()將會(huì)返回true(建議在打開視頻或攝像頭時(shí)都使用該成員函數(shù)判斷是否打開成功)。
二、視頻讀取
視頻幀讀取到cv::Mat矩陣中,有兩種方式:
一種是read()操作
?? ?cv::Mat frame;
?? ?cap.read(frame);?
另一種是 “>>”操作。
?? ?cv::Mat frame;
?? ?cap >> frame;?
三、設(shè)置和獲取攝像頭屬性參數(shù)
?比如設(shè)置屬性參數(shù), bool VideoCapture::set(int propertyId, double value),設(shè)置成功返回ture,失敗返回false。參數(shù):第一個(gè)是屬性ID,第二個(gè)是該屬性要設(shè)置的值。
?capture.set(CV_CAP_PROP_FRAME_WIDTH, 1080);//寬度?
?capture.set(CV_CAP_PROP_FRAME_HEIGHT, 960);//高度
?capture.set(CV_CAP_PROP_FPS, 30);//幀率 幀/秒
?capture.set(CV_CAP_PROP_BRIGHTNESS, 1);//亮度 1
?capture.set(CV_CAP_PROP_CONTRAST,40);//對(duì)比度 40
?capture.set(CV_CAP_PROP_SATURATION, 50);//飽和度 50
?capture.set(CV_CAP_PROP_HUE, 50);//色調(diào) 50
?capture.set(CV_CAP_PROP_EXPOSURE, 50);//曝光 50
?capture.set(CV_CAP_PROP_FOURCC, 50);//FOURCC編解碼器的4個(gè)字符代碼。
?capture.set(CV_CAP_PROP_POS_AVI_RATIO,0);//視頻文件的相對(duì)位置:0-膠片開始,1-膠片結(jié)束。
?capture.set(CV_CAP_PROP_CONVERT_RGB,1);//表示圖像是否應(yīng)轉(zhuǎn)換為RGB的布爾標(biāo)志
?capture.set(CV_CAP_PROP_RECTIFICATION,1);//立體攝像機(jī)的整流標(biāo)志(注意:只有當(dāng)前支持DC1394 v 2.x后端)
?比如獲取屬性參數(shù), double VideoCapture::get(int propId),參數(shù):第一個(gè)是屬性的ID。如果查詢的視頻屬性是VideoCapture類不支持的,將會(huì)返回0。
?int nFrameWidth = capture.get(CV_CAP_PROP_FRAME_WIDTH);
?int nFrameHeight = capture.get(CV_CAP_PROP_FRAME_HEIGHT);
?double fFrameRate = capture.get(CV_CAP_PROP_FPS);
?int nBrightness = capture.get(CV_CAP_PROP_BRIGHTNESS);
?int nContrast = capture.get(CV_CAP_PROP_CONTRAST);
?int nSaturation = capture.get(CV_CAP_PROP_SATURATION);
?int nHue = capture.get(CV_CAP_PROP_HUE);
?int nExposure = capture.get(CV_CAP_PROP_EXPOSURE);
?double fFrameCount = capture.get(CV_CAP_PROP_FRAME_COUNT);//總幀數(shù)
double fFramePos = capture.get(CV_CAP_PROP_POS_FRAMES);//視頻幀號(hào),0-based index of the frame to be decoded/captured next.
double fTimestamp = capture.get(CV_CAP_PROP_POS_MSEC);//時(shí)間戳(毫秒),position of the video file in milliseconds or video capture timestamp.
int ex = static_cast<int>(capture.get(CV_CAP_PROP_FOURCC));//獲取FOURCC4個(gè)字符表示的視頻編碼器格式
// Transform from int to char via Bitwise operators
char EXT[] = {(char)(ex & 0XFF),(char)((ex & 0XFF00) >> 8),(char)((ex & 0XFF0000) >> 16),(char)((ex & 0XFF000000) >> 24),0};
如果是MPEG4編碼,ex為0x7634706d,EXT為mp4v
如果是H264編碼,ex為0x31637661,EXT為avc1
如果是H265編碼,ex為0x31637662,EXT為avc2
CV_FOURCC獲取編碼格式:
cv.VideoWriter.fourcc(‘P’, ‘I’, ‘M’, ‘1’) 表示 MPEG-1 codec
cv.VideoWriter.fourcc(‘M’, ‘J’, ‘P’, ‘G’) 表示 motion-jpeg codec
cv.VideoWriter.fourcc(‘M’, ‘P’, ‘4’, ‘2’) 表示 MPEG-4.2 codec
cv.VideoWriter.fourcc(‘D’, ‘I’, ‘V’, ‘3’) 表示 MPEG-4.3 codec
cv.VideoWriter.fourcc(‘D’, ‘I’, ‘V’, ‘X’) 表示 MPEG-4 codec
cv.VideoWriter.fourcc(‘U’, ‘2’, ‘6’, ‘3’) 表示 H263 codec
cv.VideoWriter.fourcc(‘I’, ‘2’, ‘6’, ‘3’) 表示 H263I codec
cv.VideoWriter.fourcc(‘F’, ‘L’, ‘V’, ‘1’) 表示 FLV1 codec
四、設(shè)置視頻幀的讀取位置
VideoCapture類的set方法可以允許我們?nèi)〕鲆曨l中某個(gè)位置的幀,它有一些參數(shù),可以按時(shí)間,也可以按幀號(hào),還可以按視頻長短的比例。
double position=100.0;
capture.set(CV_CAP_PROP_POS_FRAMES,position);//幀號(hào)
double position=10000;
capture.set(CV_CAP_PROP_POS_MSEC,position);//時(shí)間戳位置(毫秒)
double position=0.5;
capture.set(CV_CAP_PROP_POS_AVI_RATIO,position);//視頻1/2位置
五、關(guān)閉視頻文件或者攝像頭。
VideoCapture::release()
六、實(shí)例
1、讀取本地視頻文件或網(wǎng)絡(luò)視頻文件。
#include<opencv2/opencv.hpp>
using namespace cv;
?
void main(){
? ? VideoCapture cap;
? ? cap.open("d:\\test.mp4");
? ? //cap.open("http://xxx/test.mp4");//http視頻url地址
? ? if(!cap.isOpened())//如果視頻不能正常打開則返回
? ? ? ? return;
? ? Mat frame;
? ? while(true)
? ? {
? ? ? ? cap>>frame;//等價(jià)于cap.read(frame);
? ? ? ? if(frame.empty())//如果某幀為空則退出循環(huán)
? ? ? ? ? ? break;
? ? ? ? imshow("video", frame);
? ? ? ? waitKey(25);//每幀延時(shí)25毫秒
? ? }
? ? cap.release();//釋放資源
}
2、讀取攝像頭視頻
#include<opencv2/opencv.hpp>
using namespace cv;
?
void main(){
? ? //打開攝像機(jī)設(shè)備
? ? cv::VideoCapture cap= cv::VideoCapture(0);
? ? //先設(shè)置采集格式
? ? cap.set(CV_CAP_PROP_FOURCC, cv::VideoWriter::fourcc('M', 'J', 'P', 'G'));
? ? //再設(shè)置高清采集分辨率
? ? cap.set(CV_CAP_PROP_FRAME_WIDTH, 1920);
? ? cap.set(CV_CAP_PROP_FRAME_HEIGHT, 1080);
?
? ? if(!cap.isOpened())
? ? ? ? return;
?
? ? Mat frame;
? ? while(1)
? ? {
? ? ? ? cap>>frame;
? ? ? ? if(frame.empty())
? ? ? ? ? ? break;
? ? ? ? imshow("video", frame);
? ? ? ? if(waitKey(25)>0)//按下任意鍵退出攝像頭
? ? ? ? ? ? break;
? ? }
? ? cap.release();
? ? destroyAllWindows();//關(guān)閉所有窗口
}
七、注意事項(xiàng)
1、OpenCV3和OpenCV2類似,視頻的讀、寫操作,分別通過cv::VideoCapture和cv::VideoWriter兩個(gè)類來實(shí)現(xiàn)。
2、使用opencv中 “cv::VideoCapture” 函數(shù),無法讀取本地文件;報(bào)錯(cuò)內(nèi)容顯示:報(bào)錯(cuò):cv::CvCapture_Images::open CAP_IMAGES: Stop scanning. Can 或者“Read video Failed”。解決方法:將opencv視頻解碼依賴ffmpeg庫拷貝到當(dāng)前目錄下即可。比如:opencv_videoio_ffmpeg455_64.dll(455_64表示opencv庫的版本)
由于OpenCV對(duì)視頻進(jìn)行處理時(shí),只能處理.avi格式的文件。不能打開.mp4格式的文件。需要將opencv安裝包的opencv_ffmpeg.dll或opencv_videoio_ffmpeg版本號(hào)xxx.dll文件拷貝到相應(yīng)的工程文件夾內(nèi)就可以支持.mp4文件了。
3、打開攝像頭高分辨率下有時(shí)延:在缺省情況下用VideoCapture打開攝像頭,小分辨率640x480可以實(shí)時(shí)顯示,但1920x1080時(shí)就會(huì)有將近1秒多的時(shí)延。
解決方法一:
可以設(shè)置緩存區(qū)大小。使用設(shè)置屬性接口將buffersize改小,使得高分辨率下也可以實(shí)時(shí)顯示。
capture.set(CV_CAP_PROP_BUFFERSIZE,1);
解決方法二:
很多攝像頭,在YUV2輸出格式高分辨率的情況下都不到15幀,以MJPG輸出格式解碼能達(dá)到30幀。文章來源:http://www.zghlxwxcb.cn/news/detail-458131.html
//打開攝像機(jī)設(shè)備
cv::VideoCapture cap= cv::VideoCapture(0);
//先設(shè)置采集格式
cap.set(CV_CAP_PROP_FOURCC, cv::VideoWriter::fourcc('M', 'J', 'P', 'G'));
//再設(shè)置高清采集分辨率
cap.set(CV_CAP_PROP_FRAME_WIDTH, 1920);
cap.set(CV_CAP_PROP_FRAME_HEIGHT, 1080);
4、VideoCapture打開網(wǎng)絡(luò)視頻文件目前只支持http格式和rtsp格式網(wǎng)絡(luò)視頻文件。文章來源地址http://www.zghlxwxcb.cn/news/detail-458131.html
到了這里,關(guān)于OpenCV VideoCapture使用方法(視頻文件、攝像頭、網(wǎng)絡(luò)視頻文件)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!