Opencv 在多次cv::VideoCapture()构造之后,cv::VideoCapture::grab()中的Segfault
在下面的代码中,我从cv::VideoCapture::grab()(实际上是,>>运算符)中获得segfault 超过100次循环后会发生错误Opencv 在多次cv::VideoCapture()构造之后,cv::VideoCapture::grab()中的Segfault,opencv,Opencv,在下面的代码中,我从cv::VideoCapture::grab()(实际上是,>>运算符)中获得segfault 超过100次循环后会发生错误 while(1) { boost::timer te; // create VideoCapture instance cv::VideoCapture cap(0); if(!cap.isOpened()) { /* shutdown code */ } cv::Mat frame; std::vec
while(1) {
boost::timer te;
// create VideoCapture instance
cv::VideoCapture cap(0);
if(!cap.isOpened()) { /* shutdown code */ }
cv::Mat frame;
std::vector<uchar> buf;
// get the latest frame from camera
cap >> frame;
// save frame as png image
cv::imencode(".png", frame, buf);
std::string data(buf.begin(), buf.end());
my.saveImage(data);
// release capture device
cap.release();
// wait 1 second
boost::asio::deadline_timer t(io, boost::posix_time::milliseconds(1000.0 - te.elapsed() * 1000));
t.wait();
}
valgrind的错误是
==28670== Invalid write of size 4
==28670== at 0x4242E75: ??? (in /usr/lib/libopencv_highgui.so.2.3.1)
==28670== by 0x4242F02: CvCaptureCAM_V4L_CPP::grabFrame() (in /usr/lib/libopencv_highgui.so.2.3.1)
==28670== by 0x46A14D2: (below main) (libc-start.c:226)
==28670== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==28670==
==28670==
==28670== Process terminating with default action of signal 11 (SIGSEGV)
==28670== Access not within mapped region at address 0x0
==28670== at 0x4242E75: ??? (in /usr/lib/libopencv_highgui.so.2.3.1)
==28670== by 0x4242F02: CvCaptureCAM_V4L_CPP::grabFrame() (in /usr/lib/libopencv_highgui.so.2.3.1)
==28670== by 0x46A14D2: (below main) (libc-start.c:226)
==28670== If you believe this happened as a result of a stack
==28670== overflow in your program's main thread (unlikely but
==28670== possible), you can try to increase the size of the
==28670== main thread stack using the --main-stacksize= flag.
==28670== The main thread stack size used in this run was 8388608.
我有两个问题
- 定期获取快照的最佳做法是什么
- 如何避免这个错误
- 环境:Ubuntu12.04,来自apt的OpenCV 2.3.1-7,V4L2
- 我的设备不接受FPS设置器
- 完整的代码是
// create VideoCapture instance
cv::VideoCapture cap(0);
while(cap.isOpened())
{
boost::timer te;
cv::Mat frame;
std::vector<uchar> buf;
// get the latest frame from camera
cap >> frame;
if ( ! frame.empty() ) // check it, please
{
// save frame as png image
cv::imencode(".png", frame, buf);
std::string data(buf.begin(), buf.end());
my.saveImage(data);
}
// wait 1 second
boost::asio::deadline_timer t(io, boost::posix_time::milliseconds(1000.0 - te.elapsed() * 1000));
t.wait();
}
//cap.release(); // can care for itself
//创建视频捕获实例
cv::视频捕获上限(0);
while(cap.isOpened())
{
boost::定时器te;
cv::垫架;
std::载体buf;
//从照相机获取最新帧
cap>>框架;
如果(!frame.empty())//请检查
{
//将帧另存为png图像
cv::imencode(“.png”,帧,buf);
字符串数据(buf.begin(),buf.end());
my.saveImage(数据);
}
//等一秒钟
boost::asio::deadline_timer t(io,boost::posix_time::毫秒(1000.0-te.appeased()*1000));
t、 等待();
}
//cap.release();//我可以照顾自己
然后,将图像编码为std::string可能会导致大量意外的文件截断(不知道my.saveImage()在做什么,但是零在图像中是完全合法的,但在字符串中不是,对吗?)
为什么不在这里使用imwrite()
最后但并非最不重要的一点是,2.3.1非常旧,最好更新到2.4.7是否有特殊原因为每个帧创建新捕获?使用
grab()
,检索到的帧不是最新的。它似乎需要抓取所有帧。据我所测试的,grab()
(在>
操作符中调用)和t.wait()
的组合会出现错误。拍摄的图像是几秒钟前的。我怀疑原因是图像是从缓冲区的第一帧拍摄的。我需要一个方法来抓取最后一帧的捕获saveImage()
将图像作为BLOB存储到MySQL数据库中。我将尝试更新。
// create VideoCapture instance
cv::VideoCapture cap(0);
while(cap.isOpened())
{
boost::timer te;
cv::Mat frame;
std::vector<uchar> buf;
// get the latest frame from camera
cap >> frame;
if ( ! frame.empty() ) // check it, please
{
// save frame as png image
cv::imencode(".png", frame, buf);
std::string data(buf.begin(), buf.end());
my.saveImage(data);
}
// wait 1 second
boost::asio::deadline_timer t(io, boost::posix_time::milliseconds(1000.0 - te.elapsed() * 1000));
t.wait();
}
//cap.release(); // can care for itself