我正在尝试使用OpenCV(C ++)中的MergeMertens暴露堆栈和多个线程来加速它。它确实可以加快速度,但是每次调用mergeExposuresInThread()之后,内存都会不断增加。
现在它正在执行4个线程,然后从下一个4开始。 它会根据基本字符串合并来自已知文件名的5个不同帧(很好地猜测)。
这是怎么了?我觉得我要释放所有已分配的对象,并且已经在stackoverflow上阅读了有关此内容的大多数文章。
在执行mergeExposuresInThread(...)大约30-40次之后,应用程序被操作系统(Ubuntu 16.04)(牺牲子级)杀死了
我使用top命令监视内存使用情况,并且它会随着时间的推移而上升(如执行mergeExposures(...)的次数更多),并在执行后下降,但总体趋势是上升,然后在顶部显示〜85%的内存使用情况。
int HDRMaker::mergeExposuresInThread(std::vector<std::string> files)
{
const int maxThreads = 4;
int threadsActive = 0;
if (hdrThreads.size() != maxThreads)
{
hdrThreads.resize(files.size());
}
// Init status
hdrThreadsStatus.resize(files.size());
for (int i = 0; i < hdrThreadsStatus.size(); i++)
{
hdrThreadsStatus[i] = 0;
}
if (resultImgs.size() != 24)
{
resultImgs.resize(24);
}
printf("mergeExposuresInThread - start\n");
int nextImg = 0;
bool shallWeRun = true;
while(shallWeRun)
{
if (threadsActive <= maxThreads)
{
const int pos = nextImg;
const std::string fname = std::string(files[pos]);
nextImg++;
threadsActive++;
hdrThreadsStatus[pos] = 1;
hdrThreads[pos]=(new std::thread([this, pos, fname] {
printf("%d %d %s\n", __LINE__, pos, fname.c_str());
Mat fusionResult;
std::string hdrBase = std::string(fname);
ReplaceStringInPlace(hdrBase, "color", "color_exp");
printf("mergeExp:%s\n", hdrBase.c_str());
ReplaceStringInPlace(hdrBase, ".png", "_");
std::vector<cv::Mat> fusionFrames;
for (int i = 0; i < 5; i++)
{
std::string expName = std::string(hdrBase + std::to_string(i) + ".png");
// printf("%s\n", expName.c_str());
cv::Mat exp = imread(hdrBase + std::to_string(i) + ".png");
fusionFrames.push_back(exp);
exp.release();
}
Ptr<MergeMertens> mergeMertens = createMergeMertens();
mergeMertens->process(fusionFrames, fusionResult);
cv::Mat rgbResult;
fusionResult = fusionResult*255;
fusionResult.convertTo(rgbResult, CV_8UC3);
accessVectorMutex.lock();
resultImgs[pos] = rgbResult;
accessVectorMutex.unlock();
imwrite(fname, rgbResult); //debug
printf("Collage ProcessHDRandSaveFile %s end\n", hdrBase.c_str());
for (int i = 0; i < 5; i++)
{
fusionFrames[i].release();
}
fusionResult.release();
rgbResult.release();
mergeMertens.release();
}));
}
if (threadsActive >= maxThreads)
{
for (int t = 0; t < hdrThreads.size(); t++)
{
accessVectorStatus.lock();
if (hdrThreadsStatus[t] == 1)
{
accessVectorStatus.unlock();
if (hdrThreads[t]->joinable())
{
hdrThreads[t]->join();
delete hdrThreads[t];
hdrThreads[t]=nullptr;
accessVectorStatus.lock();
hdrThreadsStatus[t] = 2;
threadsActive--;
accessVectorStatus.unlock();
printf("Thread:%d killed\n", t);
// break;
}
}
else
{
accessVectorStatus.unlock();
}
}
}
bool foundFalse = false;
for (int i = 0; i < hdrThreadsStatus.size(); i++)
{
if (hdrThreadsStatus[i] != 2)
{
foundFalse = true;
break;
}
}
if (foundFalse)
{
shallWeRun = true;
}
else
{
printf("All thread done exit\n");
shallWeRun = false;
break;
}
}
for (int t = 0; t < hdrThreads.size(); t++)
{
accessVectorStatus.lock();
if (hdrThreadsStatus[t] == 1)
{
accessVectorStatus.unlock();
if (hdrThreads[t]->joinable())
{
hdrThreads[t]->join();
delete hdrThreads[t];
hdrThreads[t]=nullptr;
accessVectorStatus.lock();
hdrThreadsStatus[t] = 2;
threadsActive--;
accessVectorStatus.unlock();
printf("Thread:%d killed\n", t);
break;
}
}
else
{
accessVectorStatus.unlock();
}
}
printf("mergeExposuresInThread - end\n");
return 1;
}
void ReplaceStringInPlace(std::string& subject, const std::string& search,
const std::string& replace)
{
size_t pos = 0;
while ((pos = subject.find(search, pos)) != std::string::npos) {
subject.replace(pos, search.length(), replace);
pos += replace.length();
}
}
标题
int mergeExposuresInThread(std::vector<std::string> files);
std::mutex accessVectorMutex;
std::mutex accessVectorStatus;
std::vector<std::thread*> hdrThreads;
std::vector<int> hdrThreadsStatus;
std::vector<cv::Mat> resultImgs;
通话代码
mergeExposuresInThread(filesAsStrings); // A list of 24 files
// Do other things (this does not leak without mergeExposuresInThread(...)
for (int i = 0; i < resultImgs.size(); i++)
{
resultImgs[i].release();
}