如何在不冻结的情况下显示cv::imshow("Live", frame) 和cv::imshow("ROI", frame_roi)?

问题描述 投票:0回答:0

我的目标是显示

cv::imshow("Live")
cv::imshow("ROI")
。问题是一段时间后窗口没有更新。尽管主函数循环仍在运行。

我预期的结果是窗口总是得到更新。

我的实际结果是一段时间后 Windows 没有更新。

我试过的:

  1. 假设
    cv::VideoCapture::read
    是罪魁祸首,不应被2个不同的线程调用。
  2. 假设
    cv::imshow
    是罪魁祸首,不应被2个不同的线程调用。
  3. 依赖参考:
    cv::Mat &frame
    cv::Mat &frame_roi
    被其他线程使用。
#include <opencv2/opencv.hpp>
#include <thread>

using namespace std::chrono_literals;

bool running_ = true;
std::mutex running_mutex_;

bool isRunning()
{
    std::lock_guard<std::mutex> lock(running_mutex_);
    return running_;
}

void setRunning(bool running)
{
    std::lock_guard<std::mutex> lock(running_mutex_);
    running_ = running;
}

void read(cv::Mat &frame, cv::VideoCapture &cap)
{
    while (isRunning())
    {
        cap.read(frame);
    }

    std::cout << "read exit\n";
}

void roi(cv::Mat &frame, cv::Mat &frame_roi)
{
    while (frame.empty()) continue;

    // Define the ROI
    int roi_x = 300;
    int roi_y = 200;
    int roi_width = 400;
    int roi_height = 300;

    cv::Rect rect(roi_x, roi_y, roi_width, roi_height);

    while (isRunning())
    {
        frame(rect).copyTo(frame_roi);
    }

    std::cout << "roi exit\n";
}

void imshow(cv::Mat &frame, cv::Mat &frame_roi)
{
    while (frame.empty() || frame_roi.empty()) continue;

    while (isRunning())
    {
        cv::imshow("Live", frame);
        cv::imshow("ROI", frame_roi);
    }

    std::cout << "imshow exit\n";
}

int main()
{
    cv::VideoCapture cap("nvarguscamerasrc sensor-id=0 ! "
                         "video/x-raw(memory:NVMM),width=(int)4656,height=(int)3496,format=(string)NV12,framerate=(fraction)9/1 ! "
                         "nvvidconv flip-method=0 ! "
                         "video/x-raw,width=(int)1280,height=(int)1280,format=(string)BGRx ! "
                         "videoconvert ! "
                         "video/x-raw,format=(string)BGR ! "
                         "appsink",
                         cv::CAP_GSTREAMER);
    if (!cap.isOpened())
    {
        std::cerr << "Failed to open camera" << std::endl;
        return -1;
    }

    cv::Mat frame;
    cv::Mat frame_roi;

    cv::namedWindow("Live", cv::WINDOW_NORMAL);
    cv::namedWindow("ROI", cv::WINDOW_NORMAL);

    // Start the threads
    std::thread t_read(read, std::ref(frame), std::ref(cap));
    std::thread t_roi(roi, std::ref(frame), std::ref(frame_roi));
    std::thread t_imshow(imshow, std::ref(frame), std::ref(frame_roi));

    int key;
    while (true)
    {
        key = cv::waitKey(100);
        if (key == 'q')
        {
            setRunning(false);
            break;
        }
    }

    std::cout << "waiting\n";

    // Wait for the threads to finish
    t_read.join();
    std::cout << "read joined\n";
    t_imshow.join();
    std::cout << "imshow joined\n";
    t_roi.join();
    std::cout << "roi joined\n";

    std::cout << "threads joined\n";

    // Release the camera and destroy the windows
    cap.release();
    cv::destroyAllWindows();

    return 0;
}
c++ multithreading opencv pthreads imshow
© www.soinside.com 2019 - 2024. All rights reserved.