Darwin  1.10(beta)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
drwnNNGraphThreadedMoves.h
1 /*****************************************************************************
2 ** DARWIN: A FRAMEWORK FOR MACHINE LEARNING RESEARCH AND DEVELOPMENT
3 ** Distributed under the terms of the BSD license (see the LICENSE file)
4 ** Copyright (c) 2007-2015, Stephen Gould
5 ** All rights reserved.
6 **
7 ******************************************************************************
8 ** FILENAME: drwnNNGraphThreadedMoves.h
9 ** AUTHOR(S): Stephen Gould <stephen.gould@anu.edu.au>
10 **
11 *****************************************************************************/
12 
14 
15 #pragma once
16 
17 #include "drwnNNGraph.h"
18 #include "drwnNNGraphMoves.h"
19 
20 using namespace std;
21 using namespace Eigen;
22 
23 // drwnNNGraphThreadedMoves --------------------------------------------------
25 
26 namespace drwnNNGraphThreadedMoves {
29  template<class DistanceMetric>
30  void initialize(drwnNNGraph& graph, const DistanceMetric& M);
31 
34  inline void initialize(drwnNNGraph& graph) { initialize(graph, drwnNNGraphDefaultMetric()); }
35 
38  template<class DistanceMetric>
39  double rescore(drwnNNGraph& graph, const DistanceMetric& M);
40 
43  inline double rescore(drwnNNGraph& graph) { return rescore(graph, drwnNNGraphDefaultMetric()); }
44 
47  template<class DistanceMetric>
48  void update(drwnNNGraph& graph, const DistanceMetric& M);
49 
52  inline void update(drwnNNGraph& graph) { update(graph, drwnNNGraphDefaultMetric()); }
53 
56  template<class DistanceMetric>
57  void updateImage(drwnNNGraph& graph, unsigned imgIndx, const DistanceMetric& M);
58 
62  template<class DistanceMetric>
63  bool randproj(drwnNNGraph& graph, const DistanceMetric& M);
64 
67  template<class DistanceMetric>
68  bool enrichment(drwnNNGraph& graph, const DistanceMetric& M);
69 
71  template<class DistanceMetric>
73  protected:
74  const DistanceMetric& _M;
75  set<unsigned> _imgIndxes;
77 
78  public:
79  drwnNNGraphThreadedInitializeJob(const set<unsigned>& imgIndxes, drwnNNGraph& g,
80  const DistanceMetric& M) : _M(M), _imgIndxes(imgIndxes), _graph(g) { /* do nothing */ }
81  ~drwnNNGraphThreadedInitializeJob() { /* do nothing */ }
82 
83  void operator()() {
84  for (set<unsigned>::const_iterator it = _imgIndxes.begin(); it != _imgIndxes.end(); ++it) {
85  drwnNNGraphMoves::initialize(_graph, *it, _M);
86  }
87  }
88  };
89 
91  template<class DistanceMetric>
93  protected:
94  const DistanceMetric& _M;
95  set<unsigned> _imgIndxes;
97 
98  public:
99  drwnNNGraphThreadedRescoreJob(const set<unsigned>& imgIndxes, drwnNNGraph& g,
100  const DistanceMetric& M) : _M(M), _imgIndxes(imgIndxes), _graph(g) { /* do nothing */ }
101  ~drwnNNGraphThreadedRescoreJob() { /* do nothing */ }
102 
103  void operator()() {
104  for (set<unsigned>::const_iterator it = _imgIndxes.begin(); it != _imgIndxes.end(); ++it) {
105  drwnNNGraphMoves::rescore(_graph, *it, _M);
106  }
107  }
108  };
109 
111  template<class DistanceMetric>
113  protected:
114  const DistanceMetric& _M;
115  set<unsigned> _imgIndxes;
117 
118  public:
119  drwnNNGraphThreadedUpdateJob(const set<unsigned>& imgIndxes, drwnNNGraph& g,
120  const DistanceMetric& M) : _M(M), _imgIndxes(imgIndxes), _graph(g) { /* do nothing */ }
121  ~drwnNNGraphThreadedUpdateJob() { /* do nothing */ }
122 
123  void operator()() {
124  for (set<unsigned>::const_iterator it = _imgIndxes.begin(); it != _imgIndxes.end(); ++it) {
125  drwnNNGraphThreadedMoves::updateImage(_graph, *it, _M);
126  }
127  }
128  };
129 
131  template<class DistanceMetric>
133  protected:
134  const DistanceMetric& _M;
135  set<drwnNNGraphNodeIndex> _nodeIndxes;
137 
138  public:
139  drwnNNGraphThreadedExhaustiveJob(const set<drwnNNGraphNodeIndex>& nodeIndxes, drwnNNGraph& g,
140  const DistanceMetric& M) : _M(M), _nodeIndxes(nodeIndxes), _graph(g) { /* do nothing */ }
141  ~drwnNNGraphThreadedExhaustiveJob() { /* do nothing */ }
142 
143  void operator()() {
144  for (set<drwnNNGraphNodeIndex>::const_iterator it = _nodeIndxes.begin(); it != _nodeIndxes.end(); ++it) {
145  drwnNNGraphMoves::exhaustive(_graph, *it, _M);
146  }
147  }
148  };
149 };
150 
151 // drwnNNGraphThreadedMoves implementation -----------------------------------
152 
153 template<class DistanceMetric>
154 void drwnNNGraphThreadedMoves::initialize(drwnNNGraph& graph, const DistanceMetric& M)
155 {
156  // prepare thread data
157  const unsigned nJobs = std::min((unsigned)graph.numImages(),
158  std::max((unsigned)1, drwnThreadPool::MAX_THREADS));
159  vector<set<unsigned> > imgIndxes(nJobs);
160  for (unsigned imgIndx = 0; imgIndx < graph.numImages(); imgIndx++) {
161  if (!graph[imgIndx].bSourceMatchable) {
162  DRWN_LOG_DEBUG("...skipping initialization of " << graph[imgIndx].name());
163  continue;
164  }
165 
166  imgIndxes[imgIndx % nJobs].insert(imgIndx);
167  }
168 
169  // start threads
170  drwnThreadPool threadPool(nJobs);
171  threadPool.start();
172  vector<drwnNNGraphThreadedInitializeJob<DistanceMetric> *> jobs(nJobs);
173  for (unsigned i = 0; i < nJobs; i++) {
174  jobs[i] = new drwnNNGraphThreadedInitializeJob<DistanceMetric>(imgIndxes[i], graph, M);
175  threadPool.addJob(jobs[i]);
176  }
177  threadPool.finish();
178 
179  for (unsigned i = 0; i < jobs.size(); i++) {
180  delete jobs[i];
181  }
182  jobs.clear();
183 }
184 
185 template<class DistanceMetric>
186 double drwnNNGraphThreadedMoves::rescore(drwnNNGraph& graph, const DistanceMetric& M)
187 {
188  DRWN_FCN_TIC;
189 
190  // prepare thread data
191  const unsigned nJobs = std::min((unsigned)graph.numImages(),
192  std::max((unsigned)1, drwnThreadPool::MAX_THREADS));
193  vector<set<unsigned> > imgIndxes(nJobs);
194  for (unsigned imgIndx = 0; imgIndx < graph.numImages(); imgIndx++) {
195  imgIndxes[imgIndx % nJobs].insert(imgIndx);
196  }
197 
198  // start threads
199  drwnThreadPool threadPool(nJobs);
200  threadPool.start();
201  vector<drwnNNGraphThreadedRescoreJob<DistanceMetric> *> jobs(nJobs);
202  for (unsigned i = 0; i < nJobs; i++) {
203  jobs[i] = new drwnNNGraphThreadedRescoreJob<DistanceMetric>(imgIndxes[i], graph, M);
204  threadPool.addJob(jobs[i]);
205  }
206  threadPool.finish();
207 
208  for (unsigned i = 0; i < jobs.size(); i++) {
209  delete jobs[i];
210  }
211  jobs.clear();
212 
213  DRWN_FCN_TOC;
214  return graph.energy().first;
215 }
216 
217 template<class DistanceMetric>
218 void drwnNNGraphThreadedMoves::update(drwnNNGraph& graph, const DistanceMetric& M)
219 {
220  DRWN_FCN_TIC;
221 
222  // try improve a bad match (from a random (active) image)
223  if (drwnNNGraph::DO_EXHAUSTIVE > 0) {
224  // sum scores of nodes from active images
225  double totalWeight = 0.0;
226  for (unsigned imgIndx = 0; imgIndx < graph.numImages(); imgIndx++) {
227  if (!graph[imgIndx].bSourceMatchable) continue;
228  for (unsigned segId = 0; segId < graph[imgIndx].numNodes(); segId++) {
229  const drwnNNGraphEdgeList& e = graph[imgIndx][segId].edges;
230  if (e.empty()) continue;
231 
232  totalWeight += (double)e.front().weight;
233  }
234  }
235 
236  // randomly sample n nodes
237  set<drwnNNGraphNodeIndex> sampledNodes;
238  for (int i = 0; i < drwnNNGraph::DO_EXHAUSTIVE; i++) {
239 
240  // sample the weight
241  double weight = totalWeight * drand48();
242 
243  // find the node
244  for (unsigned imgIndx = 0; imgIndx < graph.numImages(); imgIndx++) {
245  if (!graph[imgIndx].bSourceMatchable) continue;
246  for (unsigned segId = 0; segId < graph[imgIndx].numNodes(); segId++) {
247  const drwnNNGraphEdgeList& e = graph[imgIndx][segId].edges;
248  if (e.empty()) continue;
249 
250  // skip if already sampled this node
251  if (sampledNodes.find(drwnNNGraphNodeIndex(imgIndx, segId)) != sampledNodes.end())
252  continue;
253 
254  weight -= (double)e.front().weight;
255  if (weight <= 0.0) {
256  // add node to set of samples and remove from totalWeight
257  sampledNodes.insert(drwnNNGraphNodeIndex(imgIndx, segId));
258  totalWeight -= (double)e.front().weight;
259  break;
260  }
261  }
262  if (weight <= 0.0) break;
263  }
264  }
265 
266  // start threads for exhuastive search on nodes
267  if (sampledNodes.size() == 1) {
268  drwnNNGraphMoves::exhaustive(graph, *sampledNodes.begin(), M);
269  } else {
270  drwnThreadPool threadPool;
271  threadPool.start();
272  vector<drwnNNGraphThreadedExhaustiveJob<DistanceMetric> *> jobs;
273  for (set<drwnNNGraphNodeIndex>::const_iterator it = sampledNodes.begin(); it != sampledNodes.end(); ++it) {
274  set<drwnNNGraphNodeIndex> nodeIndexes;
275  nodeIndexes.insert(*it);
276  jobs.push_back(new drwnNNGraphThreadedExhaustiveJob<DistanceMetric>(nodeIndexes, graph, M));
277  threadPool.addJob(jobs.back());
278  }
279  threadPool.finish();
280 
281  for (unsigned i = 0; i < jobs.size(); i++) {
282  delete jobs[i];
283  }
284  jobs.clear();
285  }
286  }
287 
288  // random projection
289  if (drwnNNGraph::DO_RANDPROJ > 0) {
290  randproj(graph, M);
291  }
292 
293  // propagation moves
295  // prepare thread data
296  const unsigned nJobs = std::min((unsigned)graph.numImages(),
297  std::max((unsigned)1, drwnThreadPool::MAX_THREADS));
298  vector<set<unsigned> > imgIndxes(nJobs);
299  for (unsigned imgIndx = 0; imgIndx < graph.numImages(); imgIndx++) {
300  if (!graph[imgIndx].bSourceMatchable) {
301  DRWN_LOG_DEBUG("...skipping update of " << graph[imgIndx].name());
302  continue;
303  }
304 
305  imgIndxes[imgIndx % nJobs].insert(imgIndx);
306  }
307 
308  // start threads
309  drwnThreadPool threadPool(nJobs);
310  threadPool.start();
311  vector<drwnNNGraphThreadedUpdateJob<DistanceMetric> *> jobs(nJobs);
312  for (unsigned i = 0; i < nJobs; i++) {
313  jobs[i] = new drwnNNGraphThreadedUpdateJob<DistanceMetric>(imgIndxes[i], graph, M);
314  threadPool.addJob(jobs[i]);
315  }
316  threadPool.finish();
317 
318  for (unsigned i = 0; i < jobs.size(); i++) {
319  delete jobs[i];
320  }
321  jobs.clear();
322  }
323 
324  // enrichment (forward and inverse)
326  enrichment(graph, M);
327  }
328 
329  DRWN_FCN_TOC;
330 }
331 
332 template<class DistanceMetric>
333 void drwnNNGraphThreadedMoves::updateImage(drwnNNGraph& graph, unsigned imgIndx, const DistanceMetric& M)
334 {
335  // perform update on each node
336  drwnNNGraphNodeIndex u(imgIndx, 0);
337  for (u.segId = 0; u.segId < graph[u.imgIndx].numNodes(); u.segId++) {
338  if (drwnNNGraph::DO_LOCAL) {
339  drwnNNGraphMoves::local(graph, u, M);
340  }
342  drwnNNGraphMoves::propagate(graph, u, M);
343  }
345  drwnNNGraphMoves::search(graph, u, M);
346  }
347  }
348 }
349 
350 template<class DistanceMetric>
351 bool drwnNNGraphThreadedMoves::randproj(drwnNNGraph& graph, const DistanceMetric& M)
352 {
353  DRWN_FCN_TIC;
354  bool bChanged = false;
355 
356  // pick a random direction
357  VectorXf mu(graph[0][0].features.size());
358  for (int i = 0; i < mu.rows(); i++) {
359  mu[i] = float(drand48() - 0.5);
360  }
361  mu /= mu.norm();
362 
363  // project all superpixels
364  vector<pair<float, drwnNNGraphNodeIndex> > projections;
365  projections.reserve(graph.numNodes());
366 
368  for (u.imgIndx = 0; u.imgIndx < graph.numImages(); u.imgIndx++) {
369  for (u.segId = 0; u.segId < graph[u.imgIndx].numNodes(); u.segId++) {
370  const float x = mu.dot(graph[u].features);
371  projections.push_back(make_pair(x, u));
372  }
373  }
374 
375  // sort
376  sort(projections.begin(), projections.end());
377 
378  // score
379  unsigned dbCountChanged = 0;
380  unsigned inext = 0;
381  for (unsigned i = 0; i < projections.size() - 1; i++) {
382  const drwnNNGraphNodeIndex &u = projections[i].second;
383 
384  // don't update inactive images
385  if (!graph[u.imgIndx].bSourceMatchable || graph[u].edges.empty()) {
386  if (inext <= i) inext += 1;
387  continue;
388  }
389 
390  // skip if images are in the same equivalence class
391  while (inext != projections.size()) {
392  if (graph[projections[inext].second.imgIndx].bTargetMatchable &&
393  !graph.inSameEqvClass(u.imgIndx, projections[inext].second.imgIndx))
394  break;
395  inext += 1;
396  }
397 
398  if (inext == projections.size()) break;
399 
400  float uworst = sqrt(graph[u].edges.back().weight);
401  for (unsigned j = inext; j < std::min(projections.size(), (size_t)(inext + drwnNNGraph::DO_RANDPROJ)); j++) {
402  // cauchy-schwarz check
403  if ((projections[j].first - projections[i].first) >= uworst) {
404  break;
405  }
406 
407  // equivalence class check
408  if (!graph[projections[j].second.imgIndx].bTargetMatchable) continue;
409  if (graph.inSameEqvClass(u.imgIndx, projections[j].second.imgIndx))
410  continue;
411 
412  // evaluate edge candidate
413  const drwnNNGraphNodeIndex &v = projections[j].second;
414 
415  if (M.isFinite(graph[u], graph[v])) {
416  const float w = M.score(graph[u], graph[v]);
417  if (graph[u].insert(drwnNNGraphEdge(v, w))) {
418  uworst = sqrt(graph[u].edges.back().weight);
419  dbCountChanged += 1;
420  bChanged = true;
421  }
422  }
423  }
424  }
425 
426  DRWN_LOG_DEBUG("randproj() improved " << dbCountChanged << " matches");
427  DRWN_FCN_TOC;
428  return bChanged;
429 }
430 
431 template<class DistanceMetric>
432 bool drwnNNGraphThreadedMoves::enrichment(drwnNNGraph& graph, const DistanceMetric& M)
433 {
434  DRWN_FCN_TIC;
435  bool bChanged = false;
436 
437  // inverse enrichment
438  for (unsigned imgIndx = 0; imgIndx < graph.numImages(); imgIndx++) {
439  // skip image if not target matchable
440  if (!graph[imgIndx].bTargetMatchable) continue;
441 
442  for (unsigned segId = 0; segId < graph[imgIndx].numNodes(); segId++) {
443  const drwnNNGraphEdgeList& el = graph[imgIndx][segId].edges;
444  for (drwnNNGraphEdgeList::const_iterator kt = el.begin(); kt != el.end(); ++kt) {
445 
446  // skip if not active
447  if (!graph[kt->targetNode.imgIndx].bSourceMatchable)
448  continue;
449 
450  // evaluate reverse edge
451  const drwnNNGraphEdge e(drwnNNGraphNodeIndex(imgIndx, segId), kt->weight);
452  if (graph[kt->targetNode].insert(e)) {
453  bChanged = true;
454  }
455  }
456  }
457  }
458 
459  // forward enrichment
460  for (unsigned imgIndx = 0; imgIndx < graph.numImages(); imgIndx++) {
461  // only do forward enrichment on active images
462  if (!graph[imgIndx].bSourceMatchable) continue;
463 
464  for (unsigned segId = 0; segId < graph[imgIndx].numNodes(); segId++) {
465  // needed to prevent invalid iterators when updating e
466  const drwnNNGraphEdgeList el(graph[imgIndx][segId].edges);
467 
468  int nCompared = (int)drwnNNGraph::K; // prevent quadratic growth in K
469  for (drwnNNGraphEdgeList::const_iterator it = el.begin(); it != el.end(); ++it) {
470  const drwnNNGraphEdgeList& r = graph[it->targetNode].edges;
471 
472  for (drwnNNGraphEdgeList::const_iterator kt = r.begin(); kt != r.end(); ++kt) {
473  // check that we're not matching back to ourself (or any other
474  // image in the same equivalence class) and is matchable
475  if (!graph[kt->targetNode.imgIndx].bTargetMatchable) continue;
476  if (graph.inSameEqvClass(kt->targetNode.imgIndx, imgIndx)) continue;
477 
478  // check that we have processed this pair previously
479  if ((it->status == DRWN_NNG_PROCESSED_TWICE) &&
480  (kt->status == DRWN_NNG_PROCESSED_TWICE)) continue;
481 
482  // check that edge is legal
483  if (!M.isFinite(graph[imgIndx][segId], graph[kt->targetNode]))
484  continue;
485 
486  const float w = M.score(graph[imgIndx][segId], graph[kt->targetNode]);
487  if (graph[imgIndx][segId].insert(drwnNNGraphEdge(kt->targetNode, w))) {
488  bChanged = true;
489  }
490 
491  nCompared -= 1;
492  if (nCompared < 0) break;
493  }
494 
495  if (nCompared < 0) break;
496  }
497  }
498  }
499 
500  DRWN_FCN_TOC;
501  return bChanged;
502 }
static int DO_RANDPROJ
execute random projection move to given horizon
Definition: drwnNNGraph.h:315
bool local(drwnNNGraph &graph, const drwnNNGraphNodeIndex &u, const DistanceMetric &M)
local neighbourhood search around current match for superpixel u (returns true if a better match was ...
Definition: drwnNNGraphMoves.h:557
Implements a pool of threads for running concurrent jobs.
Definition: drwnThreadPool.h:76
uint16_t imgIndx
image index for this node
Definition: drwnNNGraph.h:47
Interface for a thread job functor.
Definition: drwnThreadPool.h:45
uint16_t segId
superpixel identifier this node
Definition: drwnNNGraph.h:48
void finish(bool bShowStatus=false)
finish the jobs in the queue and stop
Definition: drwnThreadPool.cpp:210
set< unsigned > _imgIndxes
indexes of images for this job
Definition: drwnNNGraphThreadedMoves.h:75
bool exhaustive(drwnNNGraph &graph, const drwnNNGraphNodeIndex &u, const DistanceMetric &M)
exhaustive search for best match across entire graph — use sparingly (returns true if a better match ...
Definition: drwnNNGraphMoves.h:745
void operator()()
thread functor called by drwnThreadPool with the appropriate threadId
Definition: drwnNNGraphThreadedMoves.h:83
Definition: drwnNNGraph.h:45
Implements the scoring functions needed by the search moves. Required member functions are isMatchabl...
Definition: drwnNNGraphMoves.h:24
static unsigned MAX_THREADS
maximum number of threads allowed
Definition: drwnThreadPool.h:80
bool enrichment(drwnNNGraph &graph, const DistanceMetric &M)
enrichment: inverse (from target to source) and forward (from source to target's target) (returns tru...
Definition: drwnNNGraphThreadedMoves.h:432
void operator()()
thread functor called by drwnThreadPool with the appropriate threadId
Definition: drwnNNGraphThreadedMoves.h:143
const DistanceMetric & _M
distance metric to use during moves
Definition: drwnNNGraphThreadedMoves.h:74
const DistanceMetric & _M
distance metric to use during moves
Definition: drwnNNGraphThreadedMoves.h:114
bool propagate(drwnNNGraph &graph, const drwnNNGraphNodeIndex &u, const DistanceMetric &M)
propagate good matches from supeprixel u to its neighbours (returns true if a better match was found)...
Definition: drwnNNGraphMoves.h:474
static bool DO_PROPAGATE
execute propagate move
Definition: drwnNNGraph.h:312
static bool DO_SEARCH
execute random search move
Definition: drwnNNGraph.h:314
void start()
prepare the thread pool to take jobs
Definition: drwnThreadPool.cpp:151
bool search(drwnNNGraph &graph, const drwnNNGraphNodeIndex &u, const DistanceMetric &M)
random search across all images for superpixel u (returns true if a better match was found) ...
Definition: drwnNNGraphMoves.h:521
void operator()()
thread functor called by drwnThreadPool with the appropriate threadId
Definition: drwnNNGraphThreadedMoves.h:123
set< drwnNNGraphNodeIndex > _nodeIndxes
indexes of nodes for this job
Definition: drwnNNGraphThreadedMoves.h:135
set< unsigned > _imgIndxes
indexes of images for this job
Definition: drwnNNGraphThreadedMoves.h:95
static unsigned int K
default number of matches per node
Definition: drwnNNGraph.h:311
void addJob(drwnThreadJob *job)
add a job to the queue
Definition: drwnThreadPool.cpp:179
double rescore(drwnNNGraph &graph, const DistanceMetric &M)
rescore all matches based on current features (which may have changed since graph was created) ...
Definition: drwnNNGraphThreadedMoves.h:186
void update(drwnNNGraph &graph, const DistanceMetric &M)
perform one update iteration (including enrichment and exhaustive) on all active images ...
Definition: drwnNNGraphThreadedMoves.h:218
size_t numNodes() const
number of nodes (superpixels) in the graph
Definition: drwnNNGraph.cpp:814
bool inSameEqvClass(unsigned imgIndxA, unsigned imgIndxB) const
return true if two images are in the same equivalence class
Definition: drwnNNGraph.h:367
drwnNNGraph & _graph
graph for updating (includes features)
Definition: drwnNNGraphThreadedMoves.h:96
const DistanceMetric & _M
distance metric to use during moves
Definition: drwnNNGraphThreadedMoves.h:94
threading rescore functor
Definition: drwnNNGraphThreadedMoves.h:92
threading exhaustive functor
Definition: drwnNNGraphThreadedMoves.h:132
pair< double, double > energy() const
sum of all edge weights (first) and best edge weights (second)
Definition: drwnNNGraph.cpp:882
size_t numImages() const
number of images in the graph
Definition: drwnNNGraph.h:343
Encapsulates an outgoing edge in a drwnNNGraph.
Definition: drwnNNGraph.h:82
drwnNNGraph & _graph
graph for updating (includes features)
Definition: drwnNNGraphThreadedMoves.h:76
void updateImage(drwnNNGraph &graph, unsigned imgIndx, const DistanceMetric &M)
perform single update iteration of propagate, local and search moves on a specific image ...
Definition: drwnNNGraphThreadedMoves.h:333
drwnNNGraph & _graph
graph for updating (includes features)
Definition: drwnNNGraphThreadedMoves.h:116
static int DO_EXHAUSTIVE
execute n exhaustive search moves per iteration
Definition: drwnNNGraph.h:317
const DistanceMetric & _M
distance metric to use during moves
Definition: drwnNNGraphThreadedMoves.h:134
static bool DO_LOCAL
execute local move
Definition: drwnNNGraph.h:313
void operator()()
thread functor called by drwnThreadPool with the appropriate threadId
Definition: drwnNNGraphThreadedMoves.h:103
double rescore(drwnNNGraph &graph, const DistanceMetric &M)
rescore all matches based on current features (which may have changed since graph was created) ...
Definition: drwnNNGraphMoves.h:283
set< unsigned > _imgIndxes
indexes of images for this job
Definition: drwnNNGraphThreadedMoves.h:115
threading initialize functor
Definition: drwnNNGraphThreadedMoves.h:72
static bool DO_ENRICHMENT
execute enrichment moves
Definition: drwnNNGraph.h:316
void initialize(drwnNNGraph &graph, const DistanceMetric &M)
randomly initialize edges (matched) for all active images (keeps existing matches unless an improveme...
Definition: drwnNNGraphThreadedMoves.h:154
Class for maintaining a nearest neighbour graph over superpixel images. Search moves are implemented ...
Definition: drwnNNGraph.h:309
drwnNNGraph & _graph
graph for updating (includes features)
Definition: drwnNNGraphThreadedMoves.h:136
void initialize(drwnNNGraph &graph, const DistanceMetric &M)
randomly initialize edges (matched) for all active images (keeps existing matches unless an improveme...
Definition: drwnNNGraphMoves.h:159
bool randproj(drwnNNGraph &graph, const DistanceMetric &M)
random projection moves that project all superpixels onto a random direction, sort and compare adjace...
Definition: drwnNNGraphThreadedMoves.h:351
threading update functor
Definition: drwnNNGraphThreadedMoves.h:112