我在以下代码中从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::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();
}
gdb的错误是
(gdb) where
#0 0xb7dcfe75 in ?? () from /usr/lib/libopencv_highgui.so.2.3
#1 0xb7dcff03 in CvCaptureCAM_V4L_CPP::grabFrame() () from /usr/lib/libopencv_highgui.so.2.3
#2 0xb7dbd783 in cvGrabFrame () from /usr/lib/libopencv_highgui.so.2.3
#3 0xb7dbd7bf in cv::VideoCapture::grab() () from /usr/lib/libopencv_highgui.so.2.3
#4 0xb7dbd562 in cv::VideoCapture::operator>>(cv::Mat&) () from /usr/lib/libopencv_highgui.so.2.3
#5 0x0804a464 in main (argv=3, argc=0xbfffea44) at main.cpp:31
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.
我有两个问题。
其他信息:
答案 0 :(得分:0)
首先,不要每次都创建新的捕获。它不是那么麻烦,而且是一项非常昂贵的操作。
// 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
然后,将图像编码为std :: string可能会导致许多意外的文件截断(不知道,my.saveImage()正在做什么,但是零在图像中完全合法,但不是在字符串,对吗?)
为什么不在这里使用imwrite()?
最后但并非最不重要,2.3.1 非常旧,更好地更新到2.4.7