Add statistics tables at the end of a run

This commit is contained in:
Ben 2022-01-17 14:19:41 +01:00
parent aaa4bf055a
commit 34f08f4195
Signed by: ben
GPG key ID: 0F54A7ED232D3319

View file

@ -12,6 +12,7 @@ import java.io.FileNotFoundException
import java.nio.file.FileSystemNotFoundException import java.nio.file.FileSystemNotFoundException
import java.nio.file.Path import java.nio.file.Path
import java.nio.file.Paths import java.nio.file.Paths
import java.util.*
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.Executors import java.util.concurrent.Executors
import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicBoolean
@ -22,6 +23,8 @@ import kotlin.system.exitProcess
import kotlin.time.Duration import kotlin.time.Duration
import kotlin.time.Duration.Companion.seconds import kotlin.time.Duration.Companion.seconds
internal const val FALSE_HIT = "False hit"
internal const val MULTIPLE = "Multiple"
internal const val HIST_SIZE = 256 internal const val HIST_SIZE = 256
internal const val FOREGROUND_THRESHOLD = 120.0f internal const val FOREGROUND_THRESHOLD = 120.0f
internal const val GAUSSIAN_KERNEL_SIZE = 3 internal const val GAUSSIAN_KERNEL_SIZE = 3
@ -254,6 +257,7 @@ private suspend fun findGoldenPoIAnimate(
suspend fun main(args: Array<String>) { suspend fun main(args: Array<String>) {
CvContext.initialize() CvContext.initialize()
val imageDirectory = Path(args.getOrElse(0) { "." }) val imageDirectory = Path(args.getOrElse(0) { "." })
val totals = HashMap<String, Int>()
val comparisonData = imageDirectory.resolve("export_data.csv").bufferedReader().lineSequence().drop(1) val comparisonData = imageDirectory.resolve("export_data.csv").bufferedReader().lineSequence().drop(1)
.map { line -> line.trimEnd().split(",") } .map { line -> line.trimEnd().split(",") }
.groupingBy { parts -> parts[0] } .groupingBy { parts -> parts[0] }
@ -264,11 +268,12 @@ suspend fun main(args: Array<String>) {
parts[3].toInt() - parts[1].toInt() + 1, parts[3].toInt() - parts[1].toInt() + 1,
parts[4].toInt() - parts[2].toInt() + 1, parts[4].toInt() - parts[2].toInt() + 1,
) )
totals.compute(descriptionToRect.first) { _, count -> (count ?: 0) + 1 }
(accumulator ?: mutableListOf()).apply { add(descriptionToRect) } (accumulator ?: mutableListOf()).apply { add(descriptionToRect) }
} }
val hits = AtomicInteger(0) val statistics: Map<String, Map<String, AtomicInteger>> = (totals.keys + FALSE_HIT + MULTIPLE).associateWith {
val falseHit = AtomicInteger(0) totals.keys.associateWith { AtomicInteger(0) }
val count = AtomicInteger(0) }
val imagePaths = imageDirectory.listDirectoryEntries("*.bmp") val imagePaths = imageDirectory.listDirectoryEntries("*.bmp")
val perImageWindow = WINDOW_MANAGER_FACTORY.createWindowManager("Current Image") val perImageWindow = WINDOW_MANAGER_FACTORY.createWindowManager("Current Image")
val scanner = EntityScanner(animate = false, scanBarSpacing = 6, foregroundThreshold = FOREGROUND_THRESHOLD) val scanner = EntityScanner(animate = false, scanBarSpacing = 6, foregroundThreshold = FOREGROUND_THRESHOLD)
@ -419,19 +424,20 @@ suspend fun main(args: Array<String>) {
} }
} }
.collect { result -> .collect { result ->
count.incrementAndGet() val matchingResults = result.third.filter { (_, comparisonRect) ->
val matchingResults = result.third.filter { (description, comparisonRect) -> (comparisonRect.contains(result.second.tl()) &&
description == result.first && comparisonRect.contains(result.second.br())) ||
(comparisonRect.contains(result.second.tl()) && (result.second.contains(comparisonRect.tl()) &&
comparisonRect.contains(result.second.br())) || result.second.contains(comparisonRect.br()))
(result.second.contains(comparisonRect.tl()) &&
result.second.contains(comparisonRect.br()))
} }
result.third.removeAll(matchingResults) result.third.removeAll(matchingResults)
when (matchingResults.size) { when (matchingResults.size) {
0 -> falseHit.incrementAndGet().also { println("False hit ${result.first}") } 0 -> statistics[FALSE_HIT]!![result.first]!!.incrementAndGet()
1 -> hits.incrementAndGet().also { println("Hit ${result.first}") } .also { println("False hit ${result.first}") }
else -> falseHit.incrementAndGet().also { println("Hit too many ${result.first}") } 1 -> statistics[matchingResults[0].first]!![result.first]!!.incrementAndGet()
.also { println("Hit ${result.first}") }
else -> statistics[MULTIPLE]!![result.first]!!.incrementAndGet()
.also { println("Hit too many ${result.first}") }
} }
} }
if (ANIMATION_DELAY.isPositive()) delay(ANIMATION_DELAY * 2000) if (ANIMATION_DELAY.isPositive()) delay(ANIMATION_DELAY * 2000)
@ -455,8 +461,37 @@ suspend fun main(args: Array<String>) {
} }
} }
deferred.join() deferred.join()
val misses = comparisonData.values.sumOf { it.size } val columnLabels = TreeSet<String>()
println("Hits ${hits.get()}, False-hits ${falseHit.get()}, Total ${count.get()}, Misses $misses") var columnLabelWidth = 1
var rowLabelWidth = 1
for (rowLabel in statistics.keys) {
rowLabelWidth = maxOf(rowLabelWidth, rowLabel.length)
for (columnLabel in statistics[rowLabel]!!.keys) {
columnLabels.add(columnLabel)
columnLabelWidth = maxOf(columnLabelWidth, columnLabel.length)
}
}
println()
println("=== Comparison matrix:")
println(" | ".padStart(rowLabelWidth + 3) + columnLabels.joinToString(" | ") { it.padStart(columnLabelWidth) })
println("-|-".padStart(rowLabelWidth + 3, '-') + columnLabels.map { "" }.joinToString("-|-") { it.padStart(columnLabelWidth, '-')})
for (comparisonLabel in columnLabels + (statistics.keys - columnLabels)) {
print(comparisonLabel.padStart(rowLabelWidth) + " | ")
for (columnLabel in columnLabels) {
print((statistics[comparisonLabel]!![columnLabel]?.toString() ?: "-").padStart(columnLabelWidth))
if (columnLabel == columnLabels.last()) {
println()
} else {
print(" | ")
}
}
}
println()
println("=== Misses:")
val misses = comparisonData.values.flatten().groupingBy { it.first }.eachCount()
for ((missLabel, missCount) in misses.entries) {
println(missLabel.padStart(rowLabelWidth) + " | " + missCount)
}
} }
} }