jonclayden / mmand

Mathematical Morphology in Any Number of Dimensions
37 stars 8 forks source link

What gives a 3D voxel structure that's "coercible to an array"? #7

Closed mavavilj closed 3 years ago

mavavilj commented 3 years ago

What gives a 3D voxel structure that's "coercible to an array"?

As required by e.g. morph?

jonclayden commented 3 years ago

That's a pretty open-ended question. What are you starting with? Some kind of image object? A file?

mavavilj commented 3 years ago

Well I'm working with this:

https://rdrr.io/cran/lidR/man/voxel_metrics.html

jonclayden commented 3 years ago

Thanks for clarifying. I'm not familiar with the lidR package, but that function appears to produce tabular data along the lines of some sparse representations. If the package doesn't provide an as.array method for its objects, or another way to convert them to array-type objects, you may need to wrangle the data into array form yourself.

mavavilj commented 3 years ago

What's the expected array like anyways?

Is there a specification for it?

Also one could of course use some other voxelization method, but this is the only one I've found so far.

I can do e.g.

as.array(as.matrix(vm))
          X     Y   Z V1
 [1,] -0.05  2.55 4.5  1
 [2,]  0.15  2.55 4.4  1
 [3,] -0.05  2.55 4.4  3
 [4,]  0.15  2.55 4.3  2
 [5,] -0.05  2.55 4.2  1
 [6,]  0.15  2.55 4.1  1
 [7,]  0.15  2.05 3.8  3
 [8,]  0.15  2.05 3.9  2
 [9,]  0.15  2.55 4.2  2
[10,]  0.15  2.55 4.0  1
[11,]  0.15  2.05 3.7  2
[12,]  0.15  2.05 3.5  1
[13,]  0.25  2.55 3.8  2
[14,]  0.25  2.05 3.8 16
[15,]  0.25  2.05 3.1  2
[16,]  0.25  3.05 4.8  3
[17,]  0.25  3.05 4.3  3
[18,]  0.25  2.55 4.2  3
[19,]  0.25  2.55 4.1  3
[20,]  0.25  2.55 4.0  2
[21,]  0.25  2.55 4.8  1
[22,]  0.25  2.05 3.7  2
[23,]  0.45  2.55 4.0  1
[24,]  0.45  2.55 4.2  1
[25,]  0.65  2.55 2.0  3
[26,]  0.65  2.55 2.2  1
[27,]  0.75  2.55 2.0  4
[28,]  0.75  2.55 2.3  4
[29,]  0.75  2.55 2.4  2
[30,]  0.75  2.55 2.1  2
[31,]  1.75 -0.05 3.8  2
[32,]  1.75 -0.05 3.7  2
[33,]  1.75 -0.05 3.2  1
[34,]  1.75 -0.05 3.5  1
[35,]  1.75 -0.05 3.6  1
[36,]  1.95 -0.05 3.2  1
[37,]  2.05 -0.05 3.3  1
[38,]  1.95 -0.05 3.8  1
[39,]  2.05 -0.05 3.8  1
[40,]  2.05 -0.05 3.4  1
[41,]  2.05 -0.05 3.5  1
[42,]  3.05  0.95 4.6  1
[43,]  3.05  0.95 4.0  1
[44,]  3.05  0.95 4.2  1
[45,]  2.95  0.95 4.1  1
[46,]  2.95  0.95 4.3  1
[47,]  3.05  0.95 4.5  1
[48,]  2.95  0.55 3.1  1
[49,]  3.15  0.55 3.0  2
[50,]  3.25  0.55 3.0  2
[51,]  3.15  0.95 4.5  1
[52,]  3.25  0.55 3.4  1

where vm is the result vm <- voxel_metrics(...,~length(Z),0.1). I.e. it's a voxelization with 0.1m voxel side length and it creates a fourth column with number of points inside that voxel. Each row marks a voxel.

Is this valid or a hack?

It's intuitive that a kernel should be definable to such structure, but does this package support this format? Or perhaps it expects numpy-like matrix?

jonclayden commented 3 years ago

The information is here, but it's not in the right form. You'd need to convert this to a dense three-dimensional array whose elements reflect the values of the metric at each location on the voxel grid. For example:

  1. Create a vector of X locations between the maximum and minimum X values in the first column, in steps of 0.1. Repeat for Y and Z.
  2. Create an array of zeros (presumably) with dimensions given by the lengths of those three vectors.
  3. Insert the values from the fourth column at locations matching each voxel location.
mavavilj commented 3 years ago

I see.

Would be probably convenient to have a function that does conversion from data.matrix, data.table and data.frame of XYZ + optional fourth dimension of data (e.g. binary "voxel is/is not empty" or "no. of points in voxel") to the format that this library expects.

jonclayden commented 3 years ago

If sparse representations were quite standard across other packages that might be easy to arrange, but there is quite a bit of variation so it's difficult to do. The slam package does some conversion between a sparse array format that is similar to this and canonical dense arrays, but lidR's format is a variation because it specifies locations in "real space" rather than integer indices.

There is nothing special about mmand's format – the dense array is a core R data structure, so it's highly interoperable. I think it makes more sense for packages to provide as.array methods for their specialised array-like data structures. It might be worth asking the lidR package maintainer about adding one to that package.

jonclayden commented 3 years ago

I'm closing this issue as out of scope, because it seems to boil down to converting a third-party package's specialised format to a generic one.