56 lines
1.9 KiB
Kotlin
56 lines
1.9 KiB
Kotlin
package network.rs485.ben.computervision
|
|
|
|
import org.opencv.core.*
|
|
import org.opencv.imgproc.Imgproc
|
|
|
|
open class IdentifiableEntity(
|
|
entity: Entity,
|
|
private val dimensionProvider: DimensionProvider = CroppingDimensionProvider(entity.lines.toList()),
|
|
) {
|
|
companion object {
|
|
const val DIST_TRANSFORM_MASK_SIZE: Int = 3
|
|
|
|
// DIST_L2 is the simple euclidean distances
|
|
const val DIST_TRANSFORM_FUNC = Imgproc.DIST_L2
|
|
}
|
|
|
|
val rows: Int = dimensionProvider.maxY - dimensionProvider.minY + 1
|
|
val cols: Int = dimensionProvider.maxX - dimensionProvider.minX + 1
|
|
val rect: Rect
|
|
get() = Rect(dimensionProvider.minX, dimensionProvider.minY, cols, rows)
|
|
val lines = entity.lines.toList()
|
|
val transformedLines = lines.map {
|
|
transformPixel(it.first) to transformPixel(it.second)
|
|
}
|
|
val entityMask: Mat = Mat(rows, cols, CvType.CV_8UC1).also { maskMat ->
|
|
maskMat.setTo(COLOR_BLACK)
|
|
transformedColor(COLOR_WHITE, maskMat)
|
|
}
|
|
val distanceMat: Mat = Mat(rows, cols, CvType.CV_32FC1).also { distanceMat ->
|
|
Imgproc.distanceTransform(entityMask, distanceMat, DIST_TRANSFORM_FUNC, DIST_TRANSFORM_MASK_SIZE)
|
|
}
|
|
val minMaxDistance: Core.MinMaxLocResult by lazy { Core.minMaxLoc(distanceMat, entityMask) }
|
|
|
|
fun transformedColor(color: Scalar, image: Mat) {
|
|
transformedLines.forEach {
|
|
image.drawLine(it, color)
|
|
}
|
|
}
|
|
|
|
fun transformPixel(pixel: Pixel) = Pixel(pixel.x - dimensionProvider.minX, pixel.y - dimensionProvider.minY)
|
|
|
|
open fun release() {
|
|
entityMask.release()
|
|
distanceMat.release()
|
|
}
|
|
|
|
override fun toString(): String {
|
|
return "IdentifiableEntity($rect)"
|
|
}
|
|
}
|
|
|
|
internal inline fun <T> withIdEntity(entity: Entity, block: (identity: IdentifiableEntity) -> T): T =
|
|
IdentifiableEntity(entity).let { identity ->
|
|
autoclean(identity, identity::release, block)
|
|
}
|