imglib / imglib2

A generic next-generation Java library for image processing
http://imglib2.net/
Other
293 stars 93 forks source link

"Stack" RealRandomAccessibles as Composite #318

Open bogovicj opened 1 year ago

bogovicj commented 1 year ago

see #317

bogovicj commented 1 year ago

I called this a RealStackCompositeView, but don't like that name. maybe RealListCompositeView?

bogovicj commented 1 year ago

I won't keep working on this until there is a more urgent use case but will leave this open in case we'd like to revisit in the future.

This needs a better name for the class, and probably would benefit from a view that does the "inverse" operation, something like: RealRandomAccessible<T> unstackRealComposite( RealRandomAccessible<Composite<T>> stack, int component ) but also with a better name

bogovicj commented 9 months ago

I'd like to revist this.

There are at least two specific applications for the code provided by this PR. One I describe below, the other is in paintera - @cmhulbert can point it one if it's of interest.

When I initially started this, I thought it might be useful for building DisplacementFieldTransforms, and I believe they still could be because somehow needs to build a RealRandomAccessible<RealLocalizable> to create a DisplacementFieldTransform.

We left this PR for a year because one (common) way to create the RealRandomAccessible<RealLocalizable> is by collapsing then interpolating. That works because some interpolators (specifically NLinearInterpolators can work on Composites, because Composites are NumericTypes

Other interpolators will not work today, for example:

because they use RealTypes. and even RealComposite types are not RealTypes.

We might choose to make some composite types RealTypes, but that would sacrifice some nice behavior, for example clipping. Clipping requires a min and max value, and there's no ordering of vectors. There are at least three clipping interpolators: Lanczos Bspline and ClampingNLinearInterpolator

A straightfoward solution to interpolate each component of the vector independently, then "stack" them. Given a list of vector componets:

final RealRandomAccessible<T>[] components 

It is possible to do this now with BiConverters, but it's very verbose:

final BiConverter<T, T, RealComposite<DoubleType>> conv0 = new BiConverter<T,T,RealComposite<DoubleType>>()
{
    @Override
    public void convert( T x, T y, RealComposite<DoubleType> output ) {
        output.get(0).set(x.getRealDouble());
        output.get(1).set(y.getRealDouble());
    }
};

final int N = 3;
final RealComposite<DoubleType> v = DoubleType.createVector(N);
final RealRandomAccessible<RealComposite<DoubleType>> img = Converters.convert( components[0], components[1], conv0, v);
RealRandomAccessible<RealComposite<DoubleType>> total = img;
for( int i = 2; i < N; i++ )
{
    final int j = i;
    total = Converters.convert(
            total,
            components[i],
            new BiConverter<RealComposite<DoubleType>,T,RealComposite<DoubleType>>()
            {
                @Override
                public void convert( RealComposite<DoubleType> part, T x, RealComposite<DoubleType> whole ) {

                    for( int d = 0; d < j; d++ )
                        whole.get(d).set(part.get(d));

                    whole.get(j).set(x.getRealDouble());
                }
            },
            v.copy());
}

This PR would

RealRandomAccessible<Composite<T>> total2 = Views.realComposite(components);