简体   繁体   中英

OpenCV - Live feed from camera is not smooth

I'm trying to capture live feed from my webcam, but when I display frames, which I'm capturing, that feed is not smooth. There is a short break between displaying frames.

Here is some of my code:

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

Here is implementation of methods, which are capturing frames and displaying frames:

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

But when I do something like this:

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

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

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

I got smooth displaying.

What should I change in my code to get that smooth feed?

Don't call cam.open(0); in VideoLoader::loadImageFromCam(cv::Mat &frame) else it will be called repeatedly.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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