C++ 在OpenCV中动态更改视频

C++ 在OpenCV中动态更改视频,c++,opencv,C++,Opencv,我有3个视频源连接到我的电脑,我想在一个屏幕上显示它们。 我最初开始将视频源放在彼此相邻的位置,效果很好,但我希望能够在运行时启用/禁用每个视频源 所以我想用键盘键(r(右)和l(左))来改变目前正在显示的摄像机 我想将以下3个变量的声明移动到while循环的外部,这样我就可以在if情况下访问它们并更改它们 cv::Mat3b combinedFrame(camRightSize.height, camMiddleSize.width + camRightSize.width);

我有3个视频源连接到我的电脑,我想在一个屏幕上显示它们。 我最初开始将视频源放在彼此相邻的位置,效果很好,但我希望能够在运行时启用/禁用每个视频源

所以我想用键盘键(r(右)和l(左))来改变目前正在显示的摄像机

我想将以下3个变量的声明移动到while循环的外部,这样我就可以在if情况下访问它们并更改它们

    cv::Mat3b combinedFrame(camRightSize.height, camMiddleSize.width + camRightSize.width);

    cv::Mat3b leftSideOfScreen(combinedFrame, Rect(0, 0, camMiddleSize.width, camMiddleSize.height));
    cameraMiddleFrameMirroredResize.copyTo(leftSideOfScreen);
    cv::Mat3b rightSideOfScreen(combinedFrame, Rect(camMiddleSize.width, 0, camRightSize.width, camRightSize.height));
以下是我的全部代码:

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

    int combinedScreenWidth = 1440;
    int combinedScreenHeight = 540;
    int rearCameraBiggerByThis = 200;
    int combinedScreenWidthHalv = combinedScreenWidth / 2;

    bool showRight = true;
    bool showLeft = false;

    //initialize and allocate memory to load the video stream from camera 

    cv::VideoCapture cameraRight(0);    // RIGHT
    cv::VideoCapture cameraMiddle(3);   // REAR
    cv::VideoCapture cameraLeft(3);     // LEFT

    if (!cameraRight.isOpened())    return 1;
    if (!cameraMiddle.isOpened())   return 1;
    if (!cameraLeft.isOpened())     return 1;

    cv::Mat3b cameraRightFrame;
    cv::Mat3b cameraMiddleFrame;
    cv::Mat3b cameraLeftFrame;

    cv::Mat3b cameraRightFrameMirrored;
    cv::Mat3b cameraMiddleFrameMirrored;
    cv::Mat3b cameraLeftFrameMirrored;

    Size camRightSize;
    Size camMiddleSize;
    Size camLeftSize;

    cv::Mat3b cameraRightFrameMirroredResize;
    cv::Mat3b cameraMiddleFrameMirroredResize;
    cv::Mat3b cameraLeftFrameMirroredResize;


    while (true) {
        // Grab and retrieve each frames of the video sequentially 
        cameraRight >> cameraRightFrame;
        cameraMiddle >> cameraMiddleFrame;
        cameraLeft >> cameraLeftFrame;
        // Mirror
        cv::flip(cameraRightFrame, cameraRightFrameMirrored, 1);
        cv::flip(cameraMiddleFrame, cameraMiddleFrameMirrored, 1);
        cv::flip(cameraLeftFrame, cameraMiddleFrameMirrored, 1);
        // Resize
        camRightSize = cameraRightFrame.size();
        camMiddleSize = cameraMiddleFrame.size();
        camLeftSize = cameraLeftFrame.size();

        resize(cameraMiddleFrameMirrored, cameraMiddleFrameMirroredResize, Size(combinedScreenWidthHalv + rearCameraBiggerByThis, combinedScreenHeight));
        resize(cameraRightFrameMirrored, cameraRightFrameMirroredResize, Size(combinedScreenWidthHalv - rearCameraBiggerByThis, combinedScreenHeight));

        // Compilation
        camRightSize = cameraRightFrameMirroredResize.size();
        camMiddleSize = cameraMiddleFrameMirroredResize.size();
        camLeftSize = cameraLeftFrameMirroredResize.size();

        if (showRight && showLeft) {    // LEFT + REAR + RIGHT

        } else if (showRight) {         // REAR + RIGHT

        } else if (showLeft) {          // LEFT + REAR

        } else {                        // REAR

        }

        cv::Mat3b combinedFrame(camRightSize.height, camMiddleSize.width + camRightSize.width);

        cv::Mat3b leftSideOfScreen(combinedFrame, Rect(0, 0, camMiddleSize.width, camMiddleSize.height));
        cameraMiddleFrameMirroredResize.copyTo(leftSideOfScreen);
        cv::Mat3b rightSideOfScreen(combinedFrame, Rect(camMiddleSize.width, 0, camRightSize.width, camRightSize.height));
        cameraRightFrameMirroredResize.copyTo(rightSideOfScreen);

        // declare windows
        cv:namedWindow("Combined", CV_WINDOW_NORMAL);
        cv::setWindowProperty("Combined", CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);
        cv::putText(combinedFrame, "REAR", cv::Point(500, 50), cv::FONT_HERSHEY_PLAIN, 2.0, cv::Scalar(255, 255, 255), 2 );

        cv::putText(combinedFrame, "RIGHT", cv::Point(950, 50), cv::FONT_HERSHEY_PLAIN, 2.0, cv::Scalar(255, 255, 255), 2 );


        cv::imshow("Combined", combinedFrame);          // 1440 x 540 Screen size
        //cv::imshow("Right Cam", cameraRightFrame);
        //cv::imshow("Middle Cam", cameraMiddleFrame);
        //cv::imshow("Left Cam", cameraLeftFrame);


        //wait for 40 milliseconds
        int c = cvWaitKey(1);

        //exit the loop if user press "Esc" key  (ASCII value of "Esc" is 27) 
        if (27 == char(c)) {
            break;
        }
        else if (114 == char(c)) {
            showRight = !showRight;
        }
        else if (108 == char(c)) {
            showLeft = !showLeft;
        }
    }

    return 0;
}

根据你的描述,我认为你想写的是:

combinedFrame(Rect(0, 0, camMiddleSize.width, camMiddleSize.height)).copyTo(leftSideOfScreen);
即:

  • 从另一个创建
    cv::Mat
    (调用
    cv::Mat::copyTo(cv::Mat&)
  • “源矩阵”是通过从
    combinedFrame
    combinedFrame(Rect(0,0,cammidleSize.width,cammidleSize.height))中提取矩形来获得的。

    • 根据你的描述,我认为你想写的是:

      combinedFrame(Rect(0, 0, camMiddleSize.width, camMiddleSize.height)).copyTo(leftSideOfScreen);
      
      即:

      • 从另一个创建
        cv::Mat
        (调用
        cv::Mat::copyTo(cv::Mat&)
      • “源矩阵”是通过从
        combinedFrame
        combinedFrame(Rect(0,0,cammidleSize.width,cammidleSize.height))中提取矩形来获得的。

      您调用的是一个不存在的重载(该消息对此相当清楚)。我所能看到的最近的是。那句话应该是什么意思?为什么不只是
      cv::Mat3b::Mat
      ?它是相同的类型,您只需从其派生类中查找即可
      int(camRightSize.width)
      ——因为它是
      cv::Size
      ,所以它已经是一个int了。即使你喜欢键入很多(基于标识符),更多的代码意味着更多的错误可能性和更多的维护工作,所以最好避免冗余最后一件事-名称空间限定不一致。只需使用名称空间cv删除
      ,它是一个。您正在调用一个不存在的重载(该消息对此相当清楚)。我所能看到的最近的是。那句话应该是什么意思?为什么不只是
      cv::Mat3b::Mat
      ?它是相同的类型,您只需从其派生类中查找即可
      int(camRightSize.width)
      ——因为它是
      cv::Size
      ,所以它已经是一个int了。即使你喜欢键入很多(基于标识符),更多的代码意味着更多的错误可能性和更多的维护工作,所以最好避免冗余最后一件事-名称空间限定不一致。只需使用名称空间cv删除
      ,这是一个。嗯,你能指出这个特定操作符重载的文档(或实现)吗?我不知道它的存在,我的编译器也不知道即使它确实存在,这在以后阅读时也会很尴尬,我更喜欢一个简单的赋值,这样可以清楚地说明发生了什么。赋值将共享内部数据。我想在你的情况下,最好是复制或克隆。让我更新一下答案。据我所知,共享数据是这里的重点。OP从完整的目标帧中获取ROI,以便将经过处理的帧从相机复制到其中(在下面的语句中)。共享数据应该可以工作,但我还没有使用OpenCV 3.x测试描述数据逐行布局的变量是否仍然正确更新<代码>屏幕左侧=组合帧(Rect(0,0,cammidlesize.width,cammidlesize.height))嗯,你能指出这个特定操作符重载的文档(或实现)吗?我不知道它的存在,我的编译器也不知道即使它确实存在,这在以后阅读时也会很尴尬,我更喜欢一个简单的赋值,这样可以清楚地说明发生了什么。赋值将共享内部数据。我想在你的情况下,最好是复制或克隆。让我更新一下答案。据我所知,共享数据是这里的重点。OP从完整的目标帧中获取ROI,以便将经过处理的帧从相机复制到其中(在下面的语句中)。共享数据应该可以工作,但我还没有使用OpenCV 3.x测试描述数据逐行布局的变量是否仍然正确更新<代码>屏幕左侧=组合帧(Rect(0,0,cammidlesize.width,cammidlesize.height))