Commit f4a9384b392cea2ed836ce1851f8d93b72803a08
1 parent
303a0d8a
introduced Distance::compare(cv::Mat, cv::Mat)
Showing
10 changed files
with
115 additions
and
45 deletions
openbr/openbr_plugin.h
| ... | ... | @@ -1324,7 +1324,8 @@ public: |
| 1324 | 1324 | virtual void train(const TemplateList &src) { (void) src; } /*!< \brief Train the distance. */ |
| 1325 | 1325 | virtual void compare(const TemplateList &target, const TemplateList &query, Output *output) const; /*!< \brief Compare two template lists. */ |
| 1326 | 1326 | virtual QList<float> compare(const TemplateList &targets, const Template &query) const; /*!< \brief Compute the normalized distance between a template and a template list. */ |
| 1327 | - virtual float compare(const Template &a, const Template &b) const = 0; /*!< \brief Compute the distance between two templates. */ | |
| 1327 | + virtual float compare(const Template &a, const Template &b) const { return compare(a.m(), b.m()); } /*!< \brief Compute the distance between two templates. */ | |
| 1328 | + virtual float compare(const cv::Mat &a, const cv::Mat &b) const = 0; | |
| 1328 | 1329 | |
| 1329 | 1330 | protected: |
| 1330 | 1331 | inline Distance *make(const QString &description) { return make(description, this); } /*!< \brief Make a subdistance. */ | ... | ... |
openbr/plugins/distance.cpp
| ... | ... | @@ -58,10 +58,10 @@ private: |
| 58 | 58 | BR_PROPERTY(Metric, metric, L2) |
| 59 | 59 | BR_PROPERTY(bool, negLogPlusOne, true) |
| 60 | 60 | |
| 61 | - float compare(const Template &a, const Template &b) const | |
| 61 | + float compare(const Mat &a, const Mat &b) const | |
| 62 | 62 | { |
| 63 | - if ((a.m().size != b.m().size) || | |
| 64 | - (a.m().type() != b.m().type())) | |
| 63 | + if ((a.size != b.size) || | |
| 64 | + (a.type() != b.type())) | |
| 65 | 65 | return -std::numeric_limits<float>::max(); |
| 66 | 66 | |
| 67 | 67 | // TODO: this max value is never returned based on the switch / default |
| ... | ... | @@ -90,7 +90,7 @@ private: |
| 90 | 90 | case Cosine: |
| 91 | 91 | return cosine(a, b); |
| 92 | 92 | case Dot: |
| 93 | - return a.m().dot(b); | |
| 93 | + return a.dot(b); | |
| 94 | 94 | default: |
| 95 | 95 | qFatal("Invalid metric"); |
| 96 | 96 | } |
| ... | ... | @@ -138,7 +138,7 @@ class DefaultDistance : public Distance |
| 138 | 138 | distance = Distance::make("Dist("+file.suffix()+")"); |
| 139 | 139 | } |
| 140 | 140 | |
| 141 | - float compare(const Template &a, const Template &b) const | |
| 141 | + float compare(const cv::Mat &a, const cv::Mat &b) const | |
| 142 | 142 | { |
| 143 | 143 | return distance->compare(a, b); |
| 144 | 144 | } |
| ... | ... | @@ -169,7 +169,7 @@ class PipeDistance : public Distance |
| 169 | 169 | futures.waitForFinished(); |
| 170 | 170 | } |
| 171 | 171 | |
| 172 | - float compare(const Template &a, const Template &b) const | |
| 172 | + float compare(const Mat &a, const Mat &b) const | |
| 173 | 173 | { |
| 174 | 174 | float result = -std::numeric_limits<float>::max(); |
| 175 | 175 | foreach (br::Distance *distance, distances) { |
| ... | ... | @@ -224,6 +224,11 @@ private: |
| 224 | 224 | distances[i]->train(partitionedSrc[i]); |
| 225 | 225 | } |
| 226 | 226 | |
| 227 | + float compare(const Mat &a, const Mat &b) const | |
| 228 | + { | |
| 229 | + return distances.first()->compare(a, b); | |
| 230 | + } | |
| 231 | + | |
| 227 | 232 | float compare(const Template &a, const Template &b) const |
| 228 | 233 | { |
| 229 | 234 | if (a.size() != b.size()) qFatal("Comparison size mismatch"); |
| ... | ... | @@ -232,7 +237,7 @@ private: |
| 232 | 237 | for (int i=0; i<distances.size(); i++) { |
| 233 | 238 | float weight; |
| 234 | 239 | weights.isEmpty() ? weight = 1. : weight = weights[i]; |
| 235 | - scores.append(weight*distances[i]->compare(Template(a.file, a[i]),Template(b.file, b[i]))); | |
| 240 | + scores.append(weight*distances[i]->compare(a[i], b[i])); | |
| 236 | 241 | } |
| 237 | 242 | |
| 238 | 243 | switch (operation) { |
| ... | ... | @@ -282,9 +287,9 @@ class ByteL1Distance : public Distance |
| 282 | 287 | { |
| 283 | 288 | Q_OBJECT |
| 284 | 289 | |
| 285 | - float compare(const Template &a, const Template &b) const | |
| 290 | + float compare(const Mat &a, const Mat &b) const | |
| 286 | 291 | { |
| 287 | - return l1(a.m().data, b.m().data, a.m().total()); | |
| 292 | + return l1(a.data, b.data, a.total()); | |
| 288 | 293 | } |
| 289 | 294 | }; |
| 290 | 295 | |
| ... | ... | @@ -299,9 +304,9 @@ class HalfByteL1Distance : public Distance |
| 299 | 304 | { |
| 300 | 305 | Q_OBJECT |
| 301 | 306 | |
| 302 | - float compare(const Template &a, const Template &b) const | |
| 307 | + float compare(const Mat &a, const Mat &b) const | |
| 303 | 308 | { |
| 304 | - return packed_l1(a.m().data, b.m().data, a.m().total()); | |
| 309 | + return packed_l1(a.data, b.data, a.total()); | |
| 305 | 310 | } |
| 306 | 311 | }; |
| 307 | 312 | |
| ... | ... | @@ -323,6 +328,11 @@ class NegativeLogPlusOneDistance : public Distance |
| 323 | 328 | distance->train(src); |
| 324 | 329 | } |
| 325 | 330 | |
| 331 | + float compare(const cv::Mat &a, const cv::Mat &b) const | |
| 332 | + { | |
| 333 | + return compare(Template(a), Template(b)); | |
| 334 | + } | |
| 335 | + | |
| 326 | 336 | float compare(const Template &a, const Template &b) const |
| 327 | 337 | { |
| 328 | 338 | return -log(distance->compare(a,b)+1); |
| ... | ... | @@ -350,21 +360,18 @@ class IdenticalDistance : public Distance |
| 350 | 360 | { |
| 351 | 361 | Q_OBJECT |
| 352 | 362 | |
| 353 | - float compare(const Template &a, const Template &b) const | |
| 363 | + float compare(const Mat &a, const Mat &b) const | |
| 354 | 364 | { |
| 355 | - const Mat &am = a.m(); | |
| 356 | - const Mat &bm = b.m(); | |
| 357 | - const size_t size = am.total() * am.elemSize(); | |
| 358 | - if (size != bm.total() * bm.elemSize()) return 0; | |
| 365 | + const size_t size = a.total() * a.elemSize(); | |
| 366 | + if (size != b.total() * b.elemSize()) return 0; | |
| 359 | 367 | for (size_t i=0; i<size; i++) |
| 360 | - if (am.data[i] != bm.data[i]) return 0; | |
| 368 | + if (a.data[i] != b.data[i]) return 0; | |
| 361 | 369 | return 1; |
| 362 | 370 | } |
| 363 | 371 | }; |
| 364 | 372 | |
| 365 | 373 | BR_REGISTER(Distance, IdenticalDistance) |
| 366 | 374 | |
| 367 | - | |
| 368 | 375 | /*! |
| 369 | 376 | * \ingroup distances |
| 370 | 377 | * \brief Online distance metric to attenuate match scores across multiple frames |
| ... | ... | @@ -381,6 +388,11 @@ class OnlineDistance : public Distance |
| 381 | 388 | mutable QHash<QString,float> scoreHash; |
| 382 | 389 | mutable QMutex mutex; |
| 383 | 390 | |
| 391 | + float compare(const Mat &a, const Mat &b) const | |
| 392 | + { | |
| 393 | + return compare(Template(a), Template(b)); | |
| 394 | + } | |
| 395 | + | |
| 384 | 396 | float compare(const Template &target, const Template &query) const |
| 385 | 397 | { |
| 386 | 398 | float currentScore = distance->compare(target, query); |
| ... | ... | @@ -403,6 +415,12 @@ class AttributeDistance : public Distance |
| 403 | 415 | Q_PROPERTY(QString attribute READ get_attribute WRITE set_attribute RESET reset_attribute STORED false) |
| 404 | 416 | BR_PROPERTY(QString, attribute, QString()) |
| 405 | 417 | |
| 418 | + float compare(const cv::Mat &, const cv::Mat &) const | |
| 419 | + { | |
| 420 | + qFatal("Logic error."); | |
| 421 | + return 0; | |
| 422 | + } | |
| 423 | + | |
| 406 | 424 | float compare(const Template &target, const Template &query) const |
| 407 | 425 | { |
| 408 | 426 | float queryValue = query.file.get<float>(attribute); |
| ... | ... | @@ -437,6 +455,11 @@ class SumDistance : public Distance |
| 437 | 455 | futures.waitForFinished(); |
| 438 | 456 | } |
| 439 | 457 | |
| 458 | + float compare(const Mat &a, const Mat &b) const | |
| 459 | + { | |
| 460 | + return compare(Template(a), Template(b)); | |
| 461 | + } | |
| 462 | + | |
| 440 | 463 | float compare(const Template &target, const Template &query) const |
| 441 | 464 | { |
| 442 | 465 | float result = 0; | ... | ... |
openbr/plugins/eigen3.cpp
| ... | ... | @@ -659,11 +659,11 @@ class L1Distance : public Distance |
| 659 | 659 | { |
| 660 | 660 | Q_OBJECT |
| 661 | 661 | |
| 662 | - float compare(const Template &a, const Template &b) const | |
| 662 | + float compare(const cv::Mat &a, const cv::Mat &b) const | |
| 663 | 663 | { |
| 664 | - const int size = a.m().rows * a.m().cols; | |
| 665 | - Eigen::Map<Eigen::VectorXf> aMap((float*)a.m().data, size); | |
| 666 | - Eigen::Map<Eigen::VectorXf> bMap((float*)b.m().data, size); | |
| 664 | + const int size = a.rows * a.cols; | |
| 665 | + Eigen::Map<Eigen::VectorXf> aMap((float*)a.data, size); | |
| 666 | + Eigen::Map<Eigen::VectorXf> bMap((float*)b.data, size); | |
| 667 | 667 | return (aMap-bMap).cwiseAbs().sum(); |
| 668 | 668 | } |
| 669 | 669 | }; |
| ... | ... | @@ -679,11 +679,11 @@ class L2Distance : public Distance |
| 679 | 679 | { |
| 680 | 680 | Q_OBJECT |
| 681 | 681 | |
| 682 | - float compare(const Template &a, const Template &b) const | |
| 682 | + float compare(const cv::Mat &a, const cv::Mat &b) const | |
| 683 | 683 | { |
| 684 | - const int size = a.m().rows * a.m().cols; | |
| 685 | - Eigen::Map<Eigen::VectorXf> aMap((float*)a.m().data, size); | |
| 686 | - Eigen::Map<Eigen::VectorXf> bMap((float*)b.m().data, size); | |
| 684 | + const int size = a.rows * a.cols; | |
| 685 | + Eigen::Map<Eigen::VectorXf> aMap((float*)a.data, size); | |
| 686 | + Eigen::Map<Eigen::VectorXf> bMap((float*)b.data, size); | |
| 687 | 687 | return (aMap-bMap).squaredNorm(); |
| 688 | 688 | } |
| 689 | 689 | }; | ... | ... |
openbr/plugins/keypoint.cpp
| ... | ... | @@ -126,13 +126,13 @@ class KeyPointMatcherDistance : public Distance |
| 126 | 126 | qFatal("Failed to create DescriptorMatcher: %s", qPrintable(matcher)); |
| 127 | 127 | } |
| 128 | 128 | |
| 129 | - float compare(const Template &a, const Template &b) const | |
| 129 | + float compare(const Mat &a, const Mat &b) const | |
| 130 | 130 | { |
| 131 | - if ((a.m().rows < 2) || (b.m().rows < 2)) return 0; | |
| 131 | + if ((a.rows < 2) || (b.rows < 2)) return 0; | |
| 132 | 132 | |
| 133 | 133 | std::vector< std::vector<DMatch> > matches; |
| 134 | - if (a.m().rows < b.m().rows) descriptorMatcher->knnMatch(a, b, matches, 2); | |
| 135 | - else descriptorMatcher->knnMatch(b, a, matches, 2); | |
| 134 | + if (a.rows < b.rows) descriptorMatcher->knnMatch(a, b, matches, 2); | |
| 135 | + else descriptorMatcher->knnMatch(b, a, matches, 2); | |
| 136 | 136 | |
| 137 | 137 | QList<float> distances; |
| 138 | 138 | foreach (const std::vector<DMatch> &match, matches) { | ... | ... |
openbr/plugins/pp5.cpp
| ... | ... | @@ -322,7 +322,7 @@ class PP5CompareDistance : public Distance |
| 322 | 322 | ppr_free_gallery(gallery.gallery); |
| 323 | 323 | } |
| 324 | 324 | |
| 325 | - float compare(const Template &target, const Template &query) const | |
| 325 | + float compare(const cv::Mat &target, const cv::Mat &query) const | |
| 326 | 326 | { |
| 327 | 327 | TemplateList targetList; |
| 328 | 328 | targetList.append(target); | ... | ... |
openbr/plugins/quality.cpp
| ... | ... | @@ -182,7 +182,7 @@ class MatchProbabilityDistance : public Distance |
| 182 | 182 | mp = MP(genuineScores, impostorScores); |
| 183 | 183 | } |
| 184 | 184 | |
| 185 | - float compare(const Template &target, const Template &query) const | |
| 185 | + float compare(const cv::Mat &target, const cv::Mat &query) const | |
| 186 | 186 | { |
| 187 | 187 | const float rawScore = distance->compare(target, query); |
| 188 | 188 | if (rawScore == -std::numeric_limits<float>::max()) return rawScore; |
| ... | ... | @@ -246,6 +246,11 @@ class ZScoreDistance : public Distance |
| 246 | 246 | if (stddev == 0) qFatal("Stddev is 0."); |
| 247 | 247 | } |
| 248 | 248 | |
| 249 | + float compare(const cv::Mat &a, const cv::Mat &b) const | |
| 250 | + { | |
| 251 | + return compare(Template(a), Template(b)); | |
| 252 | + } | |
| 253 | + | |
| 249 | 254 | float compare(const Template &target, const Template &query) const |
| 250 | 255 | { |
| 251 | 256 | float score = distance->compare(target,query); |
| ... | ... | @@ -308,7 +313,7 @@ class HeatMapDistance : public Distance |
| 308 | 313 | distances[i]->train(patches[i]); |
| 309 | 314 | } |
| 310 | 315 | |
| 311 | - float compare(const Template &target, const Template &query) const | |
| 316 | + float compare(const cv::Mat &target, const cv::Mat &query) const | |
| 312 | 317 | { |
| 313 | 318 | (void) target; |
| 314 | 319 | (void) query; |
| ... | ... | @@ -401,6 +406,11 @@ class UnitDistance : public Distance |
| 401 | 406 | qDebug("a = %f, b = %f", a, b); |
| 402 | 407 | } |
| 403 | 408 | |
| 409 | + float compare(const cv::Mat &a, const cv::Mat &b) const | |
| 410 | + { | |
| 411 | + return compare(Template(a), Template(b)); | |
| 412 | + } | |
| 413 | + | |
| 404 | 414 | float compare(const Template &target, const Template &query) const |
| 405 | 415 | { |
| 406 | 416 | return a * (distance->compare(target, query) - b); | ... | ... |
openbr/plugins/quantize.cpp
| ... | ... | @@ -163,11 +163,11 @@ class BayesianQuantizationDistance : public Distance |
| 163 | 163 | futures.waitForFinished(); |
| 164 | 164 | } |
| 165 | 165 | |
| 166 | - float compare(const Template &a, const Template &b) const | |
| 166 | + float compare(const cv::Mat &a, const cv::Mat &b) const | |
| 167 | 167 | { |
| 168 | - const uchar *aData = a.m().data; | |
| 169 | - const uchar *bData = b.m().data; | |
| 170 | - const int size = a.m().rows * a.m().cols; | |
| 168 | + const uchar *aData = a.data; | |
| 169 | + const uchar *bData = b.data; | |
| 170 | + const int size = a.rows * a.cols; | |
| 171 | 171 | float likelihood = 0; |
| 172 | 172 | for (int i=0; i<size; i++) |
| 173 | 173 | likelihood += loglikelihoods[i*256+abs(aData[i]-bData[i])]; |
| ... | ... | @@ -257,6 +257,12 @@ class ProductQuantizationDistance : public Distance |
| 257 | 257 | Q_PROPERTY(bool bayesian READ get_bayesian WRITE set_bayesian RESET reset_bayesian STORED false) |
| 258 | 258 | BR_PROPERTY(bool, bayesian, false) |
| 259 | 259 | |
| 260 | + float compare(const cv::Mat &, const cv::Mat &) const | |
| 261 | + { | |
| 262 | + qFatal("Logic error."); | |
| 263 | + return 0; | |
| 264 | + } | |
| 265 | + | |
| 260 | 266 | float compare(const Template &a, const Template &b) const |
| 261 | 267 | { |
| 262 | 268 | float distance = 0; |
| ... | ... | @@ -297,6 +303,12 @@ class RecursiveProductQuantizationDistance : public Distance |
| 297 | 303 | Q_PROPERTY(float t READ get_t WRITE set_t RESET reset_t STORED false) |
| 298 | 304 | BR_PROPERTY(float, t, -std::numeric_limits<float>::max()) |
| 299 | 305 | |
| 306 | + float compare(const cv::Mat &, const cv::Mat &) const | |
| 307 | + { | |
| 308 | + qFatal("Logic error."); | |
| 309 | + return 0; | |
| 310 | + } | |
| 311 | + | |
| 300 | 312 | float compare(const Template &a, const Template &b) const |
| 301 | 313 | { |
| 302 | 314 | return compareRecursive(a, b, 0, a.size(), 0); | ... | ... |
openbr/plugins/sentence.cpp
| ... | ... | @@ -43,12 +43,12 @@ class SentenceSimilarityDistance : public Distance |
| 43 | 43 | { |
| 44 | 44 | Q_OBJECT |
| 45 | 45 | |
| 46 | - float compare(const Template &a, const Template &b) const | |
| 46 | + float compare(const Mat &a, const Mat &b) const | |
| 47 | 47 | { |
| 48 | - uchar *aBuffer = a.m().data; | |
| 49 | - uchar *bBuffer = b.m().data; | |
| 50 | - const uchar *aEnd = aBuffer + a.m().cols; | |
| 51 | - const uchar *bEnd = bBuffer + b.m().cols; | |
| 48 | + uchar *aBuffer = a.data; | |
| 49 | + uchar *bBuffer = b.data; | |
| 50 | + const uchar *aEnd = aBuffer + a.cols; | |
| 51 | + const uchar *bEnd = bBuffer + b.cols; | |
| 52 | 52 | |
| 53 | 53 | int32_t aWord, bWord, aRows, bRows, aColumns, bColumns; |
| 54 | 54 | float *aData, *bData; | ... | ... |
openbr/plugins/svm.cpp
| ... | ... | @@ -260,10 +260,10 @@ private: |
| 260 | 260 | trainSVM(svm, deltaData, deltaLab, kernel, type, -1, -1); |
| 261 | 261 | } |
| 262 | 262 | |
| 263 | - float compare(const Template &ta, const Template &tb) const | |
| 263 | + float compare(const Mat &a, const Mat &b) const | |
| 264 | 264 | { |
| 265 | 265 | Mat delta; |
| 266 | - absdiff(ta, tb, delta); | |
| 266 | + absdiff(a, b, delta); | |
| 267 | 267 | return svm.predict(delta.reshape(1, 1)); |
| 268 | 268 | } |
| 269 | 269 | ... | ... |
openbr/plugins/validate.cpp
| ... | ... | @@ -143,6 +143,12 @@ class CrossValidateDistance : public Distance |
| 143 | 143 | { |
| 144 | 144 | Q_OBJECT |
| 145 | 145 | |
| 146 | + float compare(const cv::Mat &, const cv::Mat &) const | |
| 147 | + { | |
| 148 | + qFatal("Logic error"); | |
| 149 | + return 0; | |
| 150 | + } | |
| 151 | + | |
| 146 | 152 | float compare(const Template &a, const Template &b) const |
| 147 | 153 | { |
| 148 | 154 | static const QString key("Partition"); // More efficient to preallocate this |
| ... | ... | @@ -163,6 +169,12 @@ class FilterDistance : public Distance |
| 163 | 169 | { |
| 164 | 170 | Q_OBJECT |
| 165 | 171 | |
| 172 | + float compare(const cv::Mat &, const cv::Mat &) const | |
| 173 | + { | |
| 174 | + qFatal("Logic error."); | |
| 175 | + return 0; | |
| 176 | + } | |
| 177 | + | |
| 166 | 178 | float compare(const Template &a, const Template &b) const |
| 167 | 179 | { |
| 168 | 180 | (void) b; // Query template isn't checked |
| ... | ... | @@ -197,6 +209,12 @@ class MetadataDistance : public Distance |
| 197 | 209 | Q_PROPERTY(QStringList filters READ get_filters WRITE set_filters RESET reset_filters STORED false) |
| 198 | 210 | BR_PROPERTY(QStringList, filters, QStringList()) |
| 199 | 211 | |
| 212 | + float compare(const cv::Mat &, const cv::Mat &) const | |
| 213 | + { | |
| 214 | + qFatal("Logic error."); | |
| 215 | + return 0; | |
| 216 | + } | |
| 217 | + | |
| 200 | 218 | float compare(const Template &a, const Template &b) const |
| 201 | 219 | { |
| 202 | 220 | foreach (const QString &key, filters) { |
| ... | ... | @@ -250,6 +268,12 @@ class RejectDistance : public Distance |
| 250 | 268 | Q_PROPERTY(bool rejectIfContains READ get_rejectIfContains WRITE set_rejectIfContains RESET reset_rejectIfContains STORED false) |
| 251 | 269 | BR_PROPERTY(bool, rejectIfContains, false) |
| 252 | 270 | |
| 271 | + float compare(const cv::Mat &, const cv::Mat &) const | |
| 272 | + { | |
| 273 | + qFatal("Logic error."); | |
| 274 | + return 0; | |
| 275 | + } | |
| 276 | + | |
| 253 | 277 | float compare(const Template &a, const Template &b) const |
| 254 | 278 | { |
| 255 | 279 | // We don't look at the query | ... | ... |