2016-02-26 58 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]); 
}