Commit ffc4297278315d35c6725b057c9696c9f0be5898

Authored by Josh Klontz
1 parent 54f4d558

Windows parallel RNG workaround

openbr/plugins/imgproc/rndsubspace.cpp
@@ -30,7 +30,7 @@ namespace br @@ -30,7 +30,7 @@ namespace br
30 * \brief Generates a random subspace. 30 * \brief Generates a random subspace.
31 * \author Josh Klontz \cite jklontz 31 * \author Josh Klontz \cite jklontz
32 */ 32 */
33 -class RndSubspaceTransform : public Transform 33 +class RndSubspaceTransform : public MetaTransform
34 { 34 {
35 Q_OBJECT 35 Q_OBJECT
36 Q_PROPERTY(float fraction READ get_fraction WRITE set_fraction RESET reset_fraction STORED false) 36 Q_PROPERTY(float fraction READ get_fraction WRITE set_fraction RESET reset_fraction STORED false)
@@ -38,54 +38,66 @@ class RndSubspaceTransform : public Transform @@ -38,54 +38,66 @@ class RndSubspaceTransform : public Transform
38 BR_PROPERTY(float, fraction, 0.5) 38 BR_PROPERTY(float, fraction, 0.5)
39 BR_PROPERTY(bool, weighted, false) 39 BR_PROPERTY(bool, weighted, false)
40 40
41 - Mat map; 41 + QList<Mat> maps;
42 42
43 void train(const TemplateList &data) 43 void train(const TemplateList &data)
44 { 44 {
45 - int cols = data.first().m().cols;  
46 - int size = data.first().m().rows * cols;  
47 - QList<float> weights; weights.reserve(size);  
48 - if (weighted) {  
49 - Mat flatData = OpenCVUtils::toMat(data.data());  
50 - for (int i=0; i<size; i++) {  
51 - Scalar mean, stddev;  
52 - cv::meanStdDev(flatData.col(i), mean, stddev);  
53 - weights.append(pow(stddev[0],2.0)); 45 + // While RndSubspace transform could be independent, making it a MetaTransform is a workaround
  46 + // for parallel random number generation being difficult on Windows due to thread-local
  47 + // RNG states all initialized with the same seed and thus producing the same sequence of random numbers.
  48 + for (int index=0; index<data.first().size(); index++) {
  49 + const int cols = data.first()[index].cols;
  50 + const int size = data.first()[index].rows * cols;
  51 + QList<float> weights; weights.reserve(size);
  52 + if (weighted) {
  53 + Mat flatData = OpenCVUtils::toMat(data.data());
  54 + for (int i=0; i<size; i++) {
  55 + Scalar mean, stddev;
  56 + cv::meanStdDev(flatData.col(i), mean, stddev);
  57 + weights.append(pow(stddev[0],2.0));
  58 + }
  59 + } else {
  60 + for (int i=0; i<size; i++)
  61 + weights.append(1);
54 } 62 }
55 - } else {  
56 - for (int i=0; i<size; i++)  
57 - weights.append(1);  
58 - }  
59 - const int dimsOut = std::max(int(weights.size()*fraction), 1); 63 + const int dimsOut = std::max(int(weights.size()*fraction), 1);
60 64
61 - QList<int> sample = Common::RandSample(dimsOut, weights);  
62 - Mat xMap(1, dimsOut, CV_16SC1);  
63 - Mat yMap(1, dimsOut, CV_16SC1);  
64 - for (int j=0; j<dimsOut; j++) {  
65 - int index = sample[j];  
66 - xMap.at<short>(0,j) = index % cols;  
67 - yMap.at<short>(0,j) = index / cols;  
68 - }  
69 - std::vector<Mat> mv;  
70 - mv.push_back(xMap);  
71 - mv.push_back(yMap); 65 + QList<int> sample = Common::RandSample(dimsOut, weights);
  66 + Mat xMap(1, dimsOut, CV_16SC1);
  67 + Mat yMap(1, dimsOut, CV_16SC1);
  68 + for (int j=0; j<dimsOut; j++) {
  69 + int index = sample[j];
  70 + xMap.at<short>(0,j) = index % cols;
  71 + yMap.at<short>(0,j) = index / cols;
  72 + }
  73 + std::vector<Mat> mv;
  74 + mv.push_back(xMap);
  75 + mv.push_back(yMap);
72 76
73 - merge(mv, map); 77 + Mat map;
  78 + merge(mv, map);
  79 + maps.append(map);
  80 + }
74 } 81 }
75 82
76 void project(const Template &src, Template &dst) const 83 void project(const Template &src, Template &dst) const
77 { 84 {
78 - remap(src, dst, map, Mat(), INTER_NEAREST); 85 + dst.file = src.file;
  86 + for (int i=0; i<src.size(); i++) {
  87 + Mat m;
  88 + remap(src, m, maps[i], Mat(), INTER_NEAREST);
  89 + dst.append(m);
  90 + }
79 } 91 }
80 92
81 void store(QDataStream &stream) const 93 void store(QDataStream &stream) const
82 { 94 {
83 - stream << fraction << weighted << map; 95 + stream << maps;
84 } 96 }
85 97
86 void load(QDataStream &stream) 98 void load(QDataStream &stream)
87 { 99 {
88 - stream >> fraction >> weighted >> map; 100 + stream >> maps;
89 } 101 }
90 }; 102 };
91 103