- Adjust some demo window sizes. - Replace Random.double by Double.uniform - Tweak some demos so screenshots look more interesting
68 lines
2.4 KiB
Kotlin
68 lines
2.4 KiB
Kotlin
import boofcv.alg.filter.binary.BinaryImageOps
|
|
import boofcv.alg.filter.binary.GThresholdImageOps
|
|
import boofcv.alg.filter.binary.ThresholdImageOps
|
|
import boofcv.struct.ConnectRule
|
|
import boofcv.struct.image.GrayU8
|
|
import org.openrndr.application
|
|
import org.openrndr.boofcv.binding.toGrayF32
|
|
import org.openrndr.boofcv.binding.toShapeContours
|
|
import org.openrndr.color.ColorRGBa
|
|
import org.openrndr.color.rgb
|
|
import org.openrndr.draw.loadImage
|
|
import kotlin.math.cos
|
|
import kotlin.math.sin
|
|
|
|
fun main() = application {
|
|
program {
|
|
// Load an image, convert to BoofCV format using orx-boofcv
|
|
val input = loadImage("demo-data/images/image-001.png").toGrayF32()
|
|
|
|
// BoofCV: calculate a good threshold for the loaded image
|
|
val threshold = GThresholdImageOps.computeOtsu(input, 0.0, 255.0)
|
|
|
|
// BoofCV: use the threshold to convert the image to black and white
|
|
val binary = GrayU8(input.width, input.height)
|
|
ThresholdImageOps.threshold(input, binary, threshold.toFloat(), false)
|
|
|
|
// BoofCV: Contract and expand the white areas to remove noise
|
|
var filtered = BinaryImageOps.erode8(binary, 1, null)
|
|
filtered = BinaryImageOps.dilate8(filtered, 1, null)
|
|
|
|
// BoofCV: Calculate contours as vector data
|
|
val contours = BinaryImageOps.contour(filtered, ConnectRule.EIGHT, null)
|
|
|
|
// orx-boofcv: convert vector data to OPENRNDR ShapeContours
|
|
val externalShapes = contours.toShapeContours(
|
|
true,
|
|
internal = false, external = true
|
|
)
|
|
val internalShapes = contours.toShapeContours(
|
|
true,
|
|
internal = true, external = false
|
|
)
|
|
|
|
extend {
|
|
drawer.run {
|
|
// Zoom in and out over time
|
|
translate(bounds.center)
|
|
scale(1.5 + 0.5 * cos(seconds * 0.2))
|
|
translate(-bounds.center)
|
|
|
|
stroke = null
|
|
|
|
// Draw all external shapes
|
|
fill = rgb(0.2)
|
|
contours(externalShapes)
|
|
|
|
// Draw internal shapes one by one to set unique colors
|
|
internalShapes.forEachIndexed { i, shp ->
|
|
val shade = 0.2 + (i % 7) * 0.1 +
|
|
0.1 * sin(i + seconds)
|
|
fill = ColorRGBa.PINK.shade(shade)
|
|
contour(shp)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|