Skip to content

Commit 4873a47

Browse files
committed
Change Dilation to use IterableLoopBuilder
1 parent 791c47f commit 4873a47

File tree

1 file changed

+31
-115
lines changed

1 file changed

+31
-115
lines changed

src/main/java/net/imglib2/algorithm/morphology/Dilation.java

Lines changed: 31 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -34,31 +34,31 @@
3434
package net.imglib2.algorithm.morphology;
3535

3636
import java.util.List;
37-
import java.util.Vector;
37+
import java.util.function.BiConsumer;
3838

39-
import net.imglib2.Cursor;
4039
import net.imglib2.FinalDimensions;
4140
import net.imglib2.Interval;
4241
import net.imglib2.IterableInterval;
43-
import net.imglib2.RandomAccess;
4442
import net.imglib2.RandomAccessible;
4543
import net.imglib2.RandomAccessibleInterval;
44+
import net.imglib2.loops.IterableLoopBuilder;
4645
import net.imglib2.algorithm.neighborhood.Neighborhood;
4746
import net.imglib2.algorithm.neighborhood.Shape;
4847
import net.imglib2.img.Img;
4948
import net.imglib2.img.ImgFactory;
50-
import net.imglib2.multithreading.Chunk;
51-
import net.imglib2.multithreading.SimpleMultiThreading;
49+
import net.imglib2.parallel.Parallelization;
5250
import net.imglib2.type.Type;
5351
import net.imglib2.type.logic.BitType;
5452
import net.imglib2.type.numeric.RealType;
53+
import net.imglib2.util.Cast;
5554
import net.imglib2.util.Util;
5655
import net.imglib2.view.ExtendedRandomAccessibleInterval;
5756
import net.imglib2.view.IntervalView;
5857
import net.imglib2.view.Views;
5958

6059
public class Dilation
6160
{
61+
6262
/**
6363
* Performs the dilation morphological operation, on a {@link RealType}
6464
* {@link Img} using a list of {@link Shape}s as a flat structuring element.
@@ -449,122 +449,38 @@ public static < T extends RealType< T >> void dilate( final RandomAccessible< T
449449
*/
450450
public static < T extends Type< T > & Comparable< T > > void dilate( final RandomAccessible< T > source, final IterableInterval< T > target, final Shape strel, final T minVal, int numThreads )
451451
{
452-
numThreads = Math.max( 1, numThreads );
453-
454-
/*
455-
* Prepare iteration.
456-
*/
457-
458-
final RandomAccessible< Neighborhood< T >> accessible = strel.neighborhoodsRandomAccessible( source );
459-
460-
/*
461-
* Multithread
462-
*/
463-
464-
final Vector< Chunk > chunks = SimpleMultiThreading.divideIntoChunks( target.size(), numThreads );
465-
final Thread[] threads = SimpleMultiThreading.newThreads( numThreads );
466-
467-
468-
final Object tmp = minVal;
469-
if ( tmp instanceof BitType )
470-
{
471-
/*
472-
* Optimization for BitType
473-
*/
452+
final RandomAccessible< Neighborhood< T > > neighborhoods = strel.neighborhoodsRandomAccessible( source );
453+
Parallelization.runWithNumThreads( numThreads, () -> {
454+
IterableLoopBuilder.setImages( target, neighborhoods ).multithreaded().forEachChunk( chunk -> {
455+
chunk.forEachPixel( getDilateAction( minVal ) );
456+
return null;
457+
} );
458+
} );
459+
}
474460

475-
for ( int i = 0; i < threads.length; i++ )
476-
{
477-
final Chunk chunk = chunks.get( i );
478-
threads[ i ] = new Thread( "Morphology dilate thread " + i )
479-
{
480-
@Override
481-
public void run()
461+
private static < T extends Type< T > & Comparable< T > > BiConsumer< T, Neighborhood< T > > getDilateAction( T minVal )
462+
{
463+
if ( minVal instanceof BitType )
464+
return Cast.unchecked( (BiConsumer< BitType, Neighborhood< BitType > > ) ( t, neighborhood ) -> {
465+
for ( BitType val1 : neighborhood )
466+
if ( val1.get() )
482467
{
483-
final RandomAccess< Neighborhood< T >> randomAccess = accessible.randomAccess( target );
484-
final Object tmp2 = target.cursor();
485-
@SuppressWarnings( "unchecked" )
486-
final Cursor< BitType > cursorDilated = ( Cursor< BitType > ) tmp2;
487-
cursorDilated.jumpFwd( chunk.getStartPosition() );
488-
489-
for ( long steps = 0; steps < chunk.getLoopSize(); steps++ )
490-
{
491-
cursorDilated.fwd();
492-
randomAccess.setPosition( cursorDilated );
493-
final Neighborhood< T > neighborhood = randomAccess.get();
494-
final Object tmp3 = neighborhood.cursor();
495-
@SuppressWarnings( "unchecked" )
496-
final Cursor< BitType > nc = ( Cursor< BitType > ) tmp3;
497-
498-
while ( nc.hasNext() )
499-
{
500-
nc.fwd();
501-
final BitType val = nc.get();
502-
if ( val.get() )
503-
{
504-
cursorDilated.get().set( true );
505-
break;
506-
}
507-
}
508-
}
509-
468+
t.set( true );
469+
return;
510470
}
511-
};
512-
}
513-
}
471+
t.set( false );
472+
} );
514473
else
515474
{
516-
/*
517-
* All other comparable type.
518-
*/
519-
520-
for ( int i = 0; i < threads.length; i++ )
521-
{
522-
final Chunk chunk = chunks.get( i );
523-
threads[ i ] = new Thread( "Morphology dilate thread " + i )
524-
{
525-
@Override
526-
public void run()
527-
{
528-
final RandomAccess< Neighborhood< T >> randomAccess = accessible.randomAccess( target );
529-
final Cursor< T > cursorDilated = target.cursor();
530-
cursorDilated.jumpFwd( chunk.getStartPosition() );
531-
532-
final T max = MorphologyUtils.createVariable( source, target );
533-
for ( long steps = 0; steps < chunk.getLoopSize(); steps++ )
534-
{
535-
cursorDilated.fwd();
536-
randomAccess.setPosition( cursorDilated );
537-
final Neighborhood< T > neighborhood = randomAccess.get();
538-
final Cursor< T > nc = neighborhood.cursor();
539-
540-
/*
541-
* Look for max in the neighborhood.
542-
*/
543-
544-
max.set( minVal );
545-
while ( nc.hasNext() )
546-
{
547-
nc.fwd();
548-
final T val = nc.get();
549-
// We need only Comparable to do this:
550-
if ( val.compareTo( max ) > 0 )
551-
{
552-
max.set( val );
553-
}
554-
}
555-
cursorDilated.get().set( max );
556-
}
557-
558-
}
559-
};
560-
}
475+
T max = minVal.copy();
476+
return ( t, neighborhood ) -> {
477+
max.set( minVal );
478+
for ( T val : neighborhood )
479+
if ( val.compareTo( max ) > 0 )
480+
max.set( val );
481+
t.set( max );
482+
};
561483
}
562-
563-
/*
564-
* Launch calculation
565-
*/
566-
567-
SimpleMultiThreading.startAndJoin( threads );
568484
}
569485

570486
/**

0 commit comments

Comments
 (0)