Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opencv 在多次cv::VideoCapture()构造之后,cv::VideoCapture::grab()中的Segfault_Opencv - Fatal编程技术网

Opencv 在多次cv::VideoCapture()构造之后,cv::VideoCapture::grab()中的Segfault

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

在下面的代码中,我从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();
}
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