这次我遇到了以下问题。我想通过将每个作为单独的线程启动来加速皮肤/背景分割。
这两个程序,不写入相同的变量,不读取相同的变量。唯一重要的是同步主程序线程,等待两个程序(皮肤和背景)完成工作,然后开始处理结果。
我做的是:
在我的主要课程标题中:
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)
函数。 / p>
我是初学者,当涉及到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);
}
我做错了什么?
答案 0 :(得分:1)
尝试使用createthread或beginthreadex而不是beginthread。看这里:
或在这里:
Windows threading: _beginthread vs _beginthreadex vs CreateThread C++
我在您的代码中看到的另一件事。您将cvInitMatHeader与非空对象一起使用。这样找我错了。它看起来像是你的记忆管理
void SKINSEG::process(cv::Mat src, cv::Mat *dst, double lambda, unsigned int vThreshold)
功能错误。看看你的任务经理,你会发现你的程序调用只会填满你所有的记忆。