使用队列制作可变大小的延迟帧缓冲区时出现意外行为

时间:2018-07-02 08:31:31

标签: c++ opencv queue framebuffer fifo

我正在尝试使用立体声摄像机的实时数据制作两个左右帧缓冲队列。按键时,清空帧缓冲区,然后在左右摄像机继续以相同速率继续推入两个队列之前,可以选择在左侧或右侧填充多个黑框,并且两个队列的前面以相等的速度读取并弹出。这应该导致,当队列到达黑帧的末尾时,左缓冲区和右缓冲区的黑帧数量将不同步。

但是,在我的实现中,尽管队列大小适当增加,并且黑框正确填充,但是当黑框结束时,两个缓冲区都显示同一时间点的帧(如我所看到的那样)帧号)。确实,在那一点上,较大(延迟)缓冲区中的每个帧似乎都是相同的。我在执行过程中做错了什么?

// Standard includes
#include <stdio.h>
#include <string.h>

// ZED include
#include <sl/Camera.hpp>

// OpenCV include (for display)
#include <opencv2/opencv.hpp>

// Using std and sl namespaces
using namespace std;
using namespace sl;

// Sample functions
void updateCameraSettings(char key, sl::Camera &zed);
void switchCameraSettings();
void printHelp();

// Sample variables
CAMERA_SETTINGS camera_settings_ = CAMERA_SETTINGS_BRIGHTNESS;
string str_camera_settings = "BRIGHTNESS";
int step_camera_setting = 1;

//
//Create bias counters
int currentBias = 0;
int prevBias = 0;
bool change = false;




int main(int argc, char **argv) {

    InitParameters init_params;
    init_params.camera_resolution = RESOLUTION_VGA; // Use HD1080 video mode
    init_params.camera_fps = 0; // Set fps at 30
    init_params.depth_mode = DEPTH_MODE_NONE;

    // Create a ZED Camera object
    Camera zed;

    // Open the camera
    ERROR_CODE err = zed.open(init_params);
    if (err != SUCCESS) {
        cout << toString(err) << endl;
        zed.close();
        return 1; // Quit if an error occurred
    }

    // Print help in console
    printHelp();

    // Print camera information
    printf("ZED Model                 : %s\n", toString(zed.getCameraInformation().camera_model).c_str());
    printf("ZED Serial Number         : %d\n", zed.getCameraInformation().serial_number);
    printf("ZED Firmware              : %d\n", zed.getCameraInformation().firmware_version);
    printf("ZED Camera Resolution     : %dx%d\n", (int)zed.getResolution().width, (int)zed.getResolution().height);
    printf("ZED Camera FPS            : %d\n", (int)zed.getCameraFPS());

    // Create a Mat to store images
    cv::Mat stitchImage;
    Mat imageL;
    Mat imageR;
    cv::Mat tempL;
    cv::Mat tempR;
    cv::Mat blackScr;

    //Create framebuffer
    std::queue<cv::Mat> LeftQueue;
    std::queue<cv::Mat> RightQueue;
    std::queue<cv::Mat> emptyQueue;

    int height = 0;
    int width = 0;

    int frameInc = 0;

    // Capture new images until 'q' is pressed
    char key = ' ';
    while (key != 'q') {

        // Check that grab() is successful
        if (zed.grab() == SUCCESS) {
            // Retrieve left image
            zed.retrieveImage(imageL, VIEW_LEFT);
            zed.retrieveImage(imageR, VIEW_RIGHT);
            height = (int)imageL.getHeight();
            width = (int)imageL.getWidth();

            tempL = cv::Mat(height, width, CV_8UC4, imageL.getPtr<sl::uchar1>(sl::MEM_CPU));
            tempR = cv::Mat(height, width, CV_8UC4, imageR.getPtr<sl::uchar1>(sl::MEM_CPU));
            blackScr = cv::Mat(height, width, CV_8UC4, cv::Scalar(0, 0, 0));

            cv::putText(tempL, std::to_string(frameInc), cv::Point(30, 30), cv::FONT_ITALIC, .5, cv::Scalar(180, 180, 180), 1, CV_AA);
            cv::putText(tempR, std::to_string(frameInc), cv::Point(30, 30), cv::FONT_ITALIC, .5, cv::Scalar(180, 180, 180), 1, CV_AA);
            frameInc++;


            if (currentBias != prevBias) {
                std::cout << "Change detected! Making new framebuffers" << std::endl;
                LeftQueue = std::queue<cv::Mat>();
                RightQueue = std::queue<cv::Mat>();
                if (currentBias < 0) {
                    std::cout << "Biasing Left Eye!" << std::endl;
                    for (int i = 1; i <= abs(currentBias); i++) {

                        LeftQueue.push(blackScr);
                        std::cout << "LeftQueue: " << LeftQueue.size() << std::endl;
                    }
                    std::cout << "Current Bias is: " << currentBias << std::endl;
                    std::cout << "LeftQueue: " << LeftQueue.size() << std::endl;
                    std::cout << "RightQueue: " << RightQueue.size() << std::endl;

                }
                else if (currentBias > 0) {
                    std::cout << "Biasing Right Eye!" << std::endl;
                    for (int i = 1; i <= abs(currentBias); i++) {

                        RightQueue.push(blackScr);
                        std::cout << "RightQueue: " << RightQueue.size() << std::endl;
                    }
                    std::cout << "Current Bias is: " << currentBias << std::endl;
                    std::cout << "LeftQueue: " << LeftQueue.size() << std::endl;
                    std::cout << "RightQueue: " << RightQueue.size() << std::endl;
                }
                else {
                    std::cout << "Resetting to no delay!" << std::endl;
                    std::cout << "Current Bias is: " << currentBias << std::endl;


                    std::cout << "LeftQueue: " << LeftQueue.size() << std::endl;
                    std::cout << "RightQueue: " << RightQueue.size() << std::endl;


                }
                prevBias = currentBias;
            }

            //Typical queue push
            LeftQueue.push(tempL);
            RightQueue.push(tempR);

            //Make OpenCV output
            cv::hconcat(LeftQueue.front(), RightQueue.front(), stitchImage);


            std::cout << "LeftFront: " << &LeftQueue.front() << std::endl;
            std::cout << "LeftBack: " << &LeftQueue.back() << std::endl;

            // Display image with OpenCV
            cv::imshow("VIEW", stitchImage);
            LeftQueue.pop();
            RightQueue.pop();
            key = cv::waitKey(5);

            // Change camera settings with keyboard
            updateCameraSettings(key, zed);
        }
        else
            key = cv::waitKey(5);
    }

    // Exit
    zed.close();
    return EXIT_SUCCESS;
}

/**
    This function updates camera settings
 **/
void updateCameraSettings(char key, sl::Camera &zed) {
    int current_value;

    // Keyboard shortcuts
    switch (key) {

    case 'l':
        currentBias = currentBias - 10;
        std::cout << "Bias Delay Left by 10 Frames" << std::endl;
        std::cout << "Current Bias is: " << currentBias << std::endl;
        break;

    case 'r':
        currentBias = currentBias + 10;
        std::cout << "Bias Delay Right by 10 Frames" << std::endl;
        std::cout << "Current Bias is: " << currentBias << std::endl;
        break;



        // Switch to the next camera parameter
    case 's':
        switchCameraSettings();
        break;

        // Increase camera settings value ('+' key)
    case '+':
        current_value = zed.getCameraSettings(camera_settings_);
        zed.setCameraSettings(camera_settings_, current_value + step_camera_setting);
        std::cout << str_camera_settings << ": " << current_value + step_camera_setting << std::endl;
        break;

        // Decrease camera settings value ('-' key)
    case '-':
        current_value = zed.getCameraSettings(camera_settings_);
        if (current_value >= 1) {
            zed.setCameraSettings(camera_settings_, current_value - step_camera_setting);
            std::cout << str_camera_settings << ": " << current_value - step_camera_setting << std::endl;
        }
        break;

        // Reset to default parameters
    case 'x':
        currentBias = 0;
        std::cout << "Reset all settings to default" << std::endl;

        zed.setCameraSettings(sl::CAMERA_SETTINGS_BRIGHTNESS, -1, true);
        zed.setCameraSettings(sl::CAMERA_SETTINGS_CONTRAST, -1, true);
        zed.setCameraSettings(sl::CAMERA_SETTINGS_HUE, -1, true);
        zed.setCameraSettings(sl::CAMERA_SETTINGS_SATURATION, -1, true);
        zed.setCameraSettings(sl::CAMERA_SETTINGS_GAIN, -1, true);
        zed.setCameraSettings(sl::CAMERA_SETTINGS_EXPOSURE, -1, true);
        zed.setCameraSettings(sl::CAMERA_SETTINGS_WHITEBALANCE, -1, true);
        break;
    }
}

/**
    This function toggles between camera settings
 **/
void switchCameraSettings() {
    step_camera_setting = 1;
    switch (camera_settings_) {
    case CAMERA_SETTINGS_BRIGHTNESS:
        camera_settings_ = CAMERA_SETTINGS_CONTRAST;
        str_camera_settings = "Contrast";
        std::cout << "Camera Settings: CONTRAST" << std::endl;
        break;

    case CAMERA_SETTINGS_CONTRAST:
        camera_settings_ = CAMERA_SETTINGS_HUE;
        str_camera_settings = "Hue";
        std::cout << "Camera Settings: HUE" << std::endl;
        break;

    case CAMERA_SETTINGS_HUE:
        camera_settings_ = CAMERA_SETTINGS_SATURATION;
        str_camera_settings = "Saturation";
        std::cout << "Camera Settings: SATURATION" << std::endl;
        break;

    case CAMERA_SETTINGS_SATURATION:
        camera_settings_ = CAMERA_SETTINGS_GAIN;
        str_camera_settings = "Gain";
        std::cout << "Camera Settings: GAIN" << std::endl;
        break;

    case CAMERA_SETTINGS_GAIN:
        camera_settings_ = CAMERA_SETTINGS_EXPOSURE;
        str_camera_settings = "Exposure";
        std::cout << "Camera Settings: EXPOSURE" << std::endl;
        break;

    case CAMERA_SETTINGS_EXPOSURE:
        camera_settings_ = CAMERA_SETTINGS_WHITEBALANCE;
        str_camera_settings = "White Balance";
        step_camera_setting = 100;
        std::cout << "Camera Settings: WHITE BALANCE" << std::endl;
        break;

    case CAMERA_SETTINGS_WHITEBALANCE:
        camera_settings_ = CAMERA_SETTINGS_BRIGHTNESS;
        str_camera_settings = "Brightness";
        std::cout << "Camera Settings: BRIGHTNESS" << std::endl;
        break;
    }
}

/**
    This function displays help
 **/
void printHelp() {
    cout << endl;
    cout << endl;
    cout << "Camera controls hotkeys: " << endl;
    cout << "  Increase camera settings value:            '+'" << endl;
    cout << "  Decrease camera settings value:            '-'" << endl;
    cout << "  Toggle camera settings:                    's'" << endl;
    cout << "  Reset all parameters:                      'r'" << endl;
    cout << endl;
    cout << "Exit : 'q'" << endl;
    cout << endl;
    cout << endl;
    cout << endl;
}

0 个答案:

没有答案