Commit c45d03f023ddbd2541ebee9a5066c36c8190d935
Merge branch 'master' of https://github.com/biometrics/openbr into no_scale
Showing
3 changed files
with
70 additions
and
10 deletions
openbr/openbr_plugin.h
| @@ -906,8 +906,8 @@ public: | @@ -906,8 +906,8 @@ public: | ||
| 906 | bool selfSimilar; /*!< \brief \c true if the \em targetFiles == \em queryFiles, \c false otherwise. */ | 906 | bool selfSimilar; /*!< \brief \c true if the \em targetFiles == \em queryFiles, \c false otherwise. */ |
| 907 | 907 | ||
| 908 | virtual ~Output() {} | 908 | virtual ~Output() {} |
| 909 | - void setBlock(int rowBlock, int columnBlock); /*!< \brief Set the current block. */ | ||
| 910 | - void setRelative(float value, int i, int j); /*!< \brief Set a score relative to the current block. */ | 909 | + virtual void setBlock(int rowBlock, int columnBlock); /*!< \brief Set the current block. */ |
| 910 | + virtual void setRelative(float value, int i, int j); /*!< \brief Set a score relative to the current block. */ | ||
| 911 | 911 | ||
| 912 | static Output *make(const File &file, const FileList &targetFiles, const FileList &queryFiles); /*!< \brief Make an output from a file and gallery/probe file lists. */ | 912 | static Output *make(const File &file, const FileList &targetFiles, const FileList &queryFiles); /*!< \brief Make an output from a file and gallery/probe file lists. */ |
| 913 | static void reformat(const FileList &targetFiles, const FileList &queryFiles, const File &simmat, const File &output); /*!< \brief Create an output from a similarity matrix and file lists. */ | 913 | static void reformat(const FileList &targetFiles, const FileList &queryFiles, const File &simmat, const File &output); /*!< \brief Create an output from a similarity matrix and file lists. */ |
openbr/plugins/misc.cpp
| @@ -424,19 +424,21 @@ BR_REGISTER(Transform, SubjectTransform) | @@ -424,19 +424,21 @@ BR_REGISTER(Transform, SubjectTransform) | ||
| 424 | 424 | ||
| 425 | /*! | 425 | /*! |
| 426 | * \ingroup transforms | 426 | * \ingroup transforms |
| 427 | - * \brief Remove templates with the specified file extension. | 427 | + * \brief Remove templates with the specified file extension or metadata value. |
| 428 | * \author Josh Klontz \cite jklontz | 428 | * \author Josh Klontz \cite jklontz |
| 429 | */ | 429 | */ |
| 430 | class RemoveTemplatesTransform : public UntrainableMetaTransform | 430 | class RemoveTemplatesTransform : public UntrainableMetaTransform |
| 431 | { | 431 | { |
| 432 | Q_OBJECT | 432 | Q_OBJECT |
| 433 | Q_PROPERTY(QString regexp READ get_regexp WRITE set_regexp RESET reset_regexp STORED false) | 433 | Q_PROPERTY(QString regexp READ get_regexp WRITE set_regexp RESET reset_regexp STORED false) |
| 434 | + Q_PROPERTY(QString key READ get_key WRITE set_key RESET reset_key STORED false) | ||
| 434 | BR_PROPERTY(QString, regexp, "") | 435 | BR_PROPERTY(QString, regexp, "") |
| 436 | + BR_PROPERTY(QString, key, "") | ||
| 435 | 437 | ||
| 436 | void project(const Template &src, Template &dst) const | 438 | void project(const Template &src, Template &dst) const |
| 437 | { | 439 | { |
| 438 | const QRegularExpression re(regexp); | 440 | const QRegularExpression re(regexp); |
| 439 | - const QRegularExpressionMatch match = re.match(src.file.suffix()); | 441 | + const QRegularExpressionMatch match = re.match(key.isEmpty() ? src.file.suffix() : src.file.get<QString>(key)); |
| 440 | if (match.hasMatch()) dst = Template(); | 442 | if (match.hasMatch()) dst = Template(); |
| 441 | else dst = src; | 443 | else dst = src; |
| 442 | } | 444 | } |
openbr/plugins/output.cpp
| @@ -138,17 +138,75 @@ BR_REGISTER(Output, meltOutput) | @@ -138,17 +138,75 @@ BR_REGISTER(Output, meltOutput) | ||
| 138 | * \brief \ref simmat output. | 138 | * \brief \ref simmat output. |
| 139 | * \author Josh Klontz \cite jklontz | 139 | * \author Josh Klontz \cite jklontz |
| 140 | */ | 140 | */ |
| 141 | -class mtxOutput : public MatrixOutput | 141 | +class mtxOutput : public Output |
| 142 | { | 142 | { |
| 143 | Q_OBJECT | 143 | Q_OBJECT |
| 144 | + int headerSize, rowBlock, columnBlock; | ||
| 145 | + cv::Mat blockScores; | ||
| 144 | 146 | ||
| 145 | ~mtxOutput() | 147 | ~mtxOutput() |
| 146 | { | 148 | { |
| 147 | - if (file.isNull() || targetFiles.isEmpty() || queryFiles.isEmpty()) return; | ||
| 148 | - BEE::writeSimmat(data, | ||
| 149 | - file.name, | ||
| 150 | - targetFiles.first().get<QString>("Gallery", "Unknown_Target"), | ||
| 151 | - queryFiles.first().get<QString>("Gallery", "Unknown_Query")); | 149 | + writeBlock(); |
| 150 | + } | ||
| 151 | + | ||
| 152 | + void setBlock(int rowBlock, int columnBlock) | ||
| 153 | + { | ||
| 154 | + if ((rowBlock == 0) && (columnBlock == 0)) { | ||
| 155 | + // Initialize the file | ||
| 156 | + QFile f(file); | ||
| 157 | + QtUtils::touchDir(f); | ||
| 158 | + if (!f.open(QFile::WriteOnly)) | ||
| 159 | + qFatal("Unable to open %s for writing.", qPrintable(file)); | ||
| 160 | + const int endian = 0x12345678; | ||
| 161 | + QByteArray header; | ||
| 162 | + header.append("S2\n"); | ||
| 163 | + header.append(qPrintable(targetFiles.first().get<QString>("Gallery", "Unknown_Target"))); | ||
| 164 | + header.append("\n"); | ||
| 165 | + header.append(qPrintable(queryFiles.first().get<QString>("Gallery", "Unknown_Query"))); | ||
| 166 | + header.append("\nMF "); | ||
| 167 | + header.append(qPrintable(QString::number(queryFiles.size()))); | ||
| 168 | + header.append(" "); | ||
| 169 | + header.append(qPrintable(QString::number(targetFiles.size()))); | ||
| 170 | + header.append(" "); | ||
| 171 | + header.append(QByteArray((const char*)&endian, 4)); | ||
| 172 | + header.append("\n"); | ||
| 173 | + headerSize = f.write(header); | ||
| 174 | + const float defaultValue = -std::numeric_limits<float>::max(); | ||
| 175 | + for (int i=0; i<targetFiles.size()*queryFiles.size(); i++) | ||
| 176 | + f.write((const char*)&defaultValue, 4); | ||
| 177 | + f.close(); | ||
| 178 | + } else { | ||
| 179 | + writeBlock(); | ||
| 180 | + } | ||
| 181 | + | ||
| 182 | + this->rowBlock = rowBlock; | ||
| 183 | + this->columnBlock = columnBlock; | ||
| 184 | + blockScores = cv::Mat(std::min(queryFiles.size()-rowBlock*Globals->blockSize, Globals->blockSize), | ||
| 185 | + std::min(targetFiles.size()-columnBlock*Globals->blockSize, Globals->blockSize), | ||
| 186 | + CV_32FC1); | ||
| 187 | + } | ||
| 188 | + | ||
| 189 | + void setRelative(float value, int i, int j) | ||
| 190 | + { | ||
| 191 | + blockScores.at<float>(i,j) = value; | ||
| 192 | + } | ||
| 193 | + | ||
| 194 | + void set(float value, int i, int j) | ||
| 195 | + { | ||
| 196 | + (void) value; (void) i; (void) j; | ||
| 197 | + qFatal("Logic error."); | ||
| 198 | + } | ||
| 199 | + | ||
| 200 | + void writeBlock() | ||
| 201 | + { | ||
| 202 | + QFile f(file); | ||
| 203 | + if (!f.open(QFile::ReadWrite)) | ||
| 204 | + qFatal("Unable to open %s for modifying.", qPrintable(file)); | ||
| 205 | + for (int i=0; i<blockScores.rows; i++) { | ||
| 206 | + f.seek(headerSize + sizeof(float)*((rowBlock*Globals->blockSize+i)*targetFiles.size()+(columnBlock*Globals->blockSize))); | ||
| 207 | + f.write((const char*)blockScores.row(i).data, sizeof(float)*blockScores.cols); | ||
| 208 | + } | ||
| 209 | + f.close(); | ||
| 152 | } | 210 | } |
| 153 | }; | 211 | }; |
| 154 | 212 |