OpenCV-来自摄像机的实时馈送不流畅

时间:2018-09-28 15:55:26

标签: c++ opencv

我正在尝试从网络摄像头捕获实时Feed,但是当我显示要捕获的帧时,该Feed并不流畅。显示帧之间有一个短暂的中断。

这是我的一些代码:

class Entity : public VideoLoader, public ImageReader, public Display
{
public:
    Entity();
    void init();
private:
    std::unique_ptr<VideoLoader> ptrVideoLoaderObj;
    std::unique_ptr<ImageReader> ptrImageReaderObj;
    std::unique_ptr<Display> ptrDisplayObj;
};

Entity::Entity()
{
    ptrVideoLoaderObj = std::make_unique<VideoLoader>();
    ptrImageReaderObj = std::make_unique<ImageReader>();
    ptrDisplayObj = std::make_unique<Display>();
}

void Entity::init()
{
    cv::Mat frame;

    while (true) {
        ptrVideoLoaderObj->loadImageFromCam(frame);

        if (ptrVideoLoaderObj->checkIfFrameIsEmpty(frame)) {
            std::cerr<<"ERROR: captured empty frame\n";
            break;
        }

        ptrDisplayObj->displayImage(frame);

        if (cv::waitKey(30) >= 0)
            break;
    }
}

这是捕获帧并显示帧的方法的实现:

class VideoLoader
{
public:
    cv::Mat loadImageFromCam(cv::Mat &frame);
    bool checkIfFrameIsEmpty(cv::Mat &frame);
private:
    cv::VideoCapture cam;
};

cv::Mat VideoLoader::loadImageFromCam(cv::Mat &frame)
{
    cam.open(0);
    cam >> frame;

    return frame;   
}


class Display
{
public:
    void displayImage(cv::Mat &img) const;
};

但是当我做这样的事情时:

Entity::Entity()
{
    cv::Mat frame;
    cv::VideoCapture cam(0);

    while (true) {
        cam >> frame;
        cv::imshow("feed", frame);

        if (cv::waitKey(30) >= 0)
            break;
    }
}

显示流畅。

我应该在代码中进行哪些更改才能获得平稳的供稿?

1 个答案:

答案 0 :(得分:0)

不要调用cam.open(0);在VideoLoader :: loadImageFromCam(cv :: Mat&frame)中,否则它将被重复调用。

class VideoLoader
{
public:
    cv::Mat loadImageFromCam(cv::Mat &frame);
    bool checkIfFrameIsEmpty(cv::Mat &frame);
    void OpenCam() { cam.open(0); }
private:
    cv::VideoCapture cam;
};


    cv::Mat VideoLoader::loadImageFromCam(cv::Mat &frame)
    {
        // cam.open(0); Don't use    
        cam >> frame;        
        return frame;   
    }


void Entity::init()
    {
        cv::Mat frame;
        ptrVideoLoaderObj->OpenCam(); // see this - call open only once
        while (true) {
            ptrVideoLoaderObj->loadImageFromCam(frame);

            if (ptrVideoLoaderObj->checkIfFrameIsEmpty(frame)) {
                std::cerr<<"ERROR: captured empty frame\n";
                break;
            }

            ptrDisplayObj->displayImage(frame);

            if (cv::waitKey(30) >= 0)
                break;
        }
    }