最近由于项目的原因,有一台工控机在没有打永恒之蓝补丁之前,应用程序使用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打开导致失败)相关推荐

  1. android获取摄像头视频帧数据

    1.思路 一.通过android的Camera.setPreviewCallback(PreviewCallback cb)监听回调. 二.此回调函数public void onPreviewFram ...

  2. Android不显示Camera视频获取摄像头视频帧数据

    1.在Activity界面代码中: private var mCamera: Camera? = null private val mWidth = GwApplication.DEFAULT_REM ...

  3. C++Opencv实时读取摄像头视频保存指定帧图片

    空格截图到指定文档 string writePath = "../temp/"; int main(int argc, char** argv){VideoCapture capt ...

  4. opencv获取外接摄像头_opencv获取摄像头视频

    结合Leaning OpenCV 第二个例子 显示一个视屏文件 写了一下 获取摄像头的代码为并且创建窗口显示的代码为: #include "stdafx.h" #include # ...

  5. opencv VideoWriter保存摄像头视频、本地视频等

    打开视频文件或摄像头视频需要使用Opencv中的VideoCapture类,保存视频或摄像头视频到本地磁盘,需要使用Opencv中的VideoWriter类. VideoWriter类的一个常用构造方 ...

  6. 基于opencv,使用python提取视频帧以及提取TVL1光流

    处理视频,最常用的开源工具箱非opencv莫属了,python可以很好的支持它. 一 从视频读取帧.得到相关属性.并设置保存哪些帧 首先:我们得新建一个videocapture对象: cap=cv2. ...

  7. 60帧/秒摄像头 视频帧数最佳选择!

    随着网络的普及,作为电脑外设产品的摄像头也迅速进入千家万户.这一重大商机也给摄像头行业的发展带来一片繁荣景象.在这个进入门槛低.公模横行的行业,摄像头产品在外观设计.用户应用范围.新功能技术指标等方面 ...

  8. 2019研究生数学建模C题--图片像素获取与视频帧处理

    图像像素坐标获取 import cv2 import numpy as np img = cv2.imread('C:\Users\mimi\Desktop\1.jpg') a =[] b = [] ...

  9. 【2012年终总结】之一 opencv + ds采集摄像头视频 MFC点点滴滴

    1.MFC单文档多文档程序 不让MFC来更新菜单 1 在CMainFrame::CMainFrame中添加 2 3 m_bAutoMenuEnable = FALSE; 标题栏图标的更改 1 //cu ...

  10. 利用Flash获取摄像头视频进行动态捕捉

    一.引言 摄像头游戏是随着摄像头的普及和图形图像技术的不断发展而出现的.它摆脱了鼠标键盘的限制,给游戏者带来全新的游戏体验,能够实现许多传统游戏无法实现的游戏效果.它通过摄像头将玩家投影到游戏中,由玩 ...

最新文章

  1. 在线作图丨做一张叠加mantel test的相关性热图
  2. js变量传递给less_如何利用webpack实现一键换肤(CSS变量替换)
  3. python 深浅拷贝案例_python-浅拷贝、深拷贝实例以及讲解
  4. 总统先生,一路走好!
  5. Kth Largest Element in an Array
  6. 基于VHDL语言的数字秒表实现
  7. 抢答网页PHP,[抢答]抢答环节已结束,相关答案已封箱 - 薅羊毛(Coupon)版 - 北大未名BBS...
  8. Taro+react开发(97):问答模块04
  9. php是否支持64位,phpstudy默认不支持64位php的解决方法
  10. Axure电脑web端通用元件库rplib文件格式+移动端app通用元件库rplib文件格式(内含使用教程)
  11. C++多继承的二义性
  12. oracle 12c 性能,Oracle 12C 新性能 总结篇
  13. 比较连续分配、分页和分段三种存储分配机制的优缺点_第十九期-处理器存储模型概述(1)...
  14. caffe运行问题(持续更新),sublime设置
  15. 多台电脑集群运算_Linux服务器集群概念辨识
  16. 170319 剑指offer 1.把一个字符串转化成整数(简单问题的全面性考虑)
  17. 服务器的安全措施有哪些呢?
  18. ubuntu下 端口映射
  19. mscorsvw.exe是windows的什么进程!!
  20. 不想安装环境,我如何与前端工程师远程协作开发?

热门文章

  1. Ubuntu安装jdk8
  2. visio2016交叉线(跨线)去掉交叉点弯曲的办法
  3. aceAdmin框架依赖
  4. C语言结构体内存对齐
  5. 对象转换 json 字符串和 json转换对象的几种方式
  6. 华为机顶盒系统时间同步服务器,华为悦盒主时间同步服务器地址
  7. qimage加载jpg失败_QImage基本api
  8. gooflow 自定义流程图
  9. 几个找pdf资源的网站
  10. Html + Java登录验证码实现代码