Commit 18d78e9c62de77bc28f2f3ff32c29d33c5060836
1 parent
4302eb9e
Switched fuse distance to operate on multiple distances and added an index parameter
Showing
1 changed file
with
16 additions
and
82 deletions
openbr/plugins/distance.cpp
| ... | ... | @@ -21,7 +21,6 @@ |
| 21 | 21 | #include <opencv2/imgproc/imgproc_c.h> |
| 22 | 22 | #include "openbr_internal.h" |
| 23 | 23 | |
| 24 | -#include "openbr/core/common.h" | |
| 25 | 24 | #include "openbr/core/distance_sse.h" |
| 26 | 25 | #include "openbr/core/qtutils.h" |
| 27 | 26 | #include "openbr/core/opencvutils.h" |
| ... | ... | @@ -191,9 +190,10 @@ class FuseDistance : public Distance |
| 191 | 190 | { |
| 192 | 191 | Q_OBJECT |
| 193 | 192 | Q_ENUMS(Operation) |
| 194 | - Q_PROPERTY(QString description READ get_description WRITE set_description RESET reset_description STORED false) | |
| 193 | + Q_PROPERTY(QStringList descriptions READ get_descriptions WRITE set_descriptions RESET reset_descriptions STORED false) | |
| 195 | 194 | Q_PROPERTY(Operation operation READ get_operation WRITE set_operation RESET reset_operation STORED false) |
| 196 | 195 | Q_PROPERTY(QList<float> weights READ get_weights WRITE set_weights RESET reset_weights STORED false) |
| 196 | + Q_PROPERTY(QList<int> indices READ get_indices WRITE set_indices RESET reset_indices STORED false) | |
| 197 | 197 | |
| 198 | 198 | QList<br::Distance*> distances; |
| 199 | 199 | |
| ... | ... | @@ -202,9 +202,10 @@ public: |
| 202 | 202 | enum Operation {Mean, Sum, Max, Min}; |
| 203 | 203 | |
| 204 | 204 | private: |
| 205 | - BR_PROPERTY(QString, description, "IdenticalDistance") | |
| 205 | + BR_PROPERTY(QStringList, descriptions, QStringList()) | |
| 206 | 206 | BR_PROPERTY(Operation, operation, Mean) |
| 207 | 207 | BR_PROPERTY(QList<float>, weights, QList<float>()) |
| 208 | + BR_PROPERTY(QList<int>, indices, QList<int>()) | |
| 208 | 209 | |
| 209 | 210 | void train(const TemplateList &src) |
| 210 | 211 | { |
| ... | ... | @@ -214,8 +215,14 @@ private: |
| 214 | 215 | |
| 215 | 216 | QList<TemplateList> partitionedSrc = src.partition(split); |
| 216 | 217 | |
| 217 | - while (distances.size() < partitionedSrc.size()) | |
| 218 | - distances.append(make(description)); | |
| 218 | + if (!indices.isEmpty()) | |
| 219 | + for (int i=partitionedSrc.size()-1; i>=0; i--) | |
| 220 | + if (!indices.contains(i)) partitionedSrc.removeAt(i); | |
| 221 | + | |
| 222 | + if (descriptions.size() != partitionedSrc.size()) qFatal("Incorrect number of distances supplied."); | |
| 223 | + | |
| 224 | + for (int i=0; i<descriptions.size(); i++) | |
| 225 | + distances.append(make(descriptions[i])); | |
| 219 | 226 | |
| 220 | 227 | // Train on each of the partitions |
| 221 | 228 | for (int i=0; i<distances.size(); i++) |
| ... | ... | @@ -228,9 +235,10 @@ private: |
| 228 | 235 | |
| 229 | 236 | QList<float> scores; |
| 230 | 237 | for (int i=0; i<distances.size(); i++) { |
| 238 | + int index = indices.isEmpty() ? i : indices[i]; | |
| 231 | 239 | float weight; |
| 232 | 240 | weights.isEmpty() ? weight = 1. : weight = weights[i]; |
| 233 | - scores.append(weight*distances[i]->compare(Template(a.file, a[i]),Template(b.file, b[i]))); | |
| 241 | + scores.append(weight*distances[i]->compare(Template(a.file, a[index]),Template(b.file, b[index]))); | |
| 234 | 242 | } |
| 235 | 243 | |
| 236 | 244 | switch (operation) { |
| ... | ... | @@ -253,17 +261,14 @@ private: |
| 253 | 261 | |
| 254 | 262 | void store(QDataStream &stream) const |
| 255 | 263 | { |
| 256 | - stream << distances.size(); | |
| 257 | 264 | foreach (Distance *distance, distances) |
| 258 | 265 | distance->store(stream); |
| 259 | 266 | } |
| 260 | 267 | |
| 261 | 268 | void load(QDataStream &stream) |
| 262 | 269 | { |
| 263 | - int numDistances; | |
| 264 | - stream >> numDistances; | |
| 265 | - while (distances.size() < numDistances) | |
| 266 | - distances.append(make(description)); | |
| 270 | + for (int i=0; i<descriptions.size(); i++) | |
| 271 | + distances.append(make(descriptions[i])); | |
| 267 | 272 | foreach (Distance *distance, distances) |
| 268 | 273 | distance->load(stream); |
| 269 | 274 | } |
| ... | ... | @@ -392,77 +397,6 @@ BR_REGISTER(Distance, OnlineDistance) |
| 392 | 397 | |
| 393 | 398 | /*! |
| 394 | 399 | * \ingroup distances |
| 395 | - * \brief Unmaps turk votes to be used in a distance | |
| 396 | - * \author Scott Klum \cite sklum | |
| 397 | - */ | |
| 398 | -class TurkDistance : public Distance | |
| 399 | -{ | |
| 400 | - Q_OBJECT | |
| 401 | - Q_PROPERTY(br::Distance* distance READ get_distance WRITE set_distance RESET reset_distance) | |
| 402 | - Q_PROPERTY(QString category READ get_category WRITE set_category RESET reset_category) | |
| 403 | - Q_PROPERTY(QStringList targetAttributes READ get_targetAttributes WRITE set_targetAttributes RESET reset_targetAttributes STORED false) | |
| 404 | - Q_PROPERTY(QStringList queryAttributes READ get_queryAttributes WRITE set_queryAttributes RESET reset_queryAttributes STORED false) | |
| 405 | - BR_PROPERTY(br::Distance*, distance, NULL) | |
| 406 | - BR_PROPERTY(QString, category, QString()) | |
| 407 | - BR_PROPERTY(QStringList, targetAttributes, QStringList()) | |
| 408 | - BR_PROPERTY(QStringList, queryAttributes, QStringList()) | |
| 409 | -; | |
| 410 | - float compare(const Template &target, const Template &query) const | |
| 411 | - { | |
| 412 | - Template t = unmap(target,category); | |
| 413 | - Template q = unmap(query,category); | |
| 414 | - | |
| 415 | - QList<float> targetValues, queryValues; | |
| 416 | - foreach(const QString &s, targetAttributes) targetValues.append(t.file.get<float>(s)); | |
| 417 | - foreach(const QString &s, queryAttributes) queryValues.append(q.file.get<float>(s)); | |
| 418 | - | |
| 419 | - float stddev = .75; | |
| 420 | - float score = 0; | |
| 421 | - for(int i=0; i<targetValues.size(); i++) score += 1./(stddev*sqrt(2*CV_PI))*exp(-0.5*pow((queryValues[i]-targetValues[i])/stddev, 2)); | |
| 422 | - | |
| 423 | - return score; | |
| 424 | - } | |
| 425 | - | |
| 426 | - Template unmap(const Template &t, const QString& variable) const { | |
| 427 | - // Create a new template matching the one containing the votes in the map structure | |
| 428 | - // but remove the map structure | |
| 429 | - Template expandedT = t; | |
| 430 | - expandedT.file.remove(variable); | |
| 431 | - | |
| 432 | - QMap<QString,QVariant> map = t.file.get<QMap<QString,QVariant> >(variable); | |
| 433 | - QMapIterator<QString, QVariant> i(map); | |
| 434 | - | |
| 435 | - while (i.hasNext()) { | |
| 436 | - i.next(); | |
| 437 | - float value = i.value().toFloat(); | |
| 438 | - expandedT.file.set(i.key(),value); | |
| 439 | - } | |
| 440 | - | |
| 441 | - return expandedT; | |
| 442 | - } | |
| 443 | -}; | |
| 444 | - | |
| 445 | -BR_REGISTER(Distance, TurkDistance) | |
| 446 | - | |
| 447 | -/*! | |
| 448 | - * \ingroup distances | |
| 449 | - * \brief Attenuation function based distance | |
| 450 | - * \author Scott Klum \cite sklum | |
| 451 | - */ | |
| 452 | -class AttenuationDistance : public Distance | |
| 453 | -{ | |
| 454 | - Q_OBJECT | |
| 455 | -; | |
| 456 | - float compare(const Template &target, const Template &query) const | |
| 457 | - { | |
| 458 | - return 1; | |
| 459 | - } | |
| 460 | -}; | |
| 461 | - | |
| 462 | -BR_REGISTER(Distance, AttenuationDistance) | |
| 463 | - | |
| 464 | -/*! | |
| 465 | - * \ingroup distances | |
| 466 | 400 | * \brief Sum match scores across multiple distances |
| 467 | 401 | * \author Scott Klum \cite sklum |
| 468 | 402 | */ | ... | ... |