Commit 9ef4da29d32ee4979aa7d4c5db8e92ce8457485d
1 parent
bf179728
output impostor and genuine matches around the EER score threshold.
Showing
2 changed files
with
23 additions
and
39 deletions
openbr/core/eval.cpp
| @@ -155,10 +155,6 @@ float Evaluate(const Mat &simmat, const Mat &mask, const QString &csv, const QSt | @@ -155,10 +155,6 @@ float Evaluate(const Mat &simmat, const Mat &mask, const QString &csv, const QSt | ||
| 155 | 155 | ||
| 156 | float result = -1; | 156 | float result = -1; |
| 157 | 157 | ||
| 158 | - // Lists of top impostors and worst genuine | ||
| 159 | - QList<Comparison> topImpostors; topImpostors.reserve(matches); | ||
| 160 | - QList<Comparison> botGenuines; botGenuines.reserve(matches); | ||
| 161 | - | ||
| 162 | // Make comparisons | 158 | // Make comparisons |
| 163 | QList<Comparison> comparisons; comparisons.reserve(simmat.rows*simmat.cols); | 159 | QList<Comparison> comparisons; comparisons.reserve(simmat.rows*simmat.cols); |
| 164 | int genuineCount = 0, impostorCount = 0, numNaNs = 0; | 160 | int genuineCount = 0, impostorCount = 0, numNaNs = 0; |
| @@ -172,29 +168,8 @@ float Evaluate(const Mat &simmat, const Mat &mask, const QString &csv, const QSt | @@ -172,29 +168,8 @@ float Evaluate(const Mat &simmat, const Mat &mask, const QString &csv, const QSt | ||
| 172 | comparisons.append(comparison); | 168 | comparisons.append(comparison); |
| 173 | if (comparison.genuine) { | 169 | if (comparison.genuine) { |
| 174 | genuineCount++; | 170 | genuineCount++; |
| 175 | - if (matches != 0){ | ||
| 176 | - if (botGenuines.size() < (int)matches) { | ||
| 177 | - botGenuines.append(comparison); | ||
| 178 | - std::sort(botGenuines.begin(), botGenuines.end()); | ||
| 179 | - } else if (comparison.score < botGenuines.first().score) { | ||
| 180 | - botGenuines.removeFirst(); | ||
| 181 | - botGenuines.append(comparison); | ||
| 182 | - std::sort(botGenuines.begin(), botGenuines.end()); | ||
| 183 | - } | ||
| 184 | - } | ||
| 185 | } else { | 171 | } else { |
| 186 | impostorCount++; | 172 | impostorCount++; |
| 187 | - if (matches != 0) { | ||
| 188 | - if (topImpostors.size() < (int)matches) { | ||
| 189 | - topImpostors.append(comparison); | ||
| 190 | - std::sort(topImpostors.begin(), topImpostors.end()); | ||
| 191 | - } else if (topImpostors.last().score < comparison.score) { | ||
| 192 | - topImpostors.removeLast(); | ||
| 193 | - topImpostors.append(comparison); | ||
| 194 | - std::sort(topImpostors.begin(), topImpostors.end()); | ||
| 195 | - } | ||
| 196 | - } | ||
| 197 | - | ||
| 198 | } | 173 | } |
| 199 | } | 174 | } |
| 200 | } | 175 | } |
| @@ -214,6 +189,7 @@ float Evaluate(const Mat &simmat, const Mat &mask, const QString &csv, const QSt | @@ -214,6 +189,7 @@ float Evaluate(const Mat &simmat, const Mat &mask, const QString &csv, const QSt | ||
| 214 | int falsePositives = 0, previousFalsePositives = 0; | 189 | int falsePositives = 0, previousFalsePositives = 0; |
| 215 | int truePositives = 0, previousTruePositives = 0; | 190 | int truePositives = 0, previousTruePositives = 0; |
| 216 | int index = 0; | 191 | int index = 0; |
| 192 | + int EERIndex = 0; | ||
| 217 | float minGenuineScore = std::numeric_limits<float>::max(); | 193 | float minGenuineScore = std::numeric_limits<float>::max(); |
| 218 | float minImpostorScore = std::numeric_limits<float>::max(); | 194 | float minImpostorScore = std::numeric_limits<float>::max(); |
| 219 | 195 | ||
| @@ -246,6 +222,7 @@ float Evaluate(const Mat &simmat, const Mat &mask, const QString &csv, const QSt | @@ -246,6 +222,7 @@ float Evaluate(const Mat &simmat, const Mat &mask, const QString &csv, const QSt | ||
| 246 | if ((falsePositives > previousFalsePositives) && | 222 | if ((falsePositives > previousFalsePositives) && |
| 247 | (truePositives > previousTruePositives)) { | 223 | (truePositives > previousTruePositives)) { |
| 248 | operatingPoints.append(OperatingPoint(thresh, float(falsePositives)/impostorCount, float(truePositives)/genuineCount)); | 224 | operatingPoints.append(OperatingPoint(thresh, float(falsePositives)/impostorCount, float(truePositives)/genuineCount)); |
| 225 | + if (floor(float(falsePositives)/impostorCount*1000+0.5)/1000 == floor((1-float(truePositives)/genuineCount)*1000+0.5)/1000) EERIndex = index-1; | ||
| 249 | previousFalsePositives = falsePositives; | 226 | previousFalsePositives = falsePositives; |
| 250 | previousTruePositives = truePositives; | 227 | previousTruePositives = truePositives; |
| 251 | } | 228 | } |
| @@ -268,14 +245,21 @@ float Evaluate(const Mat &simmat, const Mat &mask, const QString &csv, const QSt | @@ -268,14 +245,21 @@ float Evaluate(const Mat &simmat, const Mat &mask, const QString &csv, const QSt | ||
| 268 | if (matches != 0) { | 245 | if (matches != 0) { |
| 269 | const FileList targetFiles = TemplateList::fromGallery(target).files(); | 246 | const FileList targetFiles = TemplateList::fromGallery(target).files(); |
| 270 | const FileList queryFiles = TemplateList::fromGallery(query).files(); | 247 | const FileList queryFiles = TemplateList::fromGallery(query).files(); |
| 271 | - for (int i=0; i<topImpostors.size(); i++) { | ||
| 272 | - lines.append("TI,"+QString::number(topImpostors[i].score)+","+targetFiles[topImpostors[i].target].get<QString>("Label")+":" | ||
| 273 | - +filePath+"/"+targetFiles[topImpostors[i].target].name+":"+queryFiles[topImpostors[i].query].get<QString>("Label")+":"+filePath+"/"+queryFiles[topImpostors[i].query].name); | 248 | + unsigned int count = 0; |
| 249 | + for (int i = EERIndex-1; i >= 0; i--) { | ||
| 250 | + if (comparisons[i].genuine) { | ||
| 251 | + lines.append("GM,"+QString::number(comparisons[i].score)+","+targetFiles[comparisons[i].target].get<QString>("Label")+":" | ||
| 252 | + +filePath+"/"+targetFiles[comparisons[i].target].name+":"+queryFiles[comparisons[i].query].get<QString>("Label")+":"+filePath+"/"+queryFiles[comparisons[i].query].name); | ||
| 253 | + if (++count == matches) break; | ||
| 254 | + } | ||
| 274 | } | 255 | } |
| 275 | - std::reverse(botGenuines.begin(), botGenuines.end()); | ||
| 276 | - for (int i=0; i<botGenuines.size(); i++) { | ||
| 277 | - lines.append("BG,"+QString::number(botGenuines[i].score)+","+targetFiles[botGenuines[i].target].get<QString>("Label")+":" | ||
| 278 | - +filePath+"/"+targetFiles[botGenuines[i].target].name+":"+queryFiles[botGenuines[i].query].get<QString>("Label")+":"+filePath+"/"+queryFiles[botGenuines[i].query].name); | 256 | + count = 0; |
| 257 | + for (int i = EERIndex+1; i < comparisons.size(); i++) { | ||
| 258 | + if (!comparisons[i].genuine) { | ||
| 259 | + lines.append("IM,"+QString::number(comparisons[i].score)+","+targetFiles[comparisons[i].target].get<QString>("Label")+":" | ||
| 260 | + +filePath+"/"+targetFiles[comparisons[i].target].name+":"+queryFiles[comparisons[i].query].get<QString>("Label")+":"+filePath+"/"+queryFiles[comparisons[i].query].name); | ||
| 261 | + if (++count == matches) break; | ||
| 262 | + } | ||
| 279 | } | 263 | } |
| 280 | } | 264 | } |
| 281 | 265 |
openbr/core/plot.cpp
| @@ -148,8 +148,8 @@ struct RPlot | @@ -148,8 +148,8 @@ struct RPlot | ||
| 148 | "# Split data into individual plots\n" | 148 | "# Split data into individual plots\n" |
| 149 | "plot_index = which(names(data)==\"Plot\")\n" | 149 | "plot_index = which(names(data)==\"Plot\")\n" |
| 150 | "Metadata <- data[grep(\"Metadata\",data$Plot),-c(1)]\n" | 150 | "Metadata <- data[grep(\"Metadata\",data$Plot),-c(1)]\n" |
| 151 | - "TI <- data[grep(\"TI\",data$Plot),-c(1)]\n" | ||
| 152 | - "BG <- data[grep(\"BG\",data$Plot),-c(1)]\n" | 151 | + "IM <- data[grep(\"IM\",data$Plot),-c(1)]\n" |
| 152 | + "GM <- data[grep(\"GM\",data$Plot),-c(1)]\n" | ||
| 153 | "DET <- data[grep(\"DET\",data$Plot),-c(1)]\n" | 153 | "DET <- data[grep(\"DET\",data$Plot),-c(1)]\n" |
| 154 | "FAR <- data[grep(\"FAR\",data$Plot),-c(1)]\n" | 154 | "FAR <- data[grep(\"FAR\",data$Plot),-c(1)]\n" |
| 155 | "FRR <- data[grep(\"FRR\",data$Plot),-c(1)]\n" | 155 | "FRR <- data[grep(\"FRR\",data$Plot),-c(1)]\n" |
| @@ -166,8 +166,8 @@ struct RPlot | @@ -166,8 +166,8 @@ struct RPlot | ||
| 166 | "\n" | 166 | "\n" |
| 167 | "# Format data\n" | 167 | "# Format data\n" |
| 168 | "Metadata$Y<-factor(Metadata$Y, levels=c(\"Genuine\",\"Impostor\",\"Ignored\",\"Gallery\",\"Probe\"))\n" | 168 | "Metadata$Y<-factor(Metadata$Y, levels=c(\"Genuine\",\"Impostor\",\"Ignored\",\"Gallery\",\"Probe\"))\n" |
| 169 | - "TI$Y <- as.character(TI$Y)\n" | ||
| 170 | - "BG$Y <- as.character(BG$Y)\n" | 169 | + "IM$Y <- as.character(IM$Y)\n" |
| 170 | + "GM$Y <- as.character(GM$Y)\n" | ||
| 171 | "DET$Y <- as.numeric(as.character(DET$Y))\n" | 171 | "DET$Y <- as.numeric(as.character(DET$Y))\n" |
| 172 | "ERR$Y <- as.numeric(as.character(ERR$Y))\n" | 172 | "ERR$Y <- as.numeric(as.character(ERR$Y))\n" |
| 173 | "SD$Y <- as.factor(unique(as.character(SD$Y)))\n" | 173 | "SD$Y <- as.factor(unique(as.character(SD$Y)))\n" |
| @@ -332,14 +332,14 @@ bool Plot(const QStringList &files, const File &destination, bool show) | @@ -332,14 +332,14 @@ bool Plot(const QStringList &files, const File &destination, bool show) | ||
| 332 | ((p.flip ? p.minor.size : p.major.size) > 1 ? QString(" + facet_wrap(~ %1, scales=\"free_x\")").arg(p.flip ? p.minor.header : p.major.header) : QString()) + | 332 | ((p.flip ? p.minor.size : p.major.size) > 1 ? QString(" + facet_wrap(~ %1, scales=\"free_x\")").arg(p.flip ? p.minor.header : p.major.header) : QString()) + |
| 333 | QString(" + theme(aspect.ratio=1)\n\n"))); | 333 | QString(" + theme(aspect.ratio=1)\n\n"))); |
| 334 | 334 | ||
| 335 | - p.file.write(qPrintable(QString("if (nrow(TI) != 0) {\n\tlibrary(jpeg)\n\tlibrary(png)\n\tlibrary(tiff)\n\tlibrary(grid)\n\t") + | 335 | + p.file.write(qPrintable(QString("if (nrow(IM) != 0) {\n\tlibrary(jpeg)\n\tlibrary(png)\n\tlibrary(grid)\n\t") + |
| 336 | QString("multiplot <- function(..., plotlist=NULL, cols) {\n\t") + | 336 | QString("multiplot <- function(..., plotlist=NULL, cols) {\n\t") + |
| 337 | QString("\trequire(grid)\n\n\t\t# Make a list from the ... arguments and plotlist\n\t\tplots <- c(list(...), plotlist)\n") + | 337 | QString("\trequire(grid)\n\n\t\t# Make a list from the ... arguments and plotlist\n\t\tplots <- c(list(...), plotlist)\n") + |
| 338 | QString("\t\tnumPlots = length(plots)\n\n\t\t# Make the panel\n\t\tplotCols = cols\n\t\tplotRows = ceiling(numPlots/plotCols)\n\n") + | 338 | QString("\t\tnumPlots = length(plots)\n\n\t\t# Make the panel\n\t\tplotCols = cols\n\t\tplotRows = ceiling(numPlots/plotCols)\n\n") + |
| 339 | QString("\t\t# Set up the page\n\t\tgrid.newpage()\n\t\tpushViewport(viewport(layout = grid.layout(plotRows, plotCols)))\n\t\tvplayout <- function(x, y)\n\t\t\tviewport(layout.pos.row = x, layout.pos.col = y)\n\n") + | 339 | QString("\t\t# Set up the page\n\t\tgrid.newpage()\n\t\tpushViewport(viewport(layout = grid.layout(plotRows, plotCols)))\n\t\tvplayout <- function(x, y)\n\t\t\tviewport(layout.pos.row = x, layout.pos.col = y)\n\n") + |
| 340 | QString("\t\t# Make each plot, in the correct location\n\t\tfor (i in 1:numPlots) {\n\t\t\tcurRow = ceiling(i/plotCols)\n\t\t\tcurCol = (i-1) %% plotCols + 1\n\t\t\tprint(plots[[i]], vp = vplayout(curRow, curCol))\n\t\t}\n\t}\n\n"))); | 340 | QString("\t\t# Make each plot, in the correct location\n\t\tfor (i in 1:numPlots) {\n\t\t\tcurRow = ceiling(i/plotCols)\n\t\t\tcurCol = (i-1) %% plotCols + 1\n\t\t\tprint(plots[[i]], vp = vplayout(curRow, curCol))\n\t\t}\n\t}\n\n"))); |
| 341 | 341 | ||
| 342 | - p.file.write(qPrintable(QString("\t# Print top impostor matches\n\tfor (i in 1:nrow(TI)) {\n\t\tscore <- TI[i,1]\n\t\tfiles <- TI[i,2]\n\t\talg <- TI[i,3]\n\t\tfiles <- unlist(strsplit(files, \"[:]\"))\n\n\t\text1 <- unlist(strsplit(files[2], \"[.]\"))[2]\n\t\text2 <- unlist(strsplit(files[4], \"[.]\"))[2]\n\t\t") + | 342 | + p.file.write(qPrintable(QString("\t# Print top impostor matches\n\tfor (i in 1:nrow(IM)) {\n\t\tscore <- IM[i,1]\n\t\tfiles <- IM[i,2]\n\t\talg <- IM[i,3]\n\t\tfiles <- unlist(strsplit(files, \"[:]\"))\n\n\t\text1 <- unlist(strsplit(files[2], \"[.]\"))[2]\n\t\text2 <- unlist(strsplit(files[4], \"[.]\"))[2]\n\t\t") + |
| 343 | QString("if (ext1 == \"jpg\" || ext1 == \"JPEG\" || ext1 == \"jpeg\" || ext1 == \"JPG\") {\n\t\t\timg1 <- readJPEG(files[2])\n\t\t} else if (ext1 == \"PNG\" || ext1 == \"png\") {\n\t\t\timg1 <- readPNG(files[2])\n\t\t} else if (ext1 == \"TIFF\" || ext1 == \"tiff\" || ext1 == \"TIF\" || ext1 == \"tif\") {\n\t\t\timg1 <- readTIFF(files[2])\n\t\t} else {\n\t\t\tnext\n\t\t}\n\t\tif (ext2 == \"jpg\" || ext2 == \"JPEG\" || ext2 == \"jpeg\" || ext2 == \"JPG\") {\n\t\t\timg2 <- readJPEG(files[4])\n\t\t} ") + | 343 | QString("if (ext1 == \"jpg\" || ext1 == \"JPEG\" || ext1 == \"jpeg\" || ext1 == \"JPG\") {\n\t\t\timg1 <- readJPEG(files[2])\n\t\t} else if (ext1 == \"PNG\" || ext1 == \"png\") {\n\t\t\timg1 <- readPNG(files[2])\n\t\t} else if (ext1 == \"TIFF\" || ext1 == \"tiff\" || ext1 == \"TIF\" || ext1 == \"tif\") {\n\t\t\timg1 <- readTIFF(files[2])\n\t\t} else {\n\t\t\tnext\n\t\t}\n\t\tif (ext2 == \"jpg\" || ext2 == \"JPEG\" || ext2 == \"jpeg\" || ext2 == \"JPG\") {\n\t\t\timg2 <- readJPEG(files[4])\n\t\t} ") + |
| 344 | QString("else if (ext2 == \"PNG\" || ext2 == \"png\") {\n\t\t\timg2 <- readPNG(files[4])\n\t\t} else if (ext2 == \"TIFF\" || ext2 == \"tiff\" || ext2 == \"TIF\" || ext2 == \"tif\") {\n\t\t\timg2 <- readTIFF(files[4])\n\t\t} else {\n\t\t\tnext\n\t\t}") + | 344 | QString("else if (ext2 == \"PNG\" || ext2 == \"png\") {\n\t\t\timg2 <- readPNG(files[4])\n\t\t} else if (ext2 == \"TIFF\" || ext2 == \"tiff\" || ext2 == \"TIF\" || ext2 == \"tif\") {\n\t\t\timg2 <- readTIFF(files[4])\n\t\t} else {\n\t\t\tnext\n\t\t}") + |
| 345 | QString("\n\t\tname1 <- files[1]\n\t\tname2 <- files[3]\n\n\t\tg1 <- rasterGrob(img1, interpolate=TRUE)\n\t\tg2 <- rasterGrob(img2, interpolate=TRUE)\n\n\t\t") + | 345 | QString("\n\t\tname1 <- files[1]\n\t\tname2 <- files[3]\n\n\t\tg1 <- rasterGrob(img1, interpolate=TRUE)\n\t\tg2 <- rasterGrob(img2, interpolate=TRUE)\n\n\t\t") + |
| @@ -347,7 +347,7 @@ bool Plot(const QStringList &files, const File &destination, bool show) | @@ -347,7 +347,7 @@ bool Plot(const QStringList &files, const File &destination, bool show) | ||
| 347 | QString("plot2 <- qplot(1:10, 1:10, geom=\"blank\") + annotation_custom(g2, xmin=-Inf, xmax=Inf, ymin=-Inf, ymax=Inf) + theme(axis.line=element_blank(), axis.text.x=element_blank(), axis.text.y=element_blank(), axis.ticks=element_blank(), panel.background=element_blank()) + labs(title=paste(\"Impostor score =\", score)) + ylab(unlist(strsplit(files[4], \"[/]\"))[length(unlist(strsplit(files[4], \"[/]\")))]) + xlab(name2)\n\n\t\t") + | 347 | QString("plot2 <- qplot(1:10, 1:10, geom=\"blank\") + annotation_custom(g2, xmin=-Inf, xmax=Inf, ymin=-Inf, ymax=Inf) + theme(axis.line=element_blank(), axis.text.x=element_blank(), axis.text.y=element_blank(), axis.ticks=element_blank(), panel.background=element_blank()) + labs(title=paste(\"Impostor score =\", score)) + ylab(unlist(strsplit(files[4], \"[/]\"))[length(unlist(strsplit(files[4], \"[/]\")))]) + xlab(name2)\n\n\t\t") + |
| 348 | QString("multiplot(plot1, plot2, cols=2)\n\t}"))); | 348 | QString("multiplot(plot1, plot2, cols=2)\n\t}"))); |
| 349 | 349 | ||
| 350 | - p.file.write(qPrintable(QString("\n\n\t# Print worst genuine matches\n\tfor (i in 1:nrow(BG)) {\n\t\tscore <- BG[i,1]\n\t\tfiles <- BG[i,2]\n\t\talg <- BG[i,3]\n\t\tfiles <- unlist(strsplit(files, \"[:]\"))\n\n\t\text1 <- unlist(strsplit(files[2], \"[.]\"))[2]\n\t\text2 <- unlist(strsplit(files[4], \"[.]\"))[2]\n\t\t") + | 350 | + p.file.write(qPrintable(QString("\n\n\t# Print worst genuine matches\n\tfor (i in 1:nrow(GM)) {\n\t\tscore <- GM[i,1]\n\t\tfiles <- GM[i,2]\n\t\talg <- GM[i,3]\n\t\tfiles <- unlist(strsplit(files, \"[:]\"))\n\n\t\text1 <- unlist(strsplit(files[2], \"[.]\"))[2]\n\t\text2 <- unlist(strsplit(files[4], \"[.]\"))[2]\n\t\t") + |
| 351 | QString("if (ext1 == \"jpg\" || ext1 == \"JPEG\" || ext1 == \"jpeg\" || ext1 == \"JPG\") {\n\t\t\timg1 <- readJPEG(files[2])\n\t\t} else if (ext1 == \"PNG\" || ext1 == \"png\") {\n\t\t\timg1 <- readPNG(files[2])\n\t\t} else if (ext1 == \"TIFF\" || ext1 == \"tiff\" || ext1 == \"TIF\" || ext1 == \"tif\") {\n\t\t\timg1 <- readTIFF(files[2])\n\t\t} else {\n\t\t\tnext\n\t\t}\n\t\tif (ext2 == \"jpg\" || ext2 == \"JPEG\" || ext2 == \"jpeg\" || ext2 == \"JPG\") {\n\t\t\timg2 <- readJPEG(files[4])\n\t\t} ") + | 351 | QString("if (ext1 == \"jpg\" || ext1 == \"JPEG\" || ext1 == \"jpeg\" || ext1 == \"JPG\") {\n\t\t\timg1 <- readJPEG(files[2])\n\t\t} else if (ext1 == \"PNG\" || ext1 == \"png\") {\n\t\t\timg1 <- readPNG(files[2])\n\t\t} else if (ext1 == \"TIFF\" || ext1 == \"tiff\" || ext1 == \"TIF\" || ext1 == \"tif\") {\n\t\t\timg1 <- readTIFF(files[2])\n\t\t} else {\n\t\t\tnext\n\t\t}\n\t\tif (ext2 == \"jpg\" || ext2 == \"JPEG\" || ext2 == \"jpeg\" || ext2 == \"JPG\") {\n\t\t\timg2 <- readJPEG(files[4])\n\t\t} ") + |
| 352 | QString("else if (ext2 == \"PNG\" || ext2 == \"png\") {\n\t\t\timg2 <- readPNG(files[4])\n\t\t} else if (ext2 == \"TIFF\" || ext2 == \"tiff\" || ext2 == \"TIF\" || ext2 == \"tif\") {\n\t\t\timg2 <- readTIFF(files[4])\n\t\t} else {\n\t\t\tnext\n\t\t}") + | 352 | QString("else if (ext2 == \"PNG\" || ext2 == \"png\") {\n\t\t\timg2 <- readPNG(files[4])\n\t\t} else if (ext2 == \"TIFF\" || ext2 == \"tiff\" || ext2 == \"TIF\" || ext2 == \"tif\") {\n\t\t\timg2 <- readTIFF(files[4])\n\t\t} else {\n\t\t\tnext\n\t\t}") + |
| 353 | QString("\n\t\tname1 <- files[1]\n\t\tname2 <- files[3]\n\n\t\tg1 <- rasterGrob(img1, interpolate=TRUE)\n\t\tg2 <- rasterGrob(img2, interpolate=TRUE)\n\n\t\t") + | 353 | QString("\n\t\tname1 <- files[1]\n\t\tname2 <- files[3]\n\n\t\tg1 <- rasterGrob(img1, interpolate=TRUE)\n\t\tg2 <- rasterGrob(img2, interpolate=TRUE)\n\n\t\t") + |