Qt调用OpenCV实现录制视频文件中的几个问题
来源:互联网 发布:淘宝店铺装修图 编辑:程序博客网 时间:2024/06/02 17:09
这几天需要做一个视频文件录制功能。用Qt调用OpenCV代码搞定。
其中线程相关的过程省略不写,与CvVideoWriter生成的部分网上有很多,也省略不写。下面只记录这个写入单帧的函数:
第一版:
//ATTENTION: 调用来自另一线程bool ETVideoController::writeVideo(const ETVideoSource &source, QSize size, CvVideoWriter *pWriter){ QImage img(source.getOneFrame()); // pImageWrite与img共享内存 IplImage* pImageWrite = cvCreateImageHeader( cvSize(size.width(), size.height()), 8, 3); pImageWrite->imageData = reinterpret_cast<char*>(img.bits()); cvCvtColor(pImageWrite, pImageWrite, CV_RGB2BGR); // 写入一帧 cvWriteFrame(pWriter, pImageWrite); cvReleaseImageHeader(&pImageWrite); return true;}
这一版本的代码没有考虑到输入的源图像非24位图的情况,也没有考虑到输入的源图像与视频大小不一致的情况。所以录制后的视频出现了花屏的情况。为改善这一问题,我把代码改成了如下形式:
第二版:
//ATTENTION: 调用来自另一线程bool ETVideoController::writeVideo(const ETVideoSource &source, QSize size, CvVideoWriter *pWriter){ // 将图像预先转化成24位 QImage img(source.getOneFrame().convertToFormat(QImage::Format_RGB888)); img = img.scaled(size); // pImageWrite与img共享内存 IplImage* pImageWrite = cvCreateImageHeader( cvSize(size.width(), size.height()), 8, 3); pImageWrite->imageData = reinterpret_cast<char*>(img.bits()); cvCvtColor(pImageWrite, pImageWrite, CV_RGB2BGR); // 写入一帧 cvWriteFrame(pWriter, pImageWrite); cvReleaseImageHeader(&pImageWrite); return true;}
其中cvWriteFrame函数在调用时发生内存错误。上网各种搜索,没有找到有用的答案,初步判断因为img对象在其复制构造函数、赋值运算符调用的过程中,Qt执行的是浅复制,而对于Qt来说,它会自动判断在需要深复制的时候再进行一次深复制以使它们看起来像完全不同的对象一样。Qt这种机制使得OpenCV访问了非法的内存地址,所以造成内存出错。于是,我将代码改成了最终的版本
第三版:
//ATTENTION: 调用来自另一线程bool ETVideoController::writeVideo(const ETVideoSource &source, QSize size, CvVideoWriter *pWriter){ QImage img = source.getOneFrame(); QImage imgDest(size, QImage::Format_RGB888); // 创建一个新图片,使用指定的大小和24位格式 { QPainter p(&imgDest); // 使用QPainter描画图片 p.drawImage(imgDest.rect(), img); } // 析构 // pImageWrite与img共享内存 IplImage* pImageWrite = cvCreateImageHeader( cvSize(size.width(), size.height()), 8, 3); pImageWrite->imageData = reinterpret_cast<char*>(imgDest.bits()); cvCvtColor(pImageWrite, pImageWrite, CV_RGB2BGR); // 写入一帧 cvWriteFrame(pWriter, pImageWrite); cvReleaseImageHeader(&pImageWrite); return true;}
Painter p外面的大括号是不可以省略的,因为我们利用在右大括号}处自动调用p的析构函数的特性。经调试,上述代码可以正常运行。
(■版权声明: 原创内容,转载仅限非商业用途,并需注明出处: http://blog.csdn.net/LoveASPDotNet)
- Qt调用OpenCV实现录制视频文件中的几个问题
- Qt使用opencv调用摄像头录制视频并保存文件
- opencv+ffmpeg+Qt h264录制
- opencv实现视频录制
- Opencv中的Bug(实现读入一个彩色视频文件并以灰度格式输出这个视频文件,学习opencv例2-10)
- opencv调用摄像头录制视频
- QT+Opencv视频文件TCP网络传输
- Opencv读取视频文件的几个问题及解决方法(读入空Mat,访问冲突)
- ffmpeg 录制udp电视信号,视频文件
- ios录制并写视频文件
- ios录制并写视频文件
- Qt调用OpenCV打开图片
- OpenCV学习笔记_调用摄像头录制视频(无声音)
- iOS AVAssetWriter 实现高分辨率录制视频,生成低体积的视频文件
- QT和网页中的JavaScript函数相互调用的实现
- OpenCV 播放视频文件
- opencv 之写视频文件
- Opencv写视频文件
- ANSYS中NUMMRG命令的小技巧
- poj 2033 DP
- TypedMessage 模式 与 java Swing 事件驱动模型
- 新手指针犯错
- 最长公共子串,出去重复子串
- Qt调用OpenCV实现录制视频文件中的几个问题
- java中的hashCode()和equals()的关系
- LOGFONT类型与D3DXFONT_DESC类型
- windows和linux双系统调整分区大小
- android-setVisibility
- 线性判别函数
- document.createElement()的用法
- LogCat中不输出日志
- hdu 1421 搬寝室