Add boofCV demo

This commit is contained in:
Abe Pazos
2020-05-16 11:44:43 +02:00
committed by GitHub
parent 36f49eeb9b
commit 7c9c87ea3f
3 changed files with 115 additions and 11 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 826 KiB

View File

@@ -0,0 +1,75 @@
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 org.openrndr.extensions.SingleScreenshot
import org.openrndr.resourceUrl
import kotlin.math.cos
import kotlin.math.sin
fun main() {
application {
program {
// -- this block is for automation purposes only
if (System.getProperty("takeScreenshot") == "true") {
extend(SingleScreenshot()) {
this.outputFile = System.getProperty("screenshotPath")
}
}
// 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)
}
}
}
}
}
}

View File

@@ -4,19 +4,48 @@ import boofcv.alg.filter.binary.Contour
import org.openrndr.shape.Shape
import org.openrndr.shape.ShapeContour
fun Contour.toShape(): Shape {
val external = external.toVector2s()
val internal = internal.filter { it.size > 0 }. map { it.toVector2s() }
val contours = listOf(ShapeContour.fromPoints(external, false)) +
internal.map {
ShapeContour.fromPoints(it, false)
}
fun Contour.toShape(closed: Boolean = false, getInternal: Boolean, getExternal: Boolean): Shape {
val contours = mutableListOf<ShapeContour>()
if (getExternal) {
val externalPoints = external.toVector2s()
contours.addAll(listOf(ShapeContour.fromPoints(externalPoints, closed)))
}
if (getInternal) {
val internalCurves = internal.filter { it.size >= 3 }.map { it.toVector2s() }
contours.addAll(internalCurves.map { internalCurve ->
ShapeContour.fromPoints(internalCurve, closed)
})
}
return Shape(contours)
}
fun List<Contour>.toShapes(): List<Shape> {
return this.filter { it.external.isNotEmpty() }.map {
it.toShape()
fun List<Contour>.toShapes(closed: Boolean = false,
internal: Boolean = true,
external: Boolean = true): List<Shape> {
return this.filter { it.external.size >= 3 }.map {
it.toShape(closed, internal, external)
}
}
fun List<Contour>.toShapeContours(closed: Boolean = false,
internal: Boolean = true,
external: Boolean = true): List<ShapeContour> {
val contours = mutableListOf<ShapeContour>()
this.forEach { contour ->
if(contour.external.size >= 3) {
if (external) {
val externalPoints = contour.external.toVector2s()
contours.add(ShapeContour.fromPoints(externalPoints, closed))
}
if (internal) {
val internalCurves = contour.internal.filter { it.size >= 3 }
.map { it.toVector2s() }
internalCurves.forEach { internalContour ->
contours.add(ShapeContour.fromPoints(internalContour, closed))
}
}
}
}
return contours
}