Commit f866c1b42d04d86fdae13275fe23140abc578f9a

Authored by bhklein
1 parent 268f5a4f

refactor knnOutput

Showing 1 changed file with 53 additions and 17 deletions
openbr/plugins/output/knn.cpp
... ... @@ -6,44 +6,80 @@
6 6 namespace br
7 7 {
8 8  
  9 +typedef QPair<float,int> Pair;
  10 +
9 11 /*!
10 12 * \ingroup outputs
11 13 * \brief Outputs the k-Nearest Neighbors from the gallery for each probe.
12 14 * \author Ben Klein \cite bhklein
13 15 */
14   -class knnOutput : public MatrixOutput
  16 +class knnOutput : public Output
15 17 {
16 18 Q_OBJECT
17 19  
  20 + int rowBlock, columnBlock;
  21 + size_t headerSize, k;
  22 + cv::Mat blockScores;
  23 +
18 24 ~knnOutput()
19 25 {
20   - size_t num_probes = (size_t)queryFiles.size();
21   - if (targetFiles.isEmpty() || queryFiles.isEmpty()) return;
22   - size_t k = file.get<size_t>("k", 20);
  26 + writeBlock();
  27 + }
23 28  
24   - if ((size_t)targetFiles.size() < k)
25   - qFatal("Gallery size %s is smaller than k = %s.", qPrintable(QString::number(targetFiles.size())), qPrintable(QString::number(k)));
  29 + void setBlock(int rowBlock, int columnBlock)
  30 + {
  31 + if ((rowBlock == 0) && (columnBlock == 0)) {
  32 + k = file.get<size_t>("k", 20);
  33 + QFile f(file);
  34 + if (!f.open(QFile::WriteOnly))
  35 + qFatal("Unable to open %s for writing.", qPrintable(file));
  36 + size_t querySize = (size_t)queryFiles.size();
  37 + f.write((const char*) &querySize, sizeof(size_t));
  38 + f.write((const char*) &k, sizeof(size_t));
  39 + headerSize = 2 * sizeof(size_t);
  40 + } else {
  41 + writeBlock();
  42 + }
26 43  
27   - QFile f(file);
28   - if (!f.open(QFile::WriteOnly))
29   - qFatal("Unable to open %s for writing.", qPrintable(file));
30   - f.write((const char*) &num_probes, sizeof(size_t));
31   - f.write((const char*) &k, sizeof(size_t));
  44 + this->rowBlock = rowBlock;
  45 + this->columnBlock = columnBlock;
  46 +
  47 + int matrixRows = std::min(queryFiles.size()-rowBlock*this->blockRows, blockRows);
  48 + int matrixCols = std::min(targetFiles.size()-columnBlock*this->blockCols, blockCols);
  49 +
  50 + blockScores = cv::Mat(matrixRows, matrixCols, CV_32FC1);
  51 + }
32 52  
33   - QVector<Candidate> neighbors; neighbors.reserve(num_probes*k);
  53 + void setRelative(float value, int i, int j)
  54 + {
  55 + blockScores.at<float>(i,j) = value;
  56 + }
  57 +
  58 + void set(float value, int i, int j)
  59 + {
  60 + (void) value; (void) i; (void) j;
  61 + qFatal("Logic error.");
  62 + }
  63 +
  64 + void writeBlock()
  65 + {
  66 + QFile f(file);
  67 + if (!f.open(QFile::ReadWrite))
  68 + qFatal("Unable to open %s for modifying.", qPrintable(file));
  69 + QVector<Candidate> neighbors; neighbors.reserve(k * blockScores.rows);
34 70  
35   - for (size_t i=0; i<num_probes; i++) {
36   - typedef QPair<float,int> Pair;
  71 + for (int i=0; i<blockScores.rows; i++) {
37 72 size_t rank = 0;
38   - foreach (const Pair &pair, Common::Sort(OpenCVUtils::matrixToVector<float>(data.row(i)), true)) {
39   - if (QString(targetFiles[pair.second]) != QString(queryFiles[i])) {
  73 + foreach (const Pair &pair, Common::Sort(OpenCVUtils::matrixToVector<float>(blockScores.row(i)), true)) {
  74 + if (QString(targetFiles[pair.second]) != QString(queryFiles[rowBlock*this->blockRows+i])) {
40 75 Candidate candidate((size_t)pair.second, pair.first);
41 76 neighbors.push_back(candidate);
42 77 if (++rank >= k) break;
43 78 }
44 79 }
45 80 }
46   - f.write((const char*) neighbors.data(), num_probes * k * sizeof(Candidate));
  81 + f.seek(headerSize + sizeof(Candidate)*quint64(rowBlock*this->blockRows)*k);
  82 + f.write((const char*) neighbors.data(), blockScores.rows * k * sizeof(Candidate));
47 83 f.close();
48 84 }
49 85 };
... ...