Skip to content

Commit f294d06

Browse files
committed
Change Erosion to use IterableLoopBuilder
1 parent 4873a47 commit f294d06

File tree

1 file changed

+30
-115
lines changed

1 file changed

+30
-115
lines changed

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

Lines changed: 30 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -34,24 +34,23 @@
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;
@@ -449,122 +448,38 @@ public static < T extends RealType< T >> void erode( final RandomAccessible< T >
449448
*/
450449
public static < T extends Type< T > & Comparable< T > > void erode( final RandomAccessible< T > source, final IterableInterval< T > target, final Shape strel, final T maxVal, int numThreads )
451450
{
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-
final Object tmp = maxVal;
468-
if ( tmp instanceof BitType )
469-
{
470-
/*
471-
* Optimization for BitType
472-
*/
451+
final RandomAccessible< Neighborhood< T >> neighborhoods = strel.neighborhoodsRandomAccessible( source );
452+
Parallelization.runWithNumThreads( numThreads, () -> {
453+
IterableLoopBuilder.setImages( target, neighborhoods ).multithreaded().forEachChunk( chunk -> {
454+
chunk.forEachPixel( getErodeAction( maxVal ) );
455+
return null;
456+
} );
457+
} );
458+
}
473459

474-
for ( int i = 0; i < threads.length; i++ )
475-
{
476-
final Chunk chunk = chunks.get( i );
477-
threads[ i ] = new Thread( "Morphology erode thread " + i )
478-
{
479-
@Override
480-
public void run()
460+
private static < T extends Type< T > & Comparable< T > > BiConsumer< T, Neighborhood< T > > getErodeAction( T maxVal )
461+
{
462+
if ( maxVal instanceof BitType )
463+
return Cast.unchecked( ( BiConsumer< BitType, Neighborhood< BitType > > ) ( t, neighborhood ) -> {
464+
for ( BitType val1 : neighborhood )
465+
if ( ! val1.get() )
481466
{
482-
final RandomAccess< Neighborhood< T >> randomAccess = accessible.randomAccess( target );
483-
final Object tmp2 = target.cursor();
484-
@SuppressWarnings( "unchecked" )
485-
final Cursor< BitType > cursorTarget = ( Cursor< BitType > ) tmp2;
486-
cursorTarget.jumpFwd( chunk.getStartPosition() );
487-
488-
for ( long steps = 0; steps < chunk.getLoopSize(); steps++ )
489-
{
490-
cursorTarget.fwd();
491-
randomAccess.setPosition( cursorTarget );
492-
final Object tmp3 = randomAccess.get();
493-
@SuppressWarnings( "unchecked" )
494-
final Neighborhood< BitType > neighborhood = (net.imglib2.algorithm.neighborhood.Neighborhood< BitType > ) tmp3;
495-
final Cursor< BitType > nc = neighborhood.cursor();
496-
497-
cursorTarget.get().set( true );
498-
while ( nc.hasNext() )
499-
{
500-
nc.fwd();
501-
final BitType val = nc.get();
502-
if ( !val.get() )
503-
{
504-
cursorTarget.get().set( false );
505-
break;
506-
}
507-
}
508-
}
509-
467+
t.set( false );
468+
return;
510469
}
511-
};
512-
}
513-
}
470+
t.set( true );
471+
} );
514472
else
515473
{
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 erode thread " + i )
524-
{
525-
@Override
526-
public void run()
527-
{
528-
final RandomAccess< Neighborhood< T >> randomAccess = accessible.randomAccess( target );
529-
final Cursor< T > cursorTarget = target.cursor();
530-
cursorTarget.jumpFwd( chunk.getStartPosition() );
531-
532-
final T max = MorphologyUtils.createVariable( source, target );
533-
for ( long steps = 0; steps < chunk.getLoopSize(); steps++ )
534-
{
535-
cursorTarget.fwd();
536-
randomAccess.setPosition( cursorTarget );
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( maxVal );
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-
cursorTarget.get().set( max );
556-
}
557-
558-
}
559-
};
560-
}
474+
T min = maxVal.copy();
475+
return ( t, neighborhood ) -> {
476+
min.set( maxVal );
477+
for ( T val : neighborhood )
478+
if ( val.compareTo( min ) < 0 )
479+
min.set( val );
480+
t.set( min );
481+
};
561482
}
562-
563-
/*
564-
* Launch calculation
565-
*/
566-
567-
SimpleMultiThreading.startAndJoin( threads );
568483
}
569484

570485
/**

0 commit comments

Comments
 (0)