日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

opencv无获取摄像头视频帧(YUV打开导致失败)

發布時間:2023/12/31 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 opencv无获取摄像头视频帧(YUV打开导致失败) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近由于項目的原因,有一臺工控機在沒有打永恒之藍補丁之前,應用程序使用opencv 3.4.1打開攝像頭后顯示視頻內容都可以正常顯示,但當安裝完windows 7 x86永恒之藍補丁后(KB4012215,KB4012212),應用程序無法正常顯示攝像頭的視頻,表現為:OPENCV打開攝像頭成功,但獲取攝像頭視頻幀得到的數據為空,使用AMCAP2.exe進行測試攝像頭,使用MJPG格式可以正常瀏覽,但把視頻設置為YUV的格式后也無法預覽。
于是想到把OPENCV設置為MJPG方式打開攝像頭進行處理,卻同樣無法預覽,測試代碼如下:

int main(int argc, const char** argv) {//if (!initLicense()) return -1;string assetFolder = "";string inputVideo = "";if (argc >= 2){assetFolder = argv[1];}if (argc >= 3){inputVideo = argv[2];}VideoCapture cap;cv::VideoWriter l_writer;int camid=0;if (!inputVideo.empty()){// open filecap.open(inputVideo);}else{cout<<" please input camera index:";cin>>camid;//設置圖像寬度cap.set(CAP_PROP_FRAME_WIDTH,640);//設置圖像高度cap.set(CAP_PROP_FRAME_HEIGHT,480);//設置幀率cap.set(CAP_PROP_FPS,30);//獲取MJPE編碼 這個值是固定的1196444237int fourcc= l_writer.fourcc('M','J','P','G');//設置編碼格式,這里只能寫在分辨率和幀率后面,否則無效cap.set(CAP_PROP_FOURCC,fourcc);// open cameracap.open(camid);}if (!cap.isOpened()){cerr << "can not open camera!" << endl;return -1;}//打印攝像頭參數cout << "Cam :" << camid;cout << "寬度(width) =" << cap.get(CV_CAP_PROP_FRAME_WIDTH)<<endl; //寬度cout << "高度(height) =" << cap.get(CV_CAP_PROP_FRAME_HEIGHT)<<endl; //高度cout << "幀數(fbs) =" << cap.get(CV_CAP_PROP_FPS)<<endl; //幀數cout << "亮度(brightness) =" << cap.get(CV_CAP_PROP_BRIGHTNESS)<<endl; //亮度cout << "對比度(contrast) =" << cap.get(CV_CAP_PROP_CONTRAST)<<endl; //對比度cout << "飽和度(saturation) =" << cap.get(CV_CAP_PROP_SATURATION)<<endl; //飽和度cout << "色調(hue) =" << cap.get(CV_CAP_PROP_HUE)<<endl; //色調cout << "曝光(exposure) =" << cap.get(CV_CAP_PROP_EXPOSURE)<<endl; //曝光int ex = static_cast<int>(cap.get(CV_CAP_PROP_FOURCC));//格式// Transform from int to char via Bitwise operatorschar EXT[] = { (char)(ex & 0XFF), (char)((ex & 0XFF00) >> 8), (char)((ex & 0XFF0000) >> 16), (char)((ex & 0XFF000000) >> 24), 0 };cout << "格式(fourcc) =" << EXT<<endl;string winName = "canvas";namedWindow(winName);moveWindow(winName, 10, 10);Mat frame;bool finish_get_faceimg = false;//Timer tmr;while (true){//tmr.tic();cap >> frame;cap >> frame;if (frame.empty()){cerr << "frame empty!" << endl;break;}double fps = 0;//1000 / tmr.toc();putText(frame, "fps:" + std::to_string((long double)fps), Point(10, 20), FONT_HERSHEY_SIMPLEX, 0.6, CV_RGB(255, 0, 0), 1);imshow(winName, frame);if (waitKey(1) == 27)break;}cap.release();return 0; }

經過多個版本的嘗試依然沒有解決問題,最終想到要不進行調試一步步進行跟進,就使用opencv3.0.0的debug版本進行調試(為什么使用opencv3.0.0,原因是由于這個版本比較老,原想這個問題會不會是新版本的問題,舊版本會不會沒有這個問題呢),在調試過程中,終端程序在打開攝像頭時發現輸出信息顯示" trying format YUV2…"等,后面就沒有見到有mjpg格式了,心想明明是設置了mjpg,為什么還是使用yuv方式打開,進行翻查opencv代碼,最終找到opencv在打開攝像頭時會進行每一種編碼方式嘗試打開,并且是按順序進行,當某一種方式打開成功后就不會再嘗試別的方式打開,opencv打開攝像頭的方式:

//-------------------------cap_dshow.cpp : int videoInput::start(int deviceID, videoDevice *VD) getMediaSubtypeAsString(mediaSubtypes[i], guidStr);---------char guidStr[8];// try specified format and sizegetMediaSubtypeAsString(VD->tryVideoType, guidStr);DebugPrintOut("SETUP: trying specified format %s @ %ix%i\n", guidStr, VD->tryWidth, VD->tryHeight);if( setSizeAndSubtype(VD, VD->tryWidth, VD->tryHeight, VD->tryVideoType) ){VD->setSize(VD->tryWidth, VD->tryHeight);VD->videoType = VD->tryVideoType;foundSize = true;} else {// try specified size with all formatsfor(int i = 0; i < VI_NUM_TYPES; i++){getMediaSubtypeAsString(mediaSubtypes[i], guidStr);DebugPrintOut("SETUP: trying format %s @ %ix%i\n", guidStr, VD->tryWidth, VD->tryHeight);if( setSizeAndSubtype(VD, VD->tryWidth, VD->tryHeight, mediaSubtypes[i]) ){VD->setSize(VD->tryWidth, VD->tryHeight);VD->videoType = mediaSubtypes[i];foundSize = true;break;}}} //-------------------------cap_dshow.cpp : videoInput::videoInput(){---------mediaSubtypes[0] = MEDIASUBTYPE_RGB24;mediaSubtypes[1] = MEDIASUBTYPE_RGB32;mediaSubtypes[2] = MEDIASUBTYPE_RGB555;mediaSubtypes[3] = MEDIASUBTYPE_RGB565;mediaSubtypes[4] = MEDIASUBTYPE_YUY2;mediaSubtypes[5] = MEDIASUBTYPE_YVYU;mediaSubtypes[6] = MEDIASUBTYPE_YUYV;mediaSubtypes[7] = MEDIASUBTYPE_IYUV;mediaSubtypes[8] = MEDIASUBTYPE_UYVY;mediaSubtypes[9] = MEDIASUBTYPE_YV12;mediaSubtypes[10] = MEDIASUBTYPE_YVU9;mediaSubtypes[11] = MEDIASUBTYPE_Y411;mediaSubtypes[12] = MEDIASUBTYPE_Y41P;mediaSubtypes[13] = MEDIASUBTYPE_Y211;mediaSubtypes[14] = MEDIASUBTYPE_AYUV;mediaSubtypes[15] = MEDIASUBTYPE_MJPG; // MGB 原位置

當YUV打開成功后,使用的攝像頭的數據格式就會停止,因此就會使用yuv進行打開,但此時系統無法使用YUV讀取攝像頭數據,因而導致無法顯示視頻。
為了解決此問題,無法從windows 7 32位系統分析解決,因此使用修改opencv打開視頻格式的方式解決了此問題,把打開的視頻數據格式修改為以下順序:mediaSubtypes[15] = MEDIASUBTYPE_MJPG;----- >mediaSubtypes[4] = MEDIASUBTYPE_MJPG;:

mediaSubtypes[0] = MEDIASUBTYPE_RGB24;mediaSubtypes[1] = MEDIASUBTYPE_RGB32;mediaSubtypes[2] = MEDIASUBTYPE_RGB555;mediaSubtypes[3] = MEDIASUBTYPE_RGB565;mediaSubtypes[4] = MEDIASUBTYPE_MJPG; // MGB 調整后的位置mediaSubtypes[5] = MEDIASUBTYPE_YUY2;mediaSubtypes[6] = MEDIASUBTYPE_YVYU;mediaSubtypes[7] = MEDIASUBTYPE_YUYV;mediaSubtypes[8] = MEDIASUBTYPE_IYUV;mediaSubtypes[9] = MEDIASUBTYPE_UYVY;mediaSubtypes[10] = MEDIASUBTYPE_YV12;mediaSubtypes[11] = MEDIASUBTYPE_YVU9;mediaSubtypes[12] = MEDIASUBTYPE_Y411;mediaSubtypes[13] = MEDIASUBTYPE_Y41P;mediaSubtypes[14] = MEDIASUBTYPE_Y211;mediaSubtypes[15] = MEDIASUBTYPE_AYUV;

總結:
1.opencv存在一定的問題,無法通過接口設置其打開視頻的格式
2.windows 7 32位更新永恒之藍補丁后導致無法預覽攝像頭數據(YUV格式),找了兩天都沒有找到原因,此問題在另一個系統的windows 7 32下又沒有問題(補丁更新的數量不一樣,除了永恒之藍補丁外,還更新了其他補丁),給我的感覺是由于永恒之藍補丁導致當前系統的directx無法兼容所致,由于時間比較緊急,打過電話給微軟,微軟卻說不是他們系統的問題,應該找一下設備應用程序開發商分析問題,工控機廠商也沒有辦法一時解決此問題。

總結

以上是生活随笔為你收集整理的opencv无获取摄像头视频帧(YUV打开导致失败)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。