Commit f866c1b42d04d86fdae13275fe23140abc578f9a
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 | }; | ... | ... |