Move SSD side coverage helper to typed Kotlin
ober
b2841cb68652cb8a50eca24b7d585995002bf09c
--- a/templates/ssd-review.ss +++ b/templates/ssd-review.ss @@ -650,20 +650,20 @@ (int32 255))) (def (pixelBlue (pixel : Int32)) : Int32 (bitwise-and pixel (int32 255))) - (def (maxInt32 (a : Int32) (b : Int32)) : Int32 + (def (pixel-max-int32 (a : Int32) (b : Int32)) : Int32 (if (> a b) a b)) - (def (minInt32 (a : Int32) (b : Int32)) : Int32 + (def (pixel-min-int32 (a : Int32) (b : Int32)) : Int32 (if (< a b) a b)) (def (pixelMaxChannel (pixel : Int32)) : Int32 (let ((r (pixelRed pixel)) (g (pixelGreen pixel)) (b (pixelBlue pixel))) - (maxInt32 r (maxInt32 g b)))) + (pixel-max-int32 r (pixel-max-int32 g b)))) (def (pixelMinChannel (pixel : Int32)) : Int32 (let ((r (pixelRed pixel)) (g (pixelGreen pixel)) (b (pixelBlue pixel))) - (minInt32 r (minInt32 g b)))) + (pixel-min-int32 r (pixel-min-int32 g b)))) (def (pixelLuminance (pixel : Int32)) : Float (+ (+ (* 0.2126 (exact->inexact (pixelRed pixel))) (* 0.7152 (exact->inexact (pixelGreen pixel)))) @@ -705,10 +705,16 @@ (typed-kotlin-file "com/sfb/ssdreview/VisionArrays.kt" (typed-library (com sfb ssdreview) - (export grayAt edgeAt) + (export grayAt edgeAt sideCoverage) (type Int32) (type IntArray) (type BooleanArray) + (type Float32) + (type FloatArray) + (def (array-max-int32 (a : Int32) (b : Int32)) : Int32 + (if (> a b) a b)) + (def (array-min-int32 (a : Int32) (b : Int32)) : Int32 + (if (< a b) a b)) (def (grayAt (gray : IntArray) (width : Int32) (height : Int32) @@ -730,7 +736,87 @@ (or (>= x width) (>= y height)))) #f - (boolean-array-ref edge (+ (* y width) x)))))) + (boolean-array-ref edge (+ (* y width) x)))) + (def (edgeBandTop? (edge : BooleanArray) + (width : Int32) + (height : Int32) + (px : Int32) + (y : Int32) + (band : Int32)) : Bool + (for/fold ((hit #f)) + ((offset (in-range (int32 0) band))) + (or hit (edgeAt edge width height px (+ y offset))))) + (def (edgeBandBottom? (edge : BooleanArray) + (width : Int32) + (height : Int32) + (px : Int32) + (y : Int32) + (h : Int32) + (band : Int32)) : Bool + (for/fold ((hit #f)) + ((offset (in-range (int32 0) band))) + (or hit (edgeAt edge width height px (- (+ y h) (+ (int32 1) offset)))))) + (def (edgeBandLeft? (edge : BooleanArray) + (width : Int32) + (height : Int32) + (x : Int32) + (py : Int32) + (band : Int32)) : Bool + (for/fold ((hit #f)) + ((offset (in-range (int32 0) band))) + (or hit (edgeAt edge width height (+ x offset) py)))) + (def (edgeBandRight? (edge : BooleanArray) + (width : Int32) + (height : Int32) + (x : Int32) + (py : Int32) + (w : Int32) + (band : Int32)) : Bool + (for/fold ((hit #f)) + ((offset (in-range (int32 0) band))) + (or hit (edgeAt edge width height (- (+ x w) (+ (int32 1) offset)) py)))) + (def (sideCoverage (edge : BooleanArray) + (width : Int32) + (height : Int32) + (x : Int32) + (y : Int32) + (w : Int32) + (h : Int32)) : FloatArray + (let ((band (array-max-int32 + (int32 1) + (array-min-int32 + (int32 2) + (array-min-int32 (/ w (int32 2)) (/ h (int32 2))))))) + (let ((top + (for/fold ((count (int32 0))) + ((px (in-range x (+ x w)))) + (if (edgeBandTop? edge width height px y band) + (+ count (int32 1)) + count))) + (bottom + (for/fold ((count (int32 0))) + ((px (in-range x (+ x w)))) + (if (edgeBandBottom? edge width height px y h band) + (+ count (int32 1)) + count))) + (left + (for/fold ((count (int32 0))) + ((py (in-range y (+ y h)))) + (if (edgeBandLeft? edge width height x py band) + (+ count (int32 1)) + count))) + (right + (for/fold ((count (int32 0))) + ((py (in-range y (+ y h)))) + (if (edgeBandRight? edge width height x py w band) + (+ count (int32 1)) + count)))) + (float-array + (/ (float32 top) (float32 (array-max-int32 (int32 1) w))) + (/ (float32 bottom) (float32 (array-max-int32 (int32 1) w))) + (/ (float32 left) (float32 (array-max-int32 (int32 1) h))) + (/ (float32 right) (float32 (array-max-int32 (int32 1) h))))))))) + (typed-kotlin-file "com/sfb/ssdreview/UiTextHelpers.kt" (typed-library (com sfb ssdreview) (export normalizeFiringArc normalizeLabel isGenericGuessLabel isSsdPdfName @@ -3235,37 +3321,6 @@ " )" " }" "" - " private fun sideCoverage(edge: BooleanArray, width: Int, height: Int, x: Int, y: Int, w: Int, h: Int): FloatArray {" - " val band = max(1, min(2, min(w / 2, h / 2)))" - " val counts = IntArray(4)" - " for (px in x until x + w) {" - " var top = false" - " var bottom = false" - " for (offset in 0 until band) {" - " top = top || edgeAt(edge, width, height, px, y + offset)" - " bottom = bottom || edgeAt(edge, width, height, px, y + h - 1 - offset)" - " }" - " if (top) counts[0] += 1" - " if (bottom) counts[1] += 1" - " }" - " for (py in y until y + h) {" - " var left = false" - " var right = false" - " for (offset in 0 until band) {" - " left = left || edgeAt(edge, width, height, x + offset, py)" - " right = right || edgeAt(edge, width, height, x + w - 1 - offset, py)" - " }" - " if (left) counts[2] += 1" - " if (right) counts[3] += 1" - " }" - " return floatArrayOf(" - " counts[0].toFloat() / max(1, w)," - " counts[1].toFloat() / max(1, w)," - " counts[2].toFloat() / max(1, h)," - " counts[3].toFloat() / max(1, h)" - " )" - " }" - "" " private fun edgeMask(gray: IntArray, width: Int, height: Int): BooleanArray {" " val gradients = IntArray(width * height)" " val samples = mutableListOf<Int>()"