From dc328451eb7ba2fea4186832e15813ca38429c69 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Tue, 28 Feb 2017 18:50:56 +0300 Subject: [PATCH] flann: use OpenCV theRNG() std::rand() has no thread-safe guarantee. backport commit: 147f3ebf0add6e281b5fc0a4d0c2826502ce88cd --- .../include/opencv2/flann/kdtree_index.h | 5 ++++ .../flann/include/opencv2/flann/lsh_index.h | 5 ++++ modules/flann/include/opencv2/flann/random.h | 28 +++++++++++++++++-- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/modules/flann/include/opencv2/flann/kdtree_index.h b/modules/flann/include/opencv2/flann/kdtree_index.h index 1b8af4a597..1300b74a69 100644 --- a/modules/flann/include/opencv2/flann/kdtree_index.h +++ b/modules/flann/include/opencv2/flann/kdtree_index.h @@ -132,7 +132,12 @@ public: /* Construct the randomized trees. */ for (int i = 0; i < trees_; i++) { /* Randomize the order of vectors to allow for unbiased sampling. */ +#ifndef OPENCV_FLANN_USE_STD_RAND + cv::randShuffle(vind_); +#else std::random_shuffle(vind_.begin(), vind_.end()); +#endif + tree_roots_[i] = divideTree(&vind_[0], int(size_) ); } } diff --git a/modules/flann/include/opencv2/flann/lsh_index.h b/modules/flann/include/opencv2/flann/lsh_index.h index 2b89337d91..17a49dd788 100644 --- a/modules/flann/include/opencv2/flann/lsh_index.h +++ b/modules/flann/include/opencv2/flann/lsh_index.h @@ -136,7 +136,12 @@ public: indices.resize( feature_size_ * CHAR_BIT ); for (size_t j = 0; j < feature_size_ * CHAR_BIT; ++j) indices[j] = j; + +#ifndef OPENCV_FLANN_USE_STD_RAND + cv::randShuffle(indices); +#else std::random_shuffle(indices.begin(), indices.end()); +#endif } lsh::LshTable& table = tables_[i]; diff --git a/modules/flann/include/opencv2/flann/random.h b/modules/flann/include/opencv2/flann/random.h index a3cf5ec53d..d6784747c0 100644 --- a/modules/flann/include/opencv2/flann/random.h +++ b/modules/flann/include/opencv2/flann/random.h @@ -40,13 +40,31 @@ namespace cvflann { +inline int rand() +{ +#ifndef OPENCV_FLANN_USE_STD_RAND +# if INT_MAX == RAND_MAX + int v = cv::theRNG().next() & INT_MAX; +# else + int v = cv::theRNG().uniform(0, RAND_MAX + 1); +# endif +#else + int v = std::rand(); +#endif // OPENCV_FLANN_USE_STD_RAND + return v; +} + /** * Seeds the random number generator * @param seed Random seed */ inline void seed_random(unsigned int seed) { - srand(seed); +#ifndef OPENCV_FLANN_USE_STD_RAND + cv::theRNG() = cv::RNG(seed); +#else + std::srand(seed); +#endif } /* @@ -60,7 +78,7 @@ inline void seed_random(unsigned int seed) */ inline double rand_double(double high = 1.0, double low = 0) { - return low + ((high-low) * (std::rand() / (RAND_MAX + 1.0))); + return low + ((high-low) * (rand() / (RAND_MAX + 1.0))); } /** @@ -71,7 +89,7 @@ inline double rand_double(double high = 1.0, double low = 0) */ inline int rand_int(int high = RAND_MAX, int low = 0) { - return low + (int) ( double(high-low) * (std::rand() / (RAND_MAX + 1.0))); + return low + (int) ( double(high-low) * (rand() / (RAND_MAX + 1.0))); } /** @@ -107,7 +125,11 @@ public: for (int i = 0; i < size_; ++i) vals_[i] = i; // shuffle the elements in the array +#ifndef OPENCV_FLANN_USE_STD_RAND + cv::randShuffle(vals_); +#else std::random_shuffle(vals_.begin(), vals_.end()); +#endif counter_ = 0; }