Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.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
在C++中使用树莓PI摄像头V4L2能获得好的FPS吗? 我试图用R4Be2.0的官方V4L2驱动程序在RasBuriPi上视频,从RasbIUS 2015-02发布的C++中得到,我的FPS问题很低。_C++_Linux_Raspberry Pi_V4l2_Raspberry Pi2 - Fatal编程技术网

在C++中使用树莓PI摄像头V4L2能获得好的FPS吗? 我试图用R4Be2.0的官方V4L2驱动程序在RasBuriPi上视频,从RasbIUS 2015-02发布的C++中得到,我的FPS问题很低。

在C++中使用树莓PI摄像头V4L2能获得好的FPS吗? 我试图用R4Be2.0的官方V4L2驱动程序在RasBuriPi上视频,从RasbIUS 2015-02发布的C++中得到,我的FPS问题很低。,c++,linux,raspberry-pi,v4l2,raspberry-pi2,C++,Linux,Raspberry Pi,V4l2,Raspberry Pi2,目前,我只是创建一个窗口并将缓冲区复制到屏幕上,这大约需要30毫秒,而select大约需要140毫秒,总共需要5-6 fps。我还尝试了100毫秒的睡眠时间,它将选择时间减少了相似的数量,从而产生了相同的fps。CPU负载约为5-15% 我还尝试从控制台或系统更改驾驶员fps,但它只能向下工作,例如,如果我将驾驶员fps设置为1fps,我将获得1fps,但如果我将其设置为90fps,我仍然获得5-6fps,即使驾驶员确认将其设置为90fps。 此外,当查询FPS模式以获得使用的分辨率时,我得到了

目前,我只是创建一个窗口并将缓冲区复制到屏幕上,这大约需要30毫秒,而select大约需要140毫秒,总共需要5-6 fps。我还尝试了100毫秒的睡眠时间,它将选择时间减少了相似的数量,从而产生了相同的fps。CPU负载约为5-15%

我还尝试从控制台或系统更改驾驶员fps,但它只能向下工作,例如,如果我将驾驶员fps设置为1fps,我将获得1fps,但如果我将其设置为90fps,我仍然获得5-6fps,即使驾驶员确认将其设置为90fps。 此外,当查询FPS模式以获得使用的分辨率时,我得到了90fps

我包括了与V4L2代码相关的代码部分,这些代码在不同部分之间省略:

以及主循环中的最后两部分:

//////////////////
// Get frame
//////////////////
FD_ZERO(&fds);
    FD_SET(mFD, &fds);
    tv.tv_sec = 3;
    tv.tv_usec = 0;

    struct timespec t0, t1;

    clock_gettime(CLOCK_REALTIME, &t0);

    // This line takes about 140ms which I don't get
    r = select(mFD + 1, &fds, NULL, NULL, &tv);

    clock_gettime(CLOCK_REALTIME, &t1);

    cout << "select time : " << ((float)(t1.tv_sec - t0.tv_sec))*1000.0f + ((float)(t1.tv_nsec - t0.tv_nsec))/1000000.0f << "\n";

    if (-1 == r)
    {
        if (EINTR == errno)
            continue;
        ErrnoExit("select");
    }

    if (r == 0)
        throw "Select timeout\n";

    // Read the frame
    //~ struct v4l2_buffer buf;
    memset(&mCurBuf, 0, sizeof(mCurBuf));
    mCurBuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    mCurBuf.memory = V4L2_MEMORY_MMAP;

    // DQBUF about 2ms
    if (-1 == Xioctl(VIDIOC_DQBUF, &mCurBuf))
    {
        if (errno == EAGAIN) continue;
        ErrnoExit("DQBUF");
    }

    clock_gettime(CLOCK_REALTIME, &mCaptureTime);

    // Manage frame in mBuffers[buf.index]
    mCurBufIndex = mCurBuf.index;

    break;
}

//////////////////
// Release frame
//////////////////
if (-1 == Xioctl(VIDIOC_QBUF, &mCurBuf))
    ErrnoExit("VIDIOC_QBUF during mainloop");

我一直在研究使用picamera的各种方法,我不是一个专家,但似乎默认的相机设置是阻碍你的因素。有许多模式和开关。我不知道它们是不是通过IOCTL暴露出来的,或者是如何暴露出来的,我才刚开始。但我必须使用一个名为v4l ctl的程序来为我想要的模式做好准备。深入研究该源代码和一些代码提升应该会让您取得伟大的成就。哦,我怀疑select调用是个问题,它只是在等待描述符,而描述符的可读性很慢。根据模式等,可以强制等待自动曝光等。
编辑:我想说的是默认设置,因为您已经更改了一些。还有一些规则未编入驱动程序。

像素格式很重要。我遇到了类似的低FPS问题,我花了一些时间使用V4L2 API在GO和C++中使用我的程序进行测试。我发现,Rpi Cam模块与H.264/MJPG像素格式具有良好的加速性能。我可以轻松地以640*480的速度获得60fps,与YUYV/RGB等非压缩格式相同。然而,JPEG运行非常慢。即使是320*240,我也只能得到4fps。我还发现JPEG的电流大于700mA,而H.264/MJPG的电流大于500mA。

尽管select看起来有点慢,但你为什么要用它呢?为什么需要超时来增加计算量?谢谢你的回答。我没有检查答案,因为我现在使用的是raspicam,它是mmal包装器,提供更好的性能。我不想潜入mmal本身,这对我来说不是一项值得的投资!所以raspicam提供的中间层很好。
//////////////////
// Get frame
//////////////////
FD_ZERO(&fds);
    FD_SET(mFD, &fds);
    tv.tv_sec = 3;
    tv.tv_usec = 0;

    struct timespec t0, t1;

    clock_gettime(CLOCK_REALTIME, &t0);

    // This line takes about 140ms which I don't get
    r = select(mFD + 1, &fds, NULL, NULL, &tv);

    clock_gettime(CLOCK_REALTIME, &t1);

    cout << "select time : " << ((float)(t1.tv_sec - t0.tv_sec))*1000.0f + ((float)(t1.tv_nsec - t0.tv_nsec))/1000000.0f << "\n";

    if (-1 == r)
    {
        if (EINTR == errno)
            continue;
        ErrnoExit("select");
    }

    if (r == 0)
        throw "Select timeout\n";

    // Read the frame
    //~ struct v4l2_buffer buf;
    memset(&mCurBuf, 0, sizeof(mCurBuf));
    mCurBuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    mCurBuf.memory = V4L2_MEMORY_MMAP;

    // DQBUF about 2ms
    if (-1 == Xioctl(VIDIOC_DQBUF, &mCurBuf))
    {
        if (errno == EAGAIN) continue;
        ErrnoExit("DQBUF");
    }

    clock_gettime(CLOCK_REALTIME, &mCaptureTime);

    // Manage frame in mBuffers[buf.index]
    mCurBufIndex = mCurBuf.index;

    break;
}

//////////////////
// Release frame
//////////////////
if (-1 == Xioctl(VIDIOC_QBUF, &mCurBuf))
    ErrnoExit("VIDIOC_QBUF during mainloop");