简体   繁体   English

在 C++ 中使用 OpenCV 时,网络摄像头出现明显的 FPS 随机下降

[英]Apparent FPS random drop in webcam when using OpenCV in C++

I'm coding a simple OpenCV example to get webcam frames during 5 seconds (~150 frames if the cam works at ~30fps).我正在编写一个简单的 OpenCV 示例,以在 5 秒内获取网络摄像头帧(如果摄像头以 ~30fps 的速度工作,则为 ~150 帧)。

After making some tests, I see that sometimes I get ~140 out of 150 frames (acceptable, I guess), but sometimes ~70.在进行了一些测试之后,我发现有时我在 150 帧中得到了大约 140 帧(我猜是可以接受的),但有时是 70 帧。 Even worse, sometimes the camera seems to suffer from those frame drops and keep in that state for hours.更糟糕的是,有时相机似乎会受到那些帧丢失的影响并保持该状态数小时。

To investigate the problem further, I stripped my program until I still have that issue even if I only read frames, but do not write them to disk.为了进一步调查这个问题,我剥离了我的程序,直到即使我只读取帧,但不将它们写入磁盘,我仍然有那个问题。 I've set a cron job in order to run a 5-seconds capture every minute, and I've been seen things like this:我已经设置了一个 cron 作业,以便每分钟运行 5 秒的捕获,并且我已经看到过这样的事情: 在此处输入图片说明

I think the two first small drops were due to system being busy, but the big, permanent one occurred in the middle of the night.我认为前两个小下降是由于系统繁忙,但大的、永久性的下降发生在半夜。 In the morning, I stopped the cron job, touched some things in the code (I can't remember exactly what) and started the test again, to see a gradual recovery followed by a new drop after 2-3 hours:早上,我停止了 cron 工作,触及了代码中的一些东西(我不记得具体是什么)并再次开始测试,看到逐渐恢复,然后在 2-3 小时后出现新的下降: 在此处输入图片说明

Since yesterday, I've turned off the computer for several hours, booted it up again and covered the webcam to ensure constant light conditions, but the frame count is still low, and stuck on 70. Also, it's really weird that the drop (70 frames out of 150) goes to exactly half the max frames I've seen in this camera (140 frames out of 150).从昨天开始,我把电脑关了几个小时,再次启动并覆盖网络摄像头以确保恒定的光照条件,但帧数仍然很低,一直停留在 70。而且,下降(真的很奇怪)( 150 帧中有 70 帧)正好是我在这台相机中看到的最大帧数的一半(150 帧中有 140 帧)。

The webcam model is Logitech C525.网络摄像头型号为罗技 C525。 I'm also testing in a Macbook Pro Late 2016 Facetime HD camera and there I see a constant 117 frames out of 150. A colleague of mine also sees frame drops in his laptop.我还在 Macbook Pro 2016 年末 Facetime 高清摄像头上进行测试,我看到 150 帧中有 117 帧恒定。我的一位同事也看到他的笔记本电脑掉帧。 Is there some problem with my code?我的代码有问题吗? Could it be thread priority?可能是线程优先级吗?

// 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;
}

It seems it has to do with low-light conditions.这似乎与弱光条件有关。 As soon as I uncovered the camara, I saw the frames increase to their expected value.一旦我发现相机,我就看到帧增加到它们的预期值。 So maybe on poor light conditions, the camera changes some settings or further processes the images, lowering its framerate.因此,可能在光线不足的情况下,相机会更改某些设置或进一步处理图像,从而降低其帧率。

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM