我一直在尝试使用 OpenCV 和 freeglut。
该程序涉及从网络摄像头捕获图像,使用 OpenCV 处理图像,并根据处理后的图像使用 OpenGL 绘制 3D 对象。
当我只使用 OpenCV 例程时,它工作得很好。
当主循环被 GLUT 控制时,问题就出现了。当我尝试从我使用 glutDisplayFunc() 注册的回调中抓取帧时,返回的图像是空的。
然而,奇怪的是,当我从使用 glutIdleFunc() 注册的回调中获取帧时,它会成功返回一个帧。
在四处摸索之后,我发现在第一次调用 display() 时无法捕获帧,但在第二次调用后起作用。
目前我的代码正在 idle() 函数中查询一个帧。
关于这样的背景,我有几个问题。
- 为什么会发生这种情况?是否是因为在 VideoCapture 获得对网络摄像头的完全访问权限之前程序在 display() 内停止?或者这纯粹是硬件问题?
- 这安全吗?我完全可以从 idle() 中抓取帧,但这种方法使用安全吗?
- 如果不是这样,是否有解决方法?如果这种方法不安全,请告诉我另一种处理此问题的方法吗?
该程序基于 OS X 版本 10.9.1 构建,正在使用的库是
- OpenCV 2.4.7.0
- freeglut 2.0.1
这是我的代码的简化版本:
#include <opencv2/opencv.hpp>
#include <GL/freeglut.h>
#include <iostream>
cv::VideoCapture capture;
cv::Mat render;
void display()
{
std::cerr << "Grabbing frame in display()" << std::endl;
capture >> render; // This does not work on first call
if(render.empty()) {
std::cerr << "Error: Grabbing empty frame in display()" << std::endl;
}
}
void idle()
{
std::cerr << "Grabbing frame in idle()" << std::endl;
capture >> render; // This always works
if(render.empty()) {
std::cerr << "Error: Grabbing empty frame in idle()" << std::endl;
}
glutPostRedisplay();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA);
glutInitWindowSize(640, 480);
int debug_window = glutCreateWindow("Debug");
glutDisplayFunc(display);
glutIdleFunc(idle);
capture.open(0);
if(!capture.isOpened()) {
std::cerr << "Error: Failed to open camera" << std::endl;
exit(1);
}
glutMainLoop();
return 0;
}
最佳答案
已知问题。
一些草率的网络摄像头驱动程序返回空第一帧、预热或其他内容。
只是 try catch 1 帧,在您进入空闲循环之前
关于c++ - OpenCV VideoCapture 仅在第一次调用 glutDisplayFunc 回调时返回空帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21353974/