c++ - 在C++中使用OpenCV时网络摄像头的FPS随机下降

标签 c++ opencv frame-rate

我正在编写一个简单的OpenCV示例,以在5秒钟内获取网络摄像机帧(如果凸轮以〜30fps的速度运行,则为约150帧)。

经过一些测试后,我发现有时候我得到150张中的140张(我猜是可以接受的),但有时是70张。更糟糕的是,有时相机似乎会遭受那些丢帧的困扰,并在这种状态下保持数小时。

为了进一步研究该问题,我剥离了程序,直到我仍然遇到该问题,即使我仅读取帧但不将其写入磁盘。我设置了一个cron作业,以便每分钟运行5秒的捕获,并且我看到过这样的事情:
enter image description here

我认为前两个小滴是由于系统繁忙而引起的,但是永久的大滴是在深夜发生的。早晨,我停止了cron作业,触摸了代码中的某些内容(我不记得确切的内容),然后再次开始测试,以了解逐渐恢复,并在2-3小时后出现新的下降:
enter image description here

从昨天开始,我已经关闭计算机了几个小时,再次启动计算机并覆盖了摄像头,以确保恒定的光照条件,但是帧数仍然很低,并停留在70。此外,下降的确很奇怪( 150幅中有70幅)正好是我在本相机中看到的最大帧数的一半(150幅中有140幅)。

网络摄像头型号为Logitech C525。我也在Macbook Pro 2016年末Facetime HD摄像机中进行测试,在150帧中,我看到了恒定的117帧。我的一位同事也看到他的笔记本电脑出现帧掉落的情况。我的代码有问题吗?可以是线程优先级吗?

// Call the program like this: ./cameraTest pixelWidth pixelHeight fps timeLimit
// timeLimit can be 1 to run a fixed 5-seconds capture, or 0 to wait for 150 frames.

#include "opencv2/opencv.hpp"
#include "iostream"
#include "thread"
#include <unistd.h>
#include <chrono>
#include <ctime>
#include <experimental/filesystem>

using namespace cv;
namespace fs = std::experimental::filesystem;


VideoCapture camera(0);
bool stop = false;
int readFrames = 0;


std::string getTimeStamp()
{
  time_t rawtime;
  struct tm * timeinfo;
  char buffer[80];

  time(&rawtime);
  timeinfo = localtime(&rawtime);

  strftime(buffer,sizeof(buffer),"%Y-%m-%d %H:%M:%S",timeinfo);
  std::string timeStamp(buffer);
  return timeStamp;
}


void getFrame()
{
    Mat frame;
    camera >> frame;
    // camera.read(frame);
    // cv::imwrite("/tmp/frames/frame" + std::to_string(readFrames) + ".jpg", frame);
    readFrames++;
}


void getFrames()
{
    Mat frame;

    while(!stop)
    {
        camera >> frame;
        // cv::imwrite("/tmp/frames/frame" + std::to_string(fc) + ".jpg", frame);
        readFrames++;
    }
}


int main(int argc, char* argv[])
{
    if(argc < 5)
    {
        std::cout << "Usage: width height fps timeLimit" << std::endl;
        return -1;
    }

    if(!camera.isOpened())
    {
        std::cout << "Couldn't open camera " << getTimeStamp() << std::endl;
        return -1;
    }

    if (!fs::is_directory("/tmp/frames"))
    {
        if(system("mkdir -p /tmp/frames") != 0)
        {
            std::cout << "Error creating /tmp/frames/" << std::endl;
        }
    }

    if (!fs::is_empty("/tmp/frames"))
    {
        system("exec rm /tmp/frames/*");
    }

    camera.set(CV_CAP_PROP_FRAME_WIDTH, atoi(argv[1]));
    camera.set(CV_CAP_PROP_FRAME_HEIGHT, atoi(argv[2]));
    camera.set(CV_CAP_PROP_FPS, atoi(argv[3]));
    //camera.set(CV_CAP_PROP_FOURCC, CV_FOURCC('M', 'J', 'P', 'G'));

    bool timeLimit(atoi(argv[4]));

    std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();

    int waitSeconds = 5;

    if(timeLimit)
    {
        std::thread tr(getFrames);
        usleep(waitSeconds * 1e6);
        stop = true;
        tr.join();
    }
    else
    {
        while(readFrames < 150)
        {
            getFrame();
        }
    }

    std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();

    std::cout << getTimeStamp() << " " << readFrames << "/" << atoi(argv[3]) * waitSeconds << " "
            << std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count() << "ms"
            << " " << atoi(argv[1]) << "," << atoi(argv[2]) << "," << atoi(argv[3])
            << std::endl;

    return 0;
}

最佳答案

似乎与弱光条件有关。一旦发现了卡马拉,我便看到框架增加到了它们的预期值。因此,在光线不足的情况下,相机可能会更改某些设置或进一步处理图像,从而降低其帧速率。

enter image description here

关于c++ - 在C++中使用OpenCV时网络摄像头的FPS随机下降,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60967068/

相关文章:

c++ - OpenCV 具有相似颜色背景的颜色检测

c++ - C++ 模板特化中声明的范围

c++ - 编译时错误,参数被识别为引用

opencv - 如何使用OpenCV停止随机林中的随机采样?

android - 如何在 android 中对动画的 fps 进行基准测试?

JAVA简单的fps动画(我该如何使用?)

javascript - 尝试使用 getUserMedia 帧速率约束

c++ - 在没有 goto 和提前返回的情况下在 C++ 中执行多个相关错误检查的优雅方法?

c++ - 在我从旧版 DirectX SDK 更改为 Windows SDK(Visual Studio 2015)后,链接器一直在提示)

c++ - 在 OpenCV 中实现热视觉