QT使用OpenCV获取视频流通过共享内存存储OpenGL展现
关键词:qt、opencv、opengl、共享内存
- 线程中通过OpenCV打开摄像头。
- 线程中将实时图像存入共享内存中,此时无论是跨线程或跨进程均可通过共享内存获取实时视频帧。
- 通过OpenGL展示实时视频流,使用OpenGL渲染视频帧,会调用GPU,CPU占用率低。展示效果如下:
注意事项
- 将QWidget 提升为自定义控件GLWidget 时,头文件要改为QWidget,否则移动工程时,容易找不到头文件。
核心代码
此Demo的核心代码如下,可以根据核心代码自行编码调试,或下载源码修改调试:
void GetCameraFrame_Thread::run()
{
if(m_cvCapture.isOpened()){
m_cvCapture.release();
}
m_bCameraOpen = m_cvCapture.open(0);
if(m_cvCapture.isOpened()){
m_cvCapture.set(CV_CAP_PROP_FOURCC, CV_FOURCC('M', 'J', 'P', 'G'));
m_cvCapture.set(CV_CAP_PROP_FRAME_WIDTH, 1600);
m_cvCapture.set(CV_CAP_PROP_FRAME_HEIGHT,1200);
}
if(m_bCameraOpen){
if(nullptr == g_pShareVideo){
g_pShareVideo = new QSharedMemory("Robot_Camera_Live");
g_pShareVideo->create(1600*1200*3+5);
}
while (!m_bExit) {
cv::Mat srcFrame, cloneFrame;
m_cvCapture.read(srcFrame);
cv::cvtColor(srcFrame, cloneFrame, CV_BGR2RGB);
if(!g_pShareVideo->isAttached()){
g_pShareVideo->attach();
}
g_pShareVideo->lock();
int *pMemData = (int*)g_pShareVideo->data(); //may be null
pMemData[0] = cloneFrame.cols;
pMemData[1] = cloneFrame.rows;
int nFlag = cloneFrame.channels() * 8;
size_t nBytes = cloneFrame.cols * cloneFrame.rows * nFlag / 8;
memcpy((void*)(pMemData+2), (void*)cloneFrame.data, nBytes);
g_pShareVideo->unlock();
QThread::msleep(10);
}
m_cvCapture.release();
}
}