Commit f00e00ece30cbaeb7a872075507bf3554197a89c

Authored by Scott Klum
1 parent 1978c25b

Added ZScore distance

Showing 1 changed file with 59 additions and 0 deletions
openbr/plugins/quality.cpp
... ... @@ -211,6 +211,65 @@ protected:
211 211  
212 212 BR_REGISTER(Distance, MatchProbabilityDistance)
213 213  
  214 +class ZScoreDistance : public Distance
  215 +{
  216 + Q_OBJECT
  217 + Q_PROPERTY(br::Distance* distance READ get_distance WRITE set_distance RESET reset_distance STORED false)
  218 + Q_PROPERTY(bool crossModality READ get_crossModality WRITE set_crossModality RESET reset_crossModality STORED false)
  219 + BR_PROPERTY(br::Distance*, distance, make("Dist(L2)"))
  220 + BR_PROPERTY(bool, crossModality, false)
  221 +
  222 + float min, max;
  223 + double mean, stddev;
  224 +
  225 + void train(const TemplateList &src)
  226 + {
  227 + distance->train(src);
  228 +
  229 + QScopedPointer<MatrixOutput> matrixOutput(MatrixOutput::make(FileList(src.size()), FileList(src.size())));
  230 + distance->compare(src, src, matrixOutput.data());
  231 +
  232 + QList<float> scores;
  233 + scores.reserve(src.size()*src.size());
  234 + for (int i=0; i<src.size(); i++) {
  235 + for (int j=0; j<i; j++) {
  236 + const float score = matrixOutput.data()->data.at<float>(i, j);
  237 + if (score == -std::numeric_limits<float>::max()) continue;
  238 + if (crossModality && src[i].file.get<QString>("MODALITY") == src[j].file.get<QString>("MODALITY")) continue;
  239 + scores.append(score);
  240 + }
  241 + }
  242 +
  243 + Common::MinMax(scores, &min, &max);
  244 + Common::MeanStdDev(scores, &mean, &stddev);
  245 +
  246 + if (stddev == 0) qFatal("Stddev is 0.");
  247 + }
  248 +
  249 + float compare(const Template &target, const Template &query) const
  250 + {
  251 + float score = distance->compare(target,query);
  252 + if (score == -std::numeric_limits<float>::max()) score = (min - mean) / stddev;
  253 + else if (score == std::numeric_limits<float>::max()) score = (max - mean) / stddev;
  254 + else score = (score - mean) / stddev;
  255 + return score;
  256 + }
  257 +
  258 + void store(QDataStream &stream) const
  259 + {
  260 + distance->store(stream);
  261 + stream << min << max << mean << stddev;
  262 + }
  263 +
  264 + void load(QDataStream &stream)
  265 + {
  266 + distance->load(stream);
  267 + stream >> min >> max >> mean >> stddev;
  268 + }
  269 +};
  270 +
  271 +BR_REGISTER(Distance, ZScoreDistance)
  272 +
214 273 /*!
215 274 * \ingroup distances
216 275 * \brief Match Probability modification for heat maps \cite klare12
... ...