Commit 96d366718d9991a7869423b052e7d735d6405d5a
1 parent
18d78e9c
Updated Turk workflow
Showing
2 changed files
with
75 additions
and
33 deletions
openbr/plugins/independent.cpp
| ... | ... | @@ -11,14 +11,11 @@ namespace br |
| 11 | 11 | |
| 12 | 12 | static TemplateList Downsample(const TemplateList &templates, int classes, int instances, float fraction, const QString & inputVariable, const QStringList &gallery) |
| 13 | 13 | { |
| 14 | - QString keepKey = "baggy"; | |
| 15 | - | |
| 16 | 14 | // Return early when no downsampling is required |
| 17 | 15 | if ((classes == std::numeric_limits<int>::max()) && |
| 18 | 16 | (instances == std::numeric_limits<int>::max()) && |
| 19 | 17 | (fraction >= 1) && |
| 20 | - (gallery.isEmpty()) && | |
| 21 | - (keepKey.isEmpty())) | |
| 18 | + (gallery.isEmpty())) | |
| 22 | 19 | return templates; |
| 23 | 20 | |
| 24 | 21 | const bool atLeast = instances < 0; | ... | ... |
openbr/plugins/turk.cpp
| ... | ... | @@ -3,50 +3,53 @@ |
| 3 | 3 | namespace br |
| 4 | 4 | { |
| 5 | 5 | |
| 6 | +static Template unmap(const Template &t, const QString& variable, const float maxVotes, const float maxRange, const float minRange, const bool classify, const bool consensusOnly) { | |
| 7 | + // Create a new template matching the one containing the votes in the map structure | |
| 8 | + // but remove the map structure | |
| 9 | + Template expandedT = t; | |
| 10 | + expandedT.file.remove(variable); | |
| 11 | + | |
| 12 | + QMap<QString,QVariant> map = t.file.get<QMap<QString,QVariant> >(variable); | |
| 13 | + QMapIterator<QString, QVariant> i(map); | |
| 14 | + bool ok; | |
| 15 | + | |
| 16 | + while (i.hasNext()) { | |
| 17 | + i.next(); | |
| 18 | + // Normalize to [minRange,maxRange] | |
| 19 | + float value = i.value().toFloat(&ok)*(maxRange-minRange)/maxVotes - minRange; | |
| 20 | + if (!ok) qFatal("Failed to expand Turk votes for %s", variable); | |
| 21 | + if (classify) (value > maxRange-((maxRange-minRange)/2)) ? value = maxRange : value = minRange; | |
| 22 | + else if (consensusOnly && (value != maxRange && value != minRange)) continue; | |
| 23 | + expandedT.file.set(i.key(),value); | |
| 24 | + } | |
| 25 | + | |
| 26 | + return expandedT; | |
| 27 | +} | |
| 28 | + | |
| 6 | 29 | /*! |
| 7 | 30 | * \ingroup transforms |
| 8 | 31 | * \brief Converts Amazon MTurk labels to a non-map format for use in a transform |
| 9 | - * Also optionally normalizes and/or classifies the votes | |
| 10 | 32 | * \author Scott Klum \cite sklum |
| 11 | 33 | */ |
| 12 | 34 | class TurkTransform : public UntrainableTransform |
| 13 | 35 | { |
| 14 | 36 | Q_OBJECT |
| 15 | - Q_PROPERTY(QString inputVariable READ get_inputVariable WRITE set_inputVariable RESET reset_inputVariable STORED false) | |
| 37 | + Q_PROPERTY(QString HIT READ get_HIT WRITE set_HIT RESET reset_HIT STORED false) | |
| 16 | 38 | Q_PROPERTY(float maxVotes READ get_maxVotes WRITE set_maxVotes RESET reset_maxVotes STORED false) |
| 39 | + Q_PROPERTY(float maxRange READ get_maxRange WRITE set_maxRange RESET reset_maxRange STORED false) | |
| 40 | + Q_PROPERTY(float minRange READ get_minRange WRITE set_minRange RESET reset_minRange STORED false) | |
| 17 | 41 | Q_PROPERTY(bool classify READ get_classify WRITE set_classify RESET reset_classify STORED false) |
| 18 | 42 | Q_PROPERTY(bool consensusOnly READ get_consensusOnly WRITE set_consensusOnly RESET reset_consensusOnly STORED false) |
| 19 | - BR_PROPERTY(QString, inputVariable, QString()) | |
| 20 | - BR_PROPERTY(float, maxVotes, 1.) | |
| 43 | + BR_PROPERTY(QString, HIT, QString()) | |
| 44 | + BR_PROPERTY(float, maxVotes, 1) | |
| 45 | + BR_PROPERTY(float, maxRange, 1) | |
| 46 | + BR_PROPERTY(float, minRange, 0) | |
| 21 | 47 | BR_PROPERTY(bool, classify, false) |
| 22 | 48 | BR_PROPERTY(bool, consensusOnly, false) |
| 23 | 49 | |
| 24 | 50 | void project(const Template &src, Template &dst) const |
| 25 | 51 | { |
| 26 | - dst = unmap(src); | |
| 27 | - } | |
| 28 | - | |
| 29 | - Template unmap(const Template &t) const { | |
| 30 | - // Create a new template matching the one containing the votes in the map structure | |
| 31 | - // but remove the map structure | |
| 32 | - Template expandedT = t; | |
| 33 | - expandedT.file.remove(inputVariable); | |
| 34 | - | |
| 35 | - QMap<QString,QVariant> map = t.file.get<QMap<QString,QVariant> >(inputVariable); | |
| 36 | - QMapIterator<QString, QVariant> i(map); | |
| 37 | - bool ok; | |
| 38 | - | |
| 39 | - while (i.hasNext()) { | |
| 40 | - i.next(); | |
| 41 | - // Normalize to [-1,1] | |
| 42 | - float value = i.value().toFloat(&ok)/maxVotes;//* 2./maxVotes - 1; | |
| 43 | - if (!ok) qFatal("Failed to expand Turk votes for %s", inputVariable); | |
| 44 | - if (classify) (value > 0) ? value = 1 : value = -1; | |
| 45 | - else if (consensusOnly && (value != 1 && value != -1)) continue; | |
| 46 | - expandedT.file.set(i.key(),value); | |
| 47 | - } | |
| 48 | - | |
| 49 | - return expandedT; | |
| 52 | + dst = unmap(src, HIT, maxVotes, maxRange, minRange, classify, consensusOnly); | |
| 50 | 53 | } |
| 51 | 54 | }; |
| 52 | 55 | |
| ... | ... | @@ -79,7 +82,7 @@ class MapTransform : public UntrainableTransform |
| 79 | 82 | // converted to the type T. For some reason, you cannot |
| 80 | 83 | // convert from a QVariant to a QVariant. Thus, this transform |
| 81 | 84 | // has to assume that the metadata we want to organize can be |
| 82 | - // converted to a float, resulting in a loss of generality :(. | |
| 85 | + // converted to a float, resulting in a loss of generality :-(. | |
| 83 | 86 | if (t.file.contains(s)) { |
| 84 | 87 | map.insert(s,t.file.get<float>(s)); |
| 85 | 88 | mappedT.file.remove(s); |
| ... | ... | @@ -94,6 +97,48 @@ class MapTransform : public UntrainableTransform |
| 94 | 97 | |
| 95 | 98 | BR_REGISTER(Transform, MapTransform) |
| 96 | 99 | |
| 100 | + | |
| 101 | +/*! | |
| 102 | + * \ingroup distances | |
| 103 | + * \brief Unmaps Turk HITs to be compared against query mats | |
| 104 | + * \author Scott Klum \cite sklum | |
| 105 | + */ | |
| 106 | +class TurkDistance : public Distance | |
| 107 | +{ | |
| 108 | + Q_OBJECT | |
| 109 | + Q_PROPERTY(QString HIT READ get_HIT WRITE set_HIT RESET reset_HIT) | |
| 110 | + Q_PROPERTY(QStringList keys READ get_keys WRITE set_keys RESET reset_keys STORED false) | |
| 111 | + Q_PROPERTY(float maxVotes READ get_maxVotes WRITE set_maxVotes RESET reset_maxVotes STORED false) | |
| 112 | + Q_PROPERTY(float maxRange READ get_maxRange WRITE set_maxRange RESET reset_maxRange STORED false) | |
| 113 | + Q_PROPERTY(float minRange READ get_minRange WRITE set_minRange RESET reset_minRange STORED false) | |
| 114 | + Q_PROPERTY(bool classify READ get_classify WRITE set_classify RESET reset_classify STORED false) | |
| 115 | + Q_PROPERTY(bool consensusOnly READ get_consensusOnly WRITE set_consensusOnly RESET reset_consensusOnly STORED false) | |
| 116 | + BR_PROPERTY(QString, HIT, QString()) | |
| 117 | + BR_PROPERTY(QStringList, keys, QStringList()) | |
| 118 | + BR_PROPERTY(float, maxVotes, 1) | |
| 119 | + BR_PROPERTY(float, maxRange, 1) | |
| 120 | + BR_PROPERTY(float, minRange, 0) | |
| 121 | + BR_PROPERTY(bool, classify, false) | |
| 122 | + BR_PROPERTY(bool, consensusOnly, false) | |
| 123 | + | |
| 124 | + float compare(const Template &target, const Template &query) const | |
| 125 | + { | |
| 126 | + Template t = unmap(target, HIT, maxVotes, maxRange, minRange, classify, consensusOnly); | |
| 127 | + | |
| 128 | + QList<float> targetValues; | |
| 129 | + foreach(const QString &s, keys) targetValues.append(t.file.get<float>(s)); | |
| 130 | + | |
| 131 | + float stddev = .75; | |
| 132 | + | |
| 133 | + float score = 0; | |
| 134 | + for (int i=0; i<targetValues.size(); i++) score += 1/(stddev*sqrt(2*CV_PI))*exp(-0.5*pow((query.m().at<float>(0,i)-targetValues[i])/stddev, 2)); | |
| 135 | + | |
| 136 | + return score; | |
| 137 | + } | |
| 138 | +}; | |
| 139 | + | |
| 140 | +BR_REGISTER(Distance, TurkDistance) | |
| 141 | + | |
| 97 | 142 | } // namespace br |
| 98 | 143 | |
| 99 | 144 | #include "turk.moc" | ... | ... |