我已经实现了一个包含单个生产者和消费者的简单程序。在这个程序中,生产者线程从Camera的Live流中抓取帧并将其保存在队列和文件夹中,而在主线程(消费者)中我得到这个帧并保存它,以便看到Frame得到了消费者与生产者推动的消费者相同。但结果并不相同。任何人都可以帮我识别我的错误吗?
#include "stdafx.h"
#include <cv.h>
#include <highgui.h>
#include <string>
#include <iostream>
#include <queue>
#include <deque>
#include <time.h>
#include "Producer.h"
#include "boost\thread.hpp"
using namespace cv;
using namespace std;
queue<Producer> Producers;
boost::mutex sharedMutex;
void threadFunction()
{
Producer p;
string name="Havard";
VideoCapture capture("rtsp://192.168.10.20:1125/Master-0?profile=Master-0");
stringstream filenamep;
SYSTEMTIME st;
Mat Image;
Mat Image2;
for(int i=0;i<200;i++)
{
sharedMutex.lock();
capture >> Image;
Image.copyTo(Image2);
p.setVariables(i,name,Image2);
Producers.push(p);
filenamep << "D:/MultiThreading/MakingThreadSafeQueue/Images/" << p.count << "p.jpg";
imwrite(filenamep.str(),Image2);
sharedMutex.unlock();
filenamep.str("");
Image.release();
Image2.release();
}
}
int _tmain(int argc, _TCHAR* argv[])
{
Mat ImgC;
Producer p2;
boost::thread producerThread(&threadFunction);
stringstream filename;
while(1)
{
Sleep(500);
while(!Producers.empty())
{
sharedMutex.lock();
p2=Producers.front();
p2.img.copyTo(ImgC);
imshow("Frame",p2.img);
filename << "D:/MultiThreading/MakingThreadSafeQueue/Images/" << p2.count << ".jpg";
imwrite(filename.str(),ImgC);
Producers.pop();
sharedMutex.unlock();
ImgC.release();
p2.img.release();
filename.str("");
}
char c=cvWaitKey(1);
if(c==27) break;
}
return 0;
}
答案 0 :(得分:1)
你可能遇到了opencv巧妙地避免复制数据的问题。如果不需要,copyTo不会分配新数据,这意味着您的生产者可能共享相同的内存块。我发现您尝试使用release来避免这种情况,但请尝试使用clone来获取深层副本!这也将消除显式调用release的需要。
capture >> Image;
p.setVariables(i,name,Image.clone());
作为旁注,您正在访问队列,而不是将其锁定在内部循环的标头中的消费者线程中。更简洁的方法是将锁定和解锁移动到内环之外。
答案 1 :(得分:0)
您是否可以检查在名为Producers的队列中复制的Producer对象中的字段'img'的内容是否被正确复制。
Mat diff, Image2gray, tempGray;
cvtColor(Image2, Image2gray, CV_BGR2GRAY);
cvtColor(Producers.back().img, tempGray, CV_BGR2GRAY);
compare(Image2gray, tempGray, diff, CMP_EQ);
if (countNonZero(diff) == Image2.total())
{
cout << "ok" << endl;
}
如果没问题,请尝试没有Producer类但直接使用Mat的生产者 - 消费者。 希望这个建议可以帮助你。