Commit cc33a4ef4e309c2e352f7ac225069217d065c98c
1 parent
77617214
Added CMC table to plot.cpp, factored out CMC code to getCMC() in eval.cpp
Showing
2 changed files
with
35 additions
and
14 deletions
openbr/core/eval.cpp
| @@ -66,6 +66,19 @@ static float getTAR(const QList<OperatingPoint> &operatingPoints, float FAR) | @@ -66,6 +66,19 @@ static float getTAR(const QList<OperatingPoint> &operatingPoints, float FAR) | ||
| 66 | return m * FAR + b; | 66 | return m * FAR + b; |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | +static float getCMC(const QVector<int> &firstGenuineReturns, int rank) | ||
| 70 | +{ | ||
| 71 | + int realizedReturns = 0, possibleReturns = 0; | ||
| 72 | + foreach (int firstGenuineReturn, firstGenuineReturns) { | ||
| 73 | + if (firstGenuineReturn > 0) { | ||
| 74 | + possibleReturns++; | ||
| 75 | + if (firstGenuineReturn <= rank) realizedReturns++; | ||
| 76 | + } | ||
| 77 | + } | ||
| 78 | + const float retrievalRate = float(realizedReturns)/possibleReturns; | ||
| 79 | + return retrievalRate; | ||
| 80 | +} | ||
| 81 | + | ||
| 69 | // Decide whether to construct a normal mask matrix, or a pairwise mask by comparing the dimensions of | 82 | // Decide whether to construct a normal mask matrix, or a pairwise mask by comparing the dimensions of |
| 70 | // scores with the size of the target and query lists | 83 | // scores with the size of the target and query lists |
| 71 | static cv::Mat constructMatchingMask(const cv::Mat &scores, const FileList &target, const FileList &query, int partition=0) | 84 | static cv::Mat constructMatchingMask(const cv::Mat &scores, const FileList &target, const FileList &query, int partition=0) |
| @@ -240,6 +253,14 @@ float Evaluate(const Mat &simmat, const Mat &mask, const QString &csv) | @@ -240,6 +253,14 @@ float Evaluate(const Mat &simmat, const Mat &mask, const QString &csv) | ||
| 240 | lines.append(qPrintable(QString("FT,0.01,%1").arg(QString::number(getTAR(operatingPoints, 0.01), 'f', 3)))); | 253 | lines.append(qPrintable(QString("FT,0.01,%1").arg(QString::number(getTAR(operatingPoints, 0.01), 'f', 3)))); |
| 241 | lines.append(qPrintable(QString("FT,0.1,%1").arg(QString::number(getTAR(operatingPoints, 0.1), 'f', 3)))); | 254 | lines.append(qPrintable(QString("FT,0.1,%1").arg(QString::number(getTAR(operatingPoints, 0.1), 'f', 3)))); |
| 242 | 255 | ||
| 256 | + //Write CMC Table (CT) | ||
| 257 | + lines.append(qPrintable(QString("CT,1,%1").arg(QString::number(getCMC(firstGenuineReturns, 1), 'f', 3)))); | ||
| 258 | + lines.append(qPrintable(QString("CT,5,%1").arg(QString::number(getCMC(firstGenuineReturns, 5), 'f', 3)))); | ||
| 259 | + lines.append(qPrintable(QString("CT,10,%1").arg(QString::number(getCMC(firstGenuineReturns, 10), 'f', 3)))); | ||
| 260 | + lines.append(qPrintable(QString("CT,20,%1").arg(QString::number(getCMC(firstGenuineReturns, 20), 'f', 3)))); | ||
| 261 | + lines.append(qPrintable(QString("CT,50,%1").arg(QString::number(getCMC(firstGenuineReturns, 50), 'f', 3)))); | ||
| 262 | + lines.append(qPrintable(QString("CT,100,%1").arg(QString::number(getCMC(firstGenuineReturns, 100), 'f', 3)))); | ||
| 263 | + | ||
| 243 | // Write FAR/TAR Bar Chart (BC) | 264 | // Write FAR/TAR Bar Chart (BC) |
| 244 | lines.append(qPrintable(QString("BC,0.001,%1").arg(QString::number(getTAR(operatingPoints, 0.001), 'f', 3)))); | 265 | lines.append(qPrintable(QString("BC,0.001,%1").arg(QString::number(getTAR(operatingPoints, 0.001), 'f', 3)))); |
| 245 | lines.append(qPrintable(QString("BC,0.01,%1").arg(QString::number(result = getTAR(operatingPoints, 0.01), 'f', 3)))); | 266 | lines.append(qPrintable(QString("BC,0.01,%1").arg(QString::number(result = getTAR(operatingPoints, 0.01), 'f', 3)))); |
| @@ -265,23 +286,13 @@ float Evaluate(const Mat &simmat, const Mat &mask, const QString &csv) | @@ -265,23 +286,13 @@ float Evaluate(const Mat &simmat, const Mat &mask, const QString &csv) | ||
| 265 | // Write Cumulative Match Characteristic (CMC) curve | 286 | // Write Cumulative Match Characteristic (CMC) curve |
| 266 | const int Max_Retrieval = 200; | 287 | const int Max_Retrieval = 200; |
| 267 | const int Report_Retrieval = 5; | 288 | const int Report_Retrieval = 5; |
| 268 | - | ||
| 269 | - float reportRetrievalRate = -1; | ||
| 270 | for (int i=1; i<=Max_Retrieval; i++) { | 289 | for (int i=1; i<=Max_Retrieval; i++) { |
| 271 | - int realizedReturns = 0, possibleReturns = 0; | ||
| 272 | - foreach (int firstGenuineReturn, firstGenuineReturns) { | ||
| 273 | - if (firstGenuineReturn > 0) { | ||
| 274 | - possibleReturns++; | ||
| 275 | - if (firstGenuineReturn <= i) realizedReturns++; | ||
| 276 | - } | ||
| 277 | - } | ||
| 278 | - const float retrievalRate = float(realizedReturns)/possibleReturns; | 290 | + const float retrievalRate = getCMC(firstGenuineReturns, i); |
| 279 | lines.append(qPrintable(QString("CMC,%1,%2").arg(QString::number(i), QString::number(retrievalRate)))); | 291 | lines.append(qPrintable(QString("CMC,%1,%2").arg(QString::number(i), QString::number(retrievalRate)))); |
| 280 | - if (i == Report_Retrieval) reportRetrievalRate = retrievalRate; | ||
| 281 | } | 292 | } |
| 282 | 293 | ||
| 283 | QtUtils::writeFile(csv, lines); | 294 | QtUtils::writeFile(csv, lines); |
| 284 | - qDebug("TAR @ FAR = 0.01: %.3f\nRetrieval Rate @ Rank = %d: %.3f", result, Report_Retrieval, reportRetrievalRate); | 295 | + qDebug("TAR @ FAR = 0.01: %.3f\nRetrieval Rate @ Rank = %d: %.3f", result, Report_Retrieval, getCMC(firstGenuineReturns, Report_Retrieval)); |
| 285 | return result; | 296 | return result; |
| 286 | } | 297 | } |
| 287 | 298 |
openbr/core/plot.cpp
| @@ -135,6 +135,7 @@ struct RPlot | @@ -135,6 +135,7 @@ struct RPlot | ||
| 135 | "FRR <- data[grep(\"FRR\",data$Plot),-c(1)]\n" | 135 | "FRR <- data[grep(\"FRR\",data$Plot),-c(1)]\n" |
| 136 | "SD <- data[grep(\"SD\",data$Plot),-c(1)]\n" | 136 | "SD <- data[grep(\"SD\",data$Plot),-c(1)]\n" |
| 137 | "FT <- data[grep(\"FT\",data$Plot),-c(1)]\n" | 137 | "FT <- data[grep(\"FT\",data$Plot),-c(1)]\n" |
| 138 | + "CT <- data[grep(\"CT\",data$Plot),-c(1)]\n" | ||
| 138 | "BC <- data[grep(\"BC\",data$Plot),-c(1)]\n" | 139 | "BC <- data[grep(\"BC\",data$Plot),-c(1)]\n" |
| 139 | "CMC <- data[grep(\"CMC\",data$Plot),-c(1)]\n" | 140 | "CMC <- data[grep(\"CMC\",data$Plot),-c(1)]\n" |
| 140 | "FAR$Error <- \"FAR\"\n" | 141 | "FAR$Error <- \"FAR\"\n" |
| @@ -148,6 +149,7 @@ struct RPlot | @@ -148,6 +149,7 @@ struct RPlot | ||
| 148 | "ERR$Y <- as.numeric(as.character(ERR$Y))\n" | 149 | "ERR$Y <- as.numeric(as.character(ERR$Y))\n" |
| 149 | "SD$Y <- as.factor(unique(as.character(SD$Y)))\n" | 150 | "SD$Y <- as.factor(unique(as.character(SD$Y)))\n" |
| 150 | "FT$Y <- as.numeric(as.character(FT$Y))\n" | 151 | "FT$Y <- as.numeric(as.character(FT$Y))\n" |
| 152 | + "CT$Y <- as.numeric(as.character(CT$Y))\n" | ||
| 151 | "BC$Y <- as.numeric(as.character(BC$Y))\n" | 153 | "BC$Y <- as.numeric(as.character(BC$Y))\n" |
| 152 | "CMC$Y <- as.numeric(as.character(CMC$Y))\n" | 154 | "CMC$Y <- as.numeric(as.character(CMC$Y))\n" |
| 153 | "\n" | 155 | "\n" |
| @@ -161,7 +163,13 @@ struct RPlot | @@ -161,7 +163,13 @@ struct RPlot | ||
| 161 | "mat <- matrix(FT$Y,nrow=6,ncol=length(algs),byrow=FALSE)\n" | 163 | "mat <- matrix(FT$Y,nrow=6,ncol=length(algs),byrow=FALSE)\n" |
| 162 | "colnames(mat) <- algs \n" | 164 | "colnames(mat) <- algs \n" |
| 163 | "rownames(mat) <- c(\"FAR = 1e-06\", \"FAR = 1e-05\", \"FAR = 1e-04\", \"FAR = 1e-03\", \"FAR = 1e-02\", \"FAR = 1e-01\")\n" | 165 | "rownames(mat) <- c(\"FAR = 1e-06\", \"FAR = 1e-05\", \"FAR = 1e-04\", \"FAR = 1e-03\", \"FAR = 1e-02\", \"FAR = 1e-01\")\n" |
| 164 | - "table <- as.table(mat)\n"); | 166 | + "FTtable <- as.table(mat)\n" |
| 167 | + "\n" | ||
| 168 | + "# Code to format CMC Table\n" | ||
| 169 | + "mat <- matrix(CT$Y,nrow=6,ncol=length(algs),byrow=FALSE)\n" | ||
| 170 | + "colnames(mat) <- algs \n" | ||
| 171 | + "rownames(mat) <- c(\" Rank 1\", \"Rank 5\", \"Rank 10\", \"Rank 20\", \"Rank 50\", \"Rank 100\")\n" | ||
| 172 | + "CMCtable <- as.table(mat)\n"); | ||
| 165 | 173 | ||
| 166 | // Open output device | 174 | // Open output device |
| 167 | file.write(qPrintable(QString("\n" | 175 | file.write(qPrintable(QString("\n" |
| @@ -189,8 +197,10 @@ struct RPlot | @@ -189,8 +197,10 @@ struct RPlot | ||
| 189 | "plot.new()\n" | 197 | "plot.new()\n" |
| 190 | "print(title(\"Gallery * Probe = Genuine + Impostor + Ignored\"))\n" | 198 | "print(title(\"Gallery * Probe = Genuine + Impostor + Ignored\"))\n" |
| 191 | "plot.new()\n" | 199 | "plot.new()\n" |
| 200 | + "print(textplot(FTtable,cex=1))\n" | ||
| 192 | "print(title(\"Table of True Accept Rates at various False Accept Rates\"))\n" | 201 | "print(title(\"Table of True Accept Rates at various False Accept Rates\"))\n" |
| 193 | - "print(textplot(table,valign=\"top\",cex=1))\n"; | 202 | + "print(textplot(CMCtable,cex=1))\n" |
| 203 | + "print(title(\"Table of retrieval rate at various ranks\"))\n"; | ||
| 194 | file.write(qPrintable(textplot.arg(PRODUCT_NAME, PRODUCT_VERSION))); | 204 | file.write(qPrintable(textplot.arg(PRODUCT_NAME, PRODUCT_VERSION))); |
| 195 | } | 205 | } |
| 196 | 206 |