Opencv 写入和读取缓冲区
Opencv writing and reading from a buffer
我有两个任务(线程)每个任务在不同的处理器(核心)上运行,第一个使用 OpenCV 重复捕获图像 videocapture()
。
我只用了这两行来捕获:
cv::Mat frame;
capture.read(frame);
现在我想使用第二个任务显示捕获的图像。在第二个任务的代码中执行 imshow
函数后:
cv::imshow("Display window", frame);
我收到以下输出错误:
OpenCV Error: Assertion failed (size.width>0 && size.height>0) in imshow, file /build/opencv-L2vuMj/opencv-3.2.0+dfsg/modules/highgui/src/window.cpp, line 304
terminate called after throwing an instance of 'cv::Exception'
what(): /build/opencv-L2vuMj/opencv-3.2.0+dfsg/modules/highgui/src/window.cpp:304: error: (-215) size.width>0 && size.height>0 in function imshow
那么,我该如何避免这个错误呢?
完整代码托管在 Github
int main()
{
VideoCapture cap;
while(1){
Mat frame;
cap >> frame;
imshow("frame",frame);
waitKey();}
}
你可以试试这个。 İf 你写 waitKey();代码要按任意键获取框架和显示框架。
cv::VideoCapture::read()
returns bool
表示读取是否成功。
您正在将空 frame
传递给 cv::imshow()
。在尝试显示之前尝试检查读取是否成功。
cv::Mat frame;
if(capture.read(frame))
{
cv::imshow(frame);
}
编辑
OP 向代码发布了 link。在他的程序中 frame
被声明为全局变量。在 120
capture.read(frame)
行中写入帧,在 140
imshow(frame)
行中不使用互斥锁从 frame
中读取 - 这是一场数据竞争。正确的代码应该是这样的:
#include <mutex>
#include <opencv2/opencv.hpp>
std::mutex mutex;
cv::Mat frame;
{
mutex.lock();
capture.read(frame);
mutex.unlock();
}
{
mutex.lock();
cv::imshow(frame);
mutex.unlock();
}
您的代码存在数据竞争问题。假设显示线程首先锁定框架并在读取之前尝试显示它,这样您就可以看到问题所在
如果你想要一个同步的解决方案,你可以使用 pthread 条件并等到图像被读取来通知你的显示功能,否则你将有一个积极的等待!!
// in the declaration part
// Declaration of thread condition variable
pthread_cond_t cond1 = PTHREAD_COND_INITIALIZER;
//in the display function
ptask DisplyingImageTask()
{
int task_job = 0;
while (1)
{
std::cout << "The job " << task_job << " of Task T" << ptask_get_index()
<< " is running on core " << sched_getcpu() << " at time : "
<< ptask_gettime(MILLI) << std::endl;
cv::namedWindow("Display window", cv::WINDOW_AUTOSIZE);
pthread_mutex_lock(&frame_rw);
//wait for the read function to send a signal
pthread_cond_wait(&cond1, &frame_rw);
cv::imshow("Display window", frame);
cv::waitKey(1);
pthread_mutex_unlock(&frame_rw);
ptask_wait_for_period();
task_job++;
}
}
// in the Read function
ptask CapturingImageTask()
{
int task_job = 0;
while (1)
{
std::cout << "The job " << task_job << " of Task T" << ptask_get_index()
<< " is running on core " << sched_getcpu() << " at time : "
<< ptask_gettime(MILLI) << std::endl;
pthread_mutex_lock(&frame_rw);
capture.read(frame);
//after capturing the frame signal the display function & everything should be synchronize as you want
pthread_cond_signal(&cond1);
pthread_mutex_unlock(&frame_rw);
ptask_wait_for_period();
task_job++;
}
}
正如其他人提到的,请尝试使用互斥锁。
您还可以在 cv::Mat 上设置一个条件,然后再尝试显示它:
if (frame.data())
imshow("window", frame);
这将检查要显示的帧是否有数据,从而避免错误。
同样,这种情况只是为了避免 imshow 错误,而不是解决原始问题,正如其他答案中提到的那样,这是两个线程之间的数据竞争。
我有两个任务(线程)每个任务在不同的处理器(核心)上运行,第一个使用 OpenCV 重复捕获图像 videocapture()
。
我只用了这两行来捕获:
cv::Mat frame;
capture.read(frame);
现在我想使用第二个任务显示捕获的图像。在第二个任务的代码中执行 imshow
函数后:
cv::imshow("Display window", frame);
我收到以下输出错误:
OpenCV Error: Assertion failed (size.width>0 && size.height>0) in imshow, file /build/opencv-L2vuMj/opencv-3.2.0+dfsg/modules/highgui/src/window.cpp, line 304
terminate called after throwing an instance of 'cv::Exception'
what(): /build/opencv-L2vuMj/opencv-3.2.0+dfsg/modules/highgui/src/window.cpp:304: error: (-215) size.width>0 && size.height>0 in function imshow
那么,我该如何避免这个错误呢?
完整代码托管在 Github
int main()
{
VideoCapture cap;
while(1){
Mat frame;
cap >> frame;
imshow("frame",frame);
waitKey();}
}
你可以试试这个。 İf 你写 waitKey();代码要按任意键获取框架和显示框架。
cv::VideoCapture::read()
returns bool
表示读取是否成功。
您正在将空 frame
传递给 cv::imshow()
。在尝试显示之前尝试检查读取是否成功。
cv::Mat frame;
if(capture.read(frame))
{
cv::imshow(frame);
}
编辑
OP 向代码发布了 link。在他的程序中 frame
被声明为全局变量。在 120
capture.read(frame)
行中写入帧,在 140
imshow(frame)
行中不使用互斥锁从 frame
中读取 - 这是一场数据竞争。正确的代码应该是这样的:
#include <mutex>
#include <opencv2/opencv.hpp>
std::mutex mutex;
cv::Mat frame;
{
mutex.lock();
capture.read(frame);
mutex.unlock();
}
{
mutex.lock();
cv::imshow(frame);
mutex.unlock();
}
您的代码存在数据竞争问题。假设显示线程首先锁定框架并在读取之前尝试显示它,这样您就可以看到问题所在 如果你想要一个同步的解决方案,你可以使用 pthread 条件并等到图像被读取来通知你的显示功能,否则你将有一个积极的等待!!
// in the declaration part
// Declaration of thread condition variable
pthread_cond_t cond1 = PTHREAD_COND_INITIALIZER;
//in the display function
ptask DisplyingImageTask()
{
int task_job = 0;
while (1)
{
std::cout << "The job " << task_job << " of Task T" << ptask_get_index()
<< " is running on core " << sched_getcpu() << " at time : "
<< ptask_gettime(MILLI) << std::endl;
cv::namedWindow("Display window", cv::WINDOW_AUTOSIZE);
pthread_mutex_lock(&frame_rw);
//wait for the read function to send a signal
pthread_cond_wait(&cond1, &frame_rw);
cv::imshow("Display window", frame);
cv::waitKey(1);
pthread_mutex_unlock(&frame_rw);
ptask_wait_for_period();
task_job++;
}
}
// in the Read function
ptask CapturingImageTask()
{
int task_job = 0;
while (1)
{
std::cout << "The job " << task_job << " of Task T" << ptask_get_index()
<< " is running on core " << sched_getcpu() << " at time : "
<< ptask_gettime(MILLI) << std::endl;
pthread_mutex_lock(&frame_rw);
capture.read(frame);
//after capturing the frame signal the display function & everything should be synchronize as you want
pthread_cond_signal(&cond1);
pthread_mutex_unlock(&frame_rw);
ptask_wait_for_period();
task_job++;
}
}
正如其他人提到的,请尝试使用互斥锁。
您还可以在 cv::Mat 上设置一个条件,然后再尝试显示它:
if (frame.data())
imshow("window", frame);
这将检查要显示的帧是否有数据,从而避免错误。
同样,这种情况只是为了避免 imshow 错误,而不是解决原始问题,正如其他答案中提到的那样,这是两个线程之间的数据竞争。