【发布时间】:2013-12-11 11:25:34
【问题描述】:
这次我遇到了以下问题。我想通过将每个线程作为单独的线程启动来加速皮肤/背景分割。
这两个程序,不要写入同一个变量,不要从同一个变量中读取。唯一重要的是同步主程序线程以等待两个程序(皮肤和后台)完成它们的工作,然后开始处理结果。
我所做的是:
在我的主类标题中:
HANDLE fgbg_codebookThread;
HANDLE skinsegThread;
然后在我的主循环函数中:
fgbg_codebookThread =( HANDLE ) _beginthread( fgbg_codebookThreadProc, 0, (void *)this );
skinsegThread =( HANDLE ) _beginthread( skinsegThreadProc, 0, (void *)this );
std::vector < HANDLE > threads;
threads.push_back(fgbg_codebookThread);
threads.push_back(skinsegThread);
if( threads.size() > 0 )
WaitForMultipleObjects( threads.size(), & threads[ 0 ], TRUE, INFINITE );
cv::bitwise_and(fgbg_codebookResult,skinsegResult,mask);
我的过程函数如下所示:
static void __cdecl fgbg_codebookThreadProc( void * Args )
{
mainApp* app = static_cast<mainApp*>(Args);
app->fgbg_codebookProc();
_endthread();
};
static void __cdecl skinsegThreadProc( void * Args )
{
mainApp* app = static_cast<mainApp*>(Args);
app->skinsegProc();
_endthread();
};
只要两个程序不以任何方式共享变量,我认为它应该可以正常工作。
但是:在大多数情况下,以下代码会将我引向断点(在随机运行一段时间后),它指向 malloc.c __forceinline void * __cdecl _heap_alloc (size_t size) 函数或 free.c void __cdecl _free_base (void * pBlock) 函数。
我是 C++ 线程的初学者,我以前从未使用过,所以我不知道发生了什么。
这是我的线程程序的主体(可以肯定):
void fgbg_codebookProc()
{
fgbg_codebook.process(fgbg_codebookFrame, &fgbg_codebookResult,frameNumber);
}
void skinsegProc()
{ skinseg.process(skinsegFrame,&skinsegResult,skinseg.lambda,skinseg.vThreshold);
}
void FGBG_CODEBOOK::process(cv::Mat input,cv::Mat *output, int nframes)
{
IplImage* rawImage=cvCloneImage(&(IplImage)input);
yuvImage = cvCloneImage(rawImage);
ImaskCodeBook = cvCreateImage( cvGetSize(rawImage), IPL_DEPTH_8U, 1 );
cvSet(ImaskCodeBook,cvScalar(255));
cvCvtColor(yuvImage, yuvImage, CV_RGB2YCrCb );//YUV For codebook method
model->modMin[0] = YUVmin[0];
model->modMin[1] = YUVmin[1];
model->modMin[2] = YUVmin[2];
model->modMax[0] = YUVmax[0];
model->modMax[1] = YUVmax[0];
model->modMax[2] = YUVmax[0];
//Basic learning of backgroundraw->width/2-100/2, raw->height/1.5-100/2),cvPoint(raw->width/2+100,raw->height/1.5+100)
if( nframes-1 < nframesToLearnBG )
cvBGCodeBookUpdate( model, yuvImage);
//Clean when learned
if( nframes-1 == nframesToLearnBG )
{
cvBGCodeBookClearStale( model, model->t/2 );
calibration = false;
}
//Start finding foreground after learning
if( nframes-1 >= nframesToLearnBG )
{
// Find foreground by codebook method
cvBGCodeBookDiff( model, yuvImage, ImaskCodeBook );
// Update periodically
/*if ((nframes-1) % 150 == 0)
{
cvBGCodeBookUpdate(model,yuvImage);
//std::cout <<"update\n";
}
if ((nframes-1) % 300 == 0)
{
cvBGCodeBookClearStale(model,model->t/2);
//std::cout <<"clear\n";
}*/
}
cv::Mat(ImaskCodeBook).copyTo(*output);
cvReleaseImage(&rawImage);
cvReleaseImage(&yuvImage);
cvReleaseImage(&ImaskCodeBook);
}
void SKINSEG::process(cv::Mat src, cv::Mat *dst, double lambda, unsigned int vThreshold)
{
skinsegResult = cv::Mat(480,640, CV_8UC1, cvScalar(0.));
cv::cvtColor(src,frameHSV,CV_RGB2HSV);
CvMat* Cs;
CvMat* CsInv;
CvMat* ms;
Cs = cvCreateMat(2, 2, CV_32FC1);
cvInitMatHeader(Cs, 2, 2, CV_32FC1, covMatrix);
CsInv = cvCreateMat(2, 2, CV_32FC1);
cvInvert(Cs, CsInv);
ms = cvCreateMat(1, 2, CV_32FC1);
cvInitMatHeader(ms, 1, 2, CV_32FC1, valAvg);
CvMat* X = cvCreateMat(1, 2, CV_32FC1);
CvMat* Xms = cvCreateMat(1, 2, CV_32FC1);
CvMat* XmsT = cvCreateMat(2, 1, CV_32FC1);
CvMat* XmsCsInv = cvCreateMat(1, 2, CV_32FC1);
CvMat* XmsCsInvXmsT = cvCreateMat(1, 1, CV_32FC1);
uchar* data = (uchar *)frameHSV.data;
uchar* dataMask = (uchar *)skinsegResult.data;
double temp[2];
for (int j = 0; j < frameHSV.cols; j++)
for (int i = 0; i < frameHSV.rows; i++)
{
cvmSet( Xms,0,0,(double)data[i*frameHSV.step+j*frameHSV.channels()+0]- cvmGet(ms,0,0) );
cvmSet( Xms,0,1,(double)data[i*frameHSV.step+j*frameHSV.channels()+1] - cvmGet(ms,0,1) );
temp[0] = cvmGet(Xms,0,0);
temp[1] = cvmGet(Xms,0,1);
cvmSet(XmsT,0,0,cvmGet(Xms,0,0));
cvmSet(XmsT,1,0,cvmGet(Xms,0,1));
cvmSet(XmsCsInv,0,0,(cvmGet(Xms,0,0) * cvmGet(CsInv,0,0)) + (cvmGet(Xms,0,1) * cvmGet(CsInv,1,0)));
cvmSet(XmsCsInv,0,1,(cvmGet(Xms,0,0) * cvmGet(CsInv,0,1)) + (cvmGet(Xms,0,1) * cvmGet(CsInv,1,1)));
cvmSet(XmsCsInvXmsT,0,0,(cvmGet(XmsCsInv,0,0) * cvmGet(XmsT,0,0)) + (cvmGet(XmsCsInv,0,1) * cvmGet(XmsT,1,0)));
double lam = cvmGet(XmsCsInvXmsT, 0, 0);
dataMask[i*skinsegResult.step+j*skinsegResult.channels()] = (((double)data[i*frameHSV.step+j*frameHSV.channels()] >= vThreshold) && (lam < lambda)) ? 255 : 0;
}
skinsegResult.copyTo(*dst);
// zwalniamy macierze
cvReleaseMat(&XmsCsInvXmsT);
cvReleaseMat(&XmsCsInv);
cvReleaseMat(&XmsT);
cvReleaseMat(&Xms);
cvReleaseMat(&X);
cvReleaseMat(&ms);
cvReleaseMat(&CsInv);
cvReleaseMat(&Cs);
}
我做错了什么?
【问题讨论】:
-
你链接多线程库了吗?
-
嗯..不。我认为
中的函数足以满足我的需求。有什么建议吗? (越简单越好)。 -
删除 Cs = cvCreateMat(2, 2, CV_32FC1);ms = cvCreateMat(1, 2, CV_32FC1);cvReleaseMat(&ms);cvReleaseMat(&Cs);
标签: c++ c multithreading opencv