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 | 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 | ... | ... |