我的目标是显示
cv::imshow("Live")
和cv::imshow("ROI")
。问题是一段时间后窗口没有更新。尽管主函数循环仍在运行。
我预期的结果是窗口总是得到更新。
我的实际结果是一段时间后 Windows 没有更新。
我试过的:
cv::VideoCapture::read
是罪魁祸首,不应被2个不同的线程调用。cv::imshow
是罪魁祸首,不应被2个不同的线程调用。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;
}