imglib / imglib2-algorithm

Image processing algorithms for ImgLib2
http://imglib2.net/
Other
22 stars 20 forks source link

Convenience methods for signed distance transform #72

Open hanslovsky opened 6 years ago

hanslovsky commented 6 years ago

With the newly introduced binary distance transform methods (#69, #71), we can now very easily create a signed distance transform (beware: Kotlin!):


private fun <B: BooleanType<B>, T: RealType<T>> signedDistanceTransform(
        mask: RandomAccessibleInterval<B>,
        distanceOutside: RandomAccessibleInterval<T>,
        distanceInside: RandomAccessibleInterval<T>,
        vararg weights: Double = doubleArrayOf(1.0),
        distanceType: DistanceTransform.DISTANCE_TYPE = DistanceTransform.DISTANCE_TYPE.EUCLIDIAN
): RandomAccessibleInterval<T> {
    DistanceTransform.binaryTransform(mask, distanceOutside, distanceType, *weights)
    DistanceTransform.binaryTransform(not(mask), distanceInside, distanceType, *weights)
    val paired= Views.interval(Views.pair(distanceOutside, distanceInside), mask)
    return difference(paired)

}

with helper methods

fun <B: BooleanType<B>> not(mask: RandomAccessibleInterval<B>): RandomAccessibleInterval<B>
{
    return Converters.convert(mask, { s,t -> t.set(!s.get()) }, Util.getTypeFromInterval(mask).createVariable())!!
}

fun<T: RealType<T>> difference(pairs: RandomAccessibleInterval<Pair<T, T>>): RandomAccessibleInterval<T> {
    return Converters.convert(
            pairs,
            { s,t -> t.set(s.a); t.sub(s.b) },
            Util.getTypeFromInterval(pairs).a.createVariable())!!
}

This will be negative inside the object defined by mask and positive everywhere else.

axtimwalde commented 3 years ago

Happy to add this once we decided what to do about the fact that this steps from -1 to 1 skipping 0 per definition of the distance transform boundaries being in the boundary pixel and not between boundary pixels (lab discussion, @hanslovsky knows the details). In isotropic spaces, we could probably just subtract 0.5 from all distances which states that the boundary is 0.5px closer to the pixel without making an effort to explain where it is. But this would not work with non-isotropic grids. This means this offset should probably go into the DT algorithm?