Commit f00e00ece30cbaeb7a872075507bf3554197a89c
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,6 +211,65 @@ protected: | ||
| 211 | 211 | ||
| 212 | BR_REGISTER(Distance, MatchProbabilityDistance) | 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 | * \ingroup distances | 274 | * \ingroup distances |
| 216 | * \brief Match Probability modification for heat maps \cite klare12 | 275 | * \brief Match Probability modification for heat maps \cite klare12 |