我必须创建一个程序,该程序使用线程用 OpenCV 精心制作 10 张图像。为此,我认为将工作分解为 3 个线程,并使用 4 个队列来包含初始 10 个图像,以及在细化过程中的中间图像。
这是我必须做的图表:
现在,我认为为此我可以使用 std::queue 来管理队列,因此将队列对象传递给每个线程。问题是:
1)我必须用push、pop方法创建一个类“队列”线程安全,对吧?使用互斥变量来重新定义多线程和同步...
2) Evey 线程在 2 个队列上工作:从一个队列 POP 和 PUSH 到另一个队列。所以每个线程都是消费者/生产者......如何将输入和输出中队列类的两个对象指针传递给每个线程?(有两个对象,所以有两个指针)?
使用我的代码,第二个线程看到输入队列总是空的。有人可以帮助我吗?给我一个关于这个问题的想法?
这是我的代码,不适用于两个线程(第二个线程看到输入队列总是空的:
#include <opencv\cv.h>
#include <opencv\highgui.h>
#include <stdio.h>
#include <windows.h>
#include <process.h>
#include <ctime>
#include <queue>
using namespace std;
using namespace cv;
/* thread safe queue*/
template<typename T>
class coda_concorr
{
private:
std::queue<T> la_coda;
HANDLE mutex;
public:
bool complete;
coda_concorr()
{
mutex = CreateMutex(NULL,FALSE,NULL);
complete = false;
}
void push(T& data)
{
WaitForSingleObject(mutex,INFINITE);
la_coda.push(data);
ReleaseMutex(mutex);
}
bool vuota() const
{
bool RetCode;
WaitForSingleObject(mutex,INFINITE);
RetCode= la_coda.empty();
ReleaseMutex(mutex);
return RetCode;
}
bool try_pop(T& popped)
{
WaitForSingleObject(mutex,INFINITE);
if (la_coda.empty())
{
ReleaseMutex(mutex);
return false;
}
popped = la_coda.front();
la_coda.pop();
ReleaseMutex(mutex);
return true;
}
};
//packet passing to threads
struct Args
{
coda_concorr<cv::Mat> in;
coda_concorr<cv::Mat> out;
};
//grey decrease funct
void grey (void *param){
Mat temp1,temp2;
Args* arg = (Args*)param;
if(!arg->in.vuota()){
while(arg->in.try_pop(temp1)){
cvtColor(temp1,temp2,CV_BGR2GRAY);
arg->out.push(temp2);
}
arg->out.complete=true;
}
else{
Sleep(100);
}
_endthread();
}
//threshold funct
void soglia(void *param){
Mat temp1a,temp2a;
Args* arg = (Args*)param;
if(arg->in.vuota()){
while(arg->in.vuota()){
cout<<endl<<"Coda vuota"<<endl;
Sleep(100);
}
}
else{
while(arg->in.try_pop(temp1a)){
threshold(temp1a,temp2a,128,255,THRESH_BINARY);
arg->out.push(temp2a);
}
}
arg->out.complete=true;
_endthread();
}
int main()
{
coda_concorr<cv::Mat> ingresso;
coda_concorr<cv::Mat> coda1;
coda_concorr<cv::Mat> coda2;
coda_concorr<cv::Mat> uscita;
//in array
Mat inn[10];
Mat out;
//assing images
inn[0]=imread("C:/OPENCV/Test/imgtest/bird1.jpg",1);
inn[1]=imread("C:/OPENCV/Test/imgtest/bird2.jpg",1);
inn[2]=imread("C:/OPENCV/Test/imgtest/bird3.jpg",1);
inn[3]=imread("C:/OPENCV/Test/imgtest/pig1.jpg",1);
inn[4]=imread("C:/OPENCV/Test/imgtest/pig2.jpg",1);
inn[5]=imread("C:/OPENCV/Test/imgtest/pig3.jpg",1);
inn[6]=imread("C:/OPENCV/Test/imgtest/spider1.jpg",1);
inn[7]=imread("C:/OPENCV/Test/imgtest/spider2.jpg",1);
inn[8]=imread("C:/OPENCV/Test/imgtest/spider3.jpg",1);
inn[9]=imread("C:/OPENCV/Test/imgtest/Nutella.jpg",1);
Args dati,dati2;
//populating queue
for(int i=0;i<=9;i++){
dati.in.push(inn[i]);
}
//assing second queue
dati.out=coda1;
HANDLE handle1,handle2;
handle1 = (HANDLE) _beginthread(grey,0,&dati);
//share part that don't WORK
dati2.in=coda1;
dati2.out=coda2;
handle2 = (HANDLE) _beginthread(soglia,0,&dati2);
WaitForSingleObject(handle2,INFINITE);
WaitForSingleObject(handle1,INFINITE);
//output
while (dati2.out.try_pop(out)){
imshow("immagine",out);
waitKey(100);
}
system("PAUSE");
return 0;
}
在此先感谢您的时间。