2016-02-26 32 views
1

虽然我使用KMEANS_RANDOM_CENTERS标志(随机性正在工作),但在boost :: threadGroup(对于多线程)中使用opencv kmeans时,我仍然保持相同的结果当不使用boost :: thread组时)。没有在使用boost :: threadGroup时在opencv kmeans中随机初始化

这是我打电话给我的k均值在一个boost ::线程组:

boost::thread_group threadGroup 
for(int i=0; i < numDescs; i++) 
{ 
    threadGroup.create_thread(boost::bind(&applyKmeansRand, matDescs[i], matCenters[i], numClusters)); 
} 
threadGroup.join_all(); 

这是我打电话的功能:

void applyKmeansRand(Mat& matDesc,Mat& matCenters,int numClusters) 
{ 
    Mat bestlabels; 

    TermCriteria criteria; 
    kmeans(matDesc, numClusters, bestlabels, criteria, 1, KMEANS_RANDOM_CENTERS, matCenters); 
} 

有没有一种可能性,即随机数发生器kmeans函数内部工作不正常?

+0

它会在每次运行后或每次编译后生成相同的数字吗?前者是一个播种问题,后者是一个......更大的问题。 – erip

+0

即使在重新编译之后......我甚至将最大迭代次数设置为1,但仍然在每次运行和编译之后都继续获得相同的输出。我正在'threadGroup.create_thread'块中运行kmeans进行平行化,也许这会以某种方式终止随机初始化? 也许一些明确的随机播种也可以帮助... – mcExchange

+0

似乎确实是一个问题与boost :: threadGroup我会适应我的问题,并进一步寻找答案。在最坏的情况下,我将不得不平行我的代码,然后使用boost :: threadGroup – mcExchange

回答

-1

你说你打电话applyKmeansRand,但你的代码说你打电话applyKmeansNTrajpRand;这有什么问题吗?

可能不是,但如果NTrajp版本具有与所示相同的签名,那么问题可能是您绑定它的方式。默认情况下,bind通过值捕获参数,因此Mat对象您的函数接收引用副本您给bind的那些副本。因此,您将计算结果存储在基本上是临时对象的位置,而不是存储在阵列中已有的对象中。

使用boost::ref绑定到引用,而不是拷贝:

boost::bind(&applyKmeansNTrajpRand, boost::ref(matDescs[i]), boost::ref(matCenters[i]), numClusters) 
+0

是的不同的名字是一个错字。我在我的问题中修正了这一点。感谢您指出。 关于通过boost引用包装器传递。错误:错误:在传递'const boost :: reference_wrapper boost :: ref(T&)[with T = cv :: Mat]'参数1' template inline reference_wrapper BOOST_REF_CONST ref(T&t)' 也许这是因为boost :: ref无法处理cv :: Mat对象?我是否也需要修改'applyKmeansRand'函数? – mcExchange

+0

“所以您的函数收到的Mat对象是引用副本” - cv :: Mat本质上是一个智能指针 – berak

+0

嗯好吧,那么如果我使用'boost :: ref()''cv :: Mat是一个智能指针? – mcExchange

0

即使我不能解析使用boost::threadGroup这神秘似乎总是使用相同的种子用于集成在cv::kmeans随机数发生器的问题。我最后做了使用kmeans的并行处理:openmp

// Include openmp header 
#include <omp.h> 
[...] 

// Some kmeans options/variables 
int numIter = 100; 
int numRepetitions= 10; 
Mat bestlabels; 
[...] 

// Execute kmeans in parallel 
#pragma omp parallel for 
for(int i=0; i < numDescs; i++) 
{ 
     TermCriteria criteria = TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, numIter, FLT_EPSILON); 
     kmeans(matDescs[i], numClusters, bestlabels, criteria, numRepetitions, KMEANS_RANDOM_CENTERS, matCenters[i]); 
}