Skip to content

Commit

Permalink
Split IterableInterval<Void> from IterableRegion
Browse files Browse the repository at this point in the history
The Cursor<Void> of the inside pixels of a region can be obtained by
region.inside().cursor() now.
  • Loading branch information
tpietzsch committed Mar 27, 2024
1 parent 6d34fc4 commit 9373214
Show file tree
Hide file tree
Showing 14 changed files with 440 additions and 159 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

<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
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
85 changes: 52 additions & 33 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,56 +112,71 @@ 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()
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 >
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

0 comments on commit 9373214

Please sign in to comment.