Move SSD contour cell helper to typed Kotlin
ober
aa24fcefdc8e48ce495e7524844d0c2fdc3b4f91
--- a/templates/ssd-review.ss +++ b/templates/ssd-review.ss @@ -705,7 +705,7 @@ (typed-kotlin-file "com/sfb/ssdreview/VisionArrays.kt" (typed-library (com sfb ssdreview) - (export grayAt edgeAt sideCoverage darkSideCoverage) + (export grayAt edgeAt sideCoverage darkSideCoverage contourCell) (type Int32) (type IntArray) (type BooleanArray) @@ -715,6 +715,16 @@ (if (> a b) a b)) (def (array-min-int32 (a : Int32) (b : Int32)) : Int32 (if (< a b) a b)) + (def (coverage-count-at-least (coverage : FloatArray) (threshold : Float32)) : Int32 + (for/fold ((count (int32 0))) + ((index (in-range (int32 0) (float-array-length coverage)))) + (if (>= (float-array-ref coverage index) threshold) + (+ count (int32 1)) + count))) + (def (coverage-sum (coverage : FloatArray)) : Float32 + (for/fold ((total (float32 0.0))) + ((index (in-range (int32 0) (float-array-length coverage)))) + (+ total (float-array-ref coverage index)))) (def (grayAt (gray : IntArray) (width : Int32) (height : Int32) @@ -894,7 +904,54 @@ (/ (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))))))))) + (/ (float32 right) (float32 (array-max-int32 (int32 1) h))))))) + (def (contourCell (component : Component) + (edge : BooleanArray) + (width : Int32) + (height : Int32)) : (Nullable SsdCell) + (let ((w (componentW component)) + (h (componentH component))) + (let ((bboxArea (* w h))) + (if (or (or (< bboxArea (int32 50)) + (> bboxArea (int32 2400))) + (or (or (< w (int32 7)) + (> w (int32 90))) + (or (< h (int32 7)) + (> h (int32 90))))) + (nullable-none SsdCell) + (let ((aspect (/ (float32 w) + (float32 (array-max-int32 (int32 1) h))))) + (if (or (< aspect (float32 0.55)) + (> aspect (float32 1.8))) + (nullable-none SsdCell) + (let ((perimeter (array-max-int32 (int32 1) (* (int32 2) (+ w h)))) + (safeArea (array-max-int32 (int32 1) bboxArea))) + (let ((edgeDensity (/ (float32 (Component-area component)) + (float32 safeArea))) + (edgePerimeterRatio (/ (float32 (Component-area component)) + (float32 perimeter)))) + (if (or (< edgeDensity (float32 0.035)) + (or (< edgePerimeterRatio (float32 0.18)) + (> edgePerimeterRatio (float32 5.0)))) + (nullable-none SsdCell) + (let ((coverage + (sideCoverage edge width height + (Component-x1 component) + (Component-y1 component) + w + h))) + (if (or (< (coverage-count-at-least coverage (float32 0.22)) + (int32 3)) + (< (coverage-sum coverage) (float32 1.10))) + (nullable-none SsdCell) + (nullable-some + (make-SsdCell + "" + (float32 (Component-x1 component)) + (float32 (Component-y1 component)) + (float32 w) + (float32 h) + "android-contour"))))))))))))))) (typed-kotlin-file "com/sfb/ssdreview/UiTextHelpers.kt" (typed-library (com sfb ssdreview) @@ -3338,22 +3395,6 @@ " .mapNotNull { contourCell(it, edge, width, height) }" " }" "" - " private fun contourCell(component: Component, edge: BooleanArray, width: Int, height: Int): SsdCell? {" - " val w = componentW(component)" - " val h = componentH(component)" - " val bboxArea = w * h" - " if (bboxArea !in 50..2400 || w !in 7..90 || h !in 7..90) return null" - " val aspect = w.toFloat() / max(1, h).toFloat()" - " if (aspect !in 0.55f..1.8f) return null" - " val perimeter = max(1, 2 * (w + h))" - " val edgeDensity = component.area.toFloat() / max(1, bboxArea).toFloat()" - " val edgePerimeterRatio = component.area.toFloat() / perimeter.toFloat()" - " if (edgeDensity < 0.035f || edgePerimeterRatio !in 0.18f..5.0f) return null" - " val coverage = sideCoverage(edge, width, height, component.x1, component.y1, w, h)" - " if (coverage.count { it >= 0.22f } < 3 || coverage.sum() < 1.10f) return null" - " return SsdCell(\"\", component.x1.toFloat(), component.y1.toFloat(), w.toFloat(), h.toFloat(), \"android-contour\")" - " }" - "" " private fun mergeDuplicateCells(cells: List<SsdCell>): MutableList<SsdCell> {" " val merged = mutableListOf<SsdCell>()" " for (cell in cells.sortedWith(compareBy<SsdCell> { it.y }.thenBy { it.x })) {"