Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split IterableRegion #71

Merged
merged 3 commits into from
Apr 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
<parent>
<groupId>org.scijava</groupId>
<artifactId>pom-scijava</artifactId>
<version>34.1.0</version>
<version>37.0.0</version>
<relativePath />
</parent>

<groupId>net.imglib2</groupId>
<artifactId>imglib2-roi</artifactId>
<version>0.14.2-SNAPSHOT</version>
<version>0.15.0-SNAPSHOT</version>

<name>ImgLib2 ROI</name>
<description>Regions of interest in ImgLib2.</description>
Expand Down Expand Up @@ -63,9 +63,6 @@ Martin Horn, Steffen Jaensch, Lee Kamentsky, Larry Lindsey, Melissa Linkert,
Mark Longair, Brian Northan, Nick Perry, Curtis Rueden, Johannes Schindelin,
Jean-Yves Tinevez and Michael Zinsmaier.</license.copyrightOwners>

<imglib2.version>6.1.0</imglib2.version>
<imglib2-realtransform.version>4.0.1</imglib2-realtransform.version>

<!-- NB: Deploy releases to the SciJava Maven repository. -->
<releaseProfiles>sign,deploy-to-scijava</releaseProfiles>
</properties>
Expand Down
19 changes: 14 additions & 5 deletions src/main/java/net/imglib2/roi/IterableRegion.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,10 @@
* i.e., it is assumed that all pixels outside the interval have value
* {@code false}.
* <p>
* Iterating only the pixels contained in the region is indicated by
* {@code IterableInterval<Void>}, i.e., when iterating, only the coordinates
* that are visited are interesting. There is no associated value.
* Iterating only the pixels contained in the region is done via the {@code
* IterableInterval<Void>} {@link #inside()}. (The pixel type is {@code Void}
* because, when iterating, only the coordinates that are visited are
* interesting. There is no associated value.)
* <p>
* We put interfaces {@code RandomAccessibleInterval<BooleanType>}, extended by
* {@code IterableRegion<BooleanType>}, extended by
Expand All @@ -62,5 +63,13 @@
*
* @author Tobias Pietzsch
*/
public interface IterableRegion< T extends BooleanType< T > > extends IterableInterval< Void >, RandomAccessibleInterval< T >
{}
public interface IterableRegion< T extends BooleanType< T > > extends RandomAccessibleInterval< T >
{
/**
* Get an {@code IterableInterval} view of only the pixels contained in the
* region (having value {@code true}).
*
* @return iterable of the pixels in the region
*/
IterableInterval< Void > inside();
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,13 @@ public interface PositionableIterableInterval< T > extends IterableInterval< T >
*
* @return the origin to which the interval is relative.
*/
public PositionableLocalizable origin();
PositionableLocalizable origin();

/**
* Make a copy of this {@link PositionableIterableInterval} which can be
* positioned independently.
*
* @return a copy with an independent position
*/
public PositionableIterableInterval< T > copy();
PositionableIterableInterval< T > copy();
}
53 changes: 50 additions & 3 deletions src/main/java/net/imglib2/roi/PositionableIterableRegion.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,19 @@
*/
package net.imglib2.roi;

import net.imglib2.Localizable;
import net.imglib2.Positionable;
import net.imglib2.roi.util.PositionableLocalizable;
import net.imglib2.type.BooleanType;
import net.imglib2.type.logic.BitType;

/**
* An {@link IterableRegion} that can be moved around.
* <p>
* The iterable view of {@link #inside()} pixels can also be moved around. Its
* position is the same as the position of this {@code
* PositionableIterableRegion}. Moving one will also move the other.
* <p>
* We put interfaces {@code RandomAccessibleInterval<BooleanType>}, extended by
* {@code IterableRegion<BooleanType>}, extended by
* {@code PositionableIterableRegion<BooleanType>} into this sequence such that
Expand All @@ -49,9 +57,48 @@
*
* @author Tobias Pietzsch
*/
public interface PositionableIterableRegion< T extends BooleanType< T > >
extends IterableRegion< T >, PositionableIterableInterval< Void >
public interface PositionableIterableRegion< T extends BooleanType< T > > extends IterableRegion< T >, Localizable, Positionable
{
/**
* Get an {@code PositionableIterableInterval} view of only the pixels contained in the
* region (having value {@code true}).
* <p>
* The position of the {@link #inside()} view is the same as the position of
* this {@code PositionableIterableRegion}. Moving one will also move the
* other.
*
* @return iterable of the pixels in the region
*/
@Override
public PositionableIterableRegion< T > copy();
PositionableIterableInterval< Void > inside();

/**
* Get the {@link Positionable}, {@link Localizable} origin of this
* interval.
* <p>
* The origin is the relative offset of the position to the minimum. For
* example if a positionable (bitmask) region is made from a {@link BitType}
* image with a circular pattern, then it is more natural if the region
* position refers to the center of the pattern instead of the upper left
* corner of the {@link BitType} image. This can be achieved by positioning
* the origin.
* <p>
* Assume a region is created from a 9x9 bitmask. The region initially has
* min=(0,0), max=(8,8), position=(0,0). Because both position and min are
* (0,0), initially origin=(0,0). Now assume the origin is moved to the
* center of the bitmask using
* <code>origin().setPosition(new int[]{4,4})</code>. After this,
* min=(-4,-4), max=(4,4), position=(0,0), and origin=(4,4).
*
* @return the origin to which the interval is relative.
*/
PositionableLocalizable origin();

/**
* Make a copy of this {@link PositionableIterableInterval} which can be
* positioned independently.
*
* @return a copy with an independent position
*/
PositionableIterableRegion< T > copy();
}
8 changes: 6 additions & 2 deletions src/main/java/net/imglib2/roi/Regions.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ public static < T > IterableInterval< T > sample( final IterableInterval< Void >
return SamplingIterableInterval.create( region, img );
}

public static < T > IterableInterval< T > sample( final IterableRegion< ? > region, final RandomAccessible< T > img )
{
return sample( region.inside(), img );
}

/**
* Given a mask and an image, return an {@link IterableInterval} over the
* pixels of the image inside the mask.
Expand Down Expand Up @@ -106,8 +111,7 @@ public static < T > IterableInterval< T > sample( final RealMaskRealInterval mas
// NB: this method is not named "sample" to avoid ambiguation with sample(IterableInterval<Void>, RandomAccessible<T>)
public static < T, B extends BooleanType< B > > IterableInterval< T > sampleWithRandomAccessible( final RandomAccessible< B > mask, final RandomAccessibleInterval< T > img )
{
final IterableInterval< Void > region = iterable( Views.interval( mask, img ) );
return sample( region, img );
return sample( iterable( Views.interval( mask, img ) ), img );
}

/**
Expand Down
87 changes: 53 additions & 34 deletions src/main/java/net/imglib2/roi/boundary/Boundary.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import net.imglib2.AbstractWrappedInterval;
import net.imglib2.Cursor;
import net.imglib2.Interval;
import net.imglib2.IterableInterval;
import net.imglib2.Localizable;
import net.imglib2.Point;
import net.imglib2.RandomAccess;
Expand Down Expand Up @@ -70,7 +71,8 @@
public final class Boundary< T extends BooleanType< T > >
extends AbstractWrappedInterval< RandomAccessibleInterval< T > > implements IterableRegion< BoolType >
{
public static enum StructuringElement

public enum StructuringElement
{
FOUR_CONNECTED,
EIGHT_CONNECTED
Expand All @@ -84,6 +86,8 @@ public static enum StructuringElement

private final int size;

private final BoundaryIterable inside;

public Boundary( final RandomAccessibleInterval< T > region )
{
this( region, FOUR_CONNECTED );
Expand All @@ -108,59 +112,74 @@ public Boundary( final RandomAccessibleInterval< T > region, final StructuringEl
break;
}
size = coords.size() / n;
inside = new BoundaryIterable();
}

@Override
public long size()
public IterableInterval< Void > inside()
{
return size;
return inside;
}

@Override
public Object iterationOrder()
public RandomAccess< BoolType > randomAccess()
{
return this;
return structuringElement == FOUR_CONNECTED
? new BoundaryRandomAccess4< T >( sourceInterval )
: new BoundaryRandomAccess8< T >( sourceInterval );
}

@Override
public BoundaryCursor cursor()
public RandomAccess< BoolType > randomAccess( final Interval interval )
{
return new BoundaryCursor();
return randomAccess();
}

@Override
public BoundaryCursor localizingCursor()
private final class BoundaryIterable extends AbstractWrappedInterval< Interval > implements IterableInterval< Void >
{
return cursor();
}
BoundaryIterable()
{
super( Boundary.this );
}

@Override
public BoundaryCursor iterator()
{
return cursor();
}
@Override
public long size()
{
return size;
}

@Override
public Void firstElement()
{
return cursor().next();
}
@Override
public Object iterationOrder()
{
return this;
}

@Override
public RandomAccess< BoolType > randomAccess()
{
return structuringElement == FOUR_CONNECTED
? new BoundaryRandomAccess4< T >( sourceInterval )
: new BoundaryRandomAccess8< T >( sourceInterval );
}
@Override
public BoundaryCursor cursor()
{
return new BoundaryCursor();
}

@Override
public RandomAccess< BoolType > randomAccess( final Interval interval )
{
return randomAccess();
@Override
public BoundaryCursor localizingCursor()
{
return cursor();
}

@Override
public BoundaryCursor iterator()
{
return cursor();
}

@Override
public Void firstElement()
{
return cursor().next();
}
}

final class BoundaryCursor extends Point implements Cursor< Void >
private final class BoundaryCursor extends Point implements Cursor< Void >
{
private int i;

Expand Down Expand Up @@ -246,7 +265,7 @@ static final class BoundaryConstructor< T extends BooleanType< T > > implements

public BoundaryConstructor( final RandomAccessibleInterval< T > region, final StructuringElement structuringElement )
{
c = Regions.iterable( region ).localizingCursor();
c = Regions.iterable( region ).inside().localizingCursor();
a = structuringElement == FOUR_CONNECTED
? new BoundaryRandomAccess4< T >( region )
: new BoundaryRandomAccess8< T >( region );
Expand Down
Loading
Loading