Converting greyscale images and dense voxel grids into CubicalGridStreams. Every constructor here reduces to fromFlatArray: a dense n-dimensional grid from a flat, row-major array of values plus an explicit shape.
sublevel = true (the default, matching GUDHI/DIPHA/Perseus's own convention) treats pixel intensity directly as filtration value -- ascending intensity = later in the filtration. sublevel = false negates every value before handing it to CubicalGridStream -- the standard "sublevel of -f is superlevel of f, reparametrized" trick (see CubicalStream.scala's own doc for why CubicalGridStream itself deliberately carries no direction flag). Reported birth/death values under sublevel = false are then in NEGATED-intensity units, not raw 0..255 -- documented, expected behavior of this trick, not a bug to "fix" by flipping signs back.
No image-I/O dependency is added for voxel (3D+) data -- there is no single standard JDK-readable volumetric format, so voxel constructors here take an already-in-memory array; callers with a specific file format (NRRD, NIfTI, a raw slice stack, ...) are expected to load it into an array upstream, with whatever library that needs, and hand the result to fromFlatArray/fromVoxelGrid3D directly.
Reads an image file via javax.imageio.ImageIO (JDK-builtin, no new dependency) -- PNG/JPEG/BMP/GIF and whatever other formats the running JVM's registered ImageReaders support.
Reads an image file via javax.imageio.ImageIO (JDK-builtin, no new dependency) -- PNG/JPEG/BMP/GIF and whatever other formats the running JVM's registered ImageReaders support.
Dense n-dimensional grid from a flat, row-major array of values and an explicit shape -- e.g. for shape = IndexedSeq(n0, n1, n2), index (i0, i1, i2) reads flatValues(i0*n1*n2 + i1*n2 + i2), the same convention Array[Array[...]].flatten produces, so fromGrayscale2D/fromVoxelGrid3D below can just flatten and delegate here.
Dense n-dimensional grid from a flat, row-major array of values and an explicit shape -- e.g. for shape = IndexedSeq(n0, n1, n2), index (i0, i1, i2) reads flatValues(i0*n1*n2 + i1*n2 + i2), the same convention Array[Array[...]].flatten produces, so fromGrayscale2D/fromVoxelGrid3D below can just flatten and delegate here.