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,44 +6,80 @@ | ||
| 6 | namespace br | 6 | namespace br |
| 7 | { | 7 | { |
| 8 | 8 | ||
| 9 | +typedef QPair<float,int> Pair; | ||
| 10 | + | ||
| 9 | /*! | 11 | /*! |
| 10 | * \ingroup outputs | 12 | * \ingroup outputs |
| 11 | * \brief Outputs the k-Nearest Neighbors from the gallery for each probe. | 13 | * \brief Outputs the k-Nearest Neighbors from the gallery for each probe. |
| 12 | * \author Ben Klein \cite bhklein | 14 | * \author Ben Klein \cite bhklein |
| 13 | */ | 15 | */ |
| 14 | -class knnOutput : public MatrixOutput | 16 | +class knnOutput : public Output |
| 15 | { | 17 | { |
| 16 | Q_OBJECT | 18 | Q_OBJECT |
| 17 | 19 | ||
| 20 | + int rowBlock, columnBlock; | ||
| 21 | + size_t headerSize, k; | ||
| 22 | + cv::Mat blockScores; | ||
| 23 | + | ||
| 18 | ~knnOutput() | 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 | size_t rank = 0; | 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 | Candidate candidate((size_t)pair.second, pair.first); | 75 | Candidate candidate((size_t)pair.second, pair.first); |
| 41 | neighbors.push_back(candidate); | 76 | neighbors.push_back(candidate); |
| 42 | if (++rank >= k) break; | 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 | f.close(); | 83 | f.close(); |
| 48 | } | 84 | } |
| 49 | }; | 85 | }; |