From b637c1bfd1043db19af95f9b4852c210055ae66d Mon Sep 17 00:00:00 2001 From: Alison Walter Date: Fri, 25 Jan 2019 22:12:33 +0100 Subject: [PATCH] Add method to add masks to labelings with default label and test --- src/main/java/net/imglib2/roi/Masks.java | 38 +++++++++++++ .../roi/mask/integer/MaskToLabelingTest.java | 54 +++++++++++++++++++ 2 files changed, 92 insertions(+) diff --git a/src/main/java/net/imglib2/roi/Masks.java b/src/main/java/net/imglib2/roi/Masks.java index cbc137ee7..8b3aed4f8 100644 --- a/src/main/java/net/imglib2/roi/Masks.java +++ b/src/main/java/net/imglib2/roi/Masks.java @@ -408,6 +408,44 @@ public static < T, I extends IntegerType< I > > void addMasksToLabeling( final L } } + /** + * Adds any {@link LabeledMaskInterval}s in the list to the provided + * {@link ImgLabeling}. If a given {@link MaskInterval} is a + * {@link CompositeMaskPredicate}, this method will recurse through the + * children looking for {@link LabeledMaskInterval}s. And if one is found, + * its label will be added to the {@code ImgLabeling} only at the locations + * in the root/parent {@code CompositeMaskPredicate}. If a given + * {@link MaskInterval} or part of a {@code CompositeMaskPredicate} does not + * contain a label, the given default label will be set at those locations. + * + * @param masks + * list of potential {@link MaskInterval}s to add + * @param labeling + * {@link ImgLabeling} to add labels/masks to + * @param defaultLabel + * the label to assign to pixels inside the given + * {@link MaskInterval}s that do not already have labels (i.e. + * not part of a {@link LabeledMaskInterval} + */ + @SuppressWarnings( "unchecked" ) + public static < T, I extends IntegerType< I > > void addMasksToLabeling( final List< MaskInterval > masks, final ImgLabeling< T, I > labeling, final T defaultLabel ) + { + addMasksToLabeling( masks, labeling, ( Class< T > ) defaultLabel.getClass() ); + + final RandomAccess< LabelingType< T > > ra = labeling.randomAccess(); + for ( final MaskInterval mi : masks ) + { + final Cursor< Void > c = Regions.iterable( Masks.toRandomAccessibleInterval( mi ) ).cursor(); + while ( c.hasNext() ) + { + c.next(); + ra.setPosition( c ); + if ( ra.get().isEmpty() ) + ra.get().add( defaultLabel ); + } + } + } + /* * Empty Masks * =============================================================== diff --git a/src/test/java/net/imglib2/roi/mask/integer/MaskToLabelingTest.java b/src/test/java/net/imglib2/roi/mask/integer/MaskToLabelingTest.java index 1b29e3dbd..33dca8466 100644 --- a/src/test/java/net/imglib2/roi/mask/integer/MaskToLabelingTest.java +++ b/src/test/java/net/imglib2/roi/mask/integer/MaskToLabelingTest.java @@ -335,6 +335,60 @@ public void testDifferentDimensions() assertTrue( c.next().isEmpty() ); } + @Test + public void testDefaultLabelEntireMask() + { + final MaskInterval m = createBox( new long[] { 10, 10 }, new long[] { 20, 20 } ); + final Img< IntType > indexImg = ArrayImgs.ints( 21, 21 ); + final ImgLabeling< String, IntType > imgLabeling = new ImgLabeling<>( indexImg ); + final String defaultLabel = "default"; + Masks.addMasksToLabeling( Collections.singletonList( m ), imgLabeling, defaultLabel ); + + final Cursor< LabelingType< String > > c = imgLabeling.cursor(); + while ( c.hasNext() ) + { + final LabelingType< String > labels = c.next(); + if ( m.test( c ) ) + { + assertTrue( labels.contains( defaultLabel ) ); + assertEquals( 1, labels.size() ); + } + else + assertTrue( labels.isEmpty() ); + } + } + + @Test + public void testDefaultLabelPartialMask() + { + final LabeledMaskInterval< String > labeledSphere = new LabeledMaskInterval<>( createSphere( new long[] { 10, 10 }, 5 ), "label" ); + final MaskInterval sphere = createSphere( new long[] { 15, 13 }, 4 ); + final MaskInterval or = labeledSphere.or( sphere ); + final MaskInterval minus = sphere.minus( labeledSphere ); + final String defaultLabel = "default"; + final Img< IntType > indexImg = ArrayImgs.ints( 20, 20 ); + final ImgLabeling< String, IntType > imgLabeling = new ImgLabeling<>( indexImg ); + Masks.addMasksToLabeling( Collections.singletonList( or ), imgLabeling, defaultLabel ); + + final Cursor< LabelingType< String > > c = imgLabeling.cursor(); + while ( c.hasNext() ) + { + final LabelingType< String > labels = c.next(); + if ( labeledSphere.test( c ) ) + { + assertTrue( labels.contains( labeledSphere.getLabel() ) ); + assertEquals( 1, labels.size() ); + } + else if ( minus.test( c ) ) + { + assertTrue( labels.contains( defaultLabel ) ); + assertEquals( 1, labels.size() ); + } + else + assertTrue( labels.isEmpty() ); + } + } + // -- Helper methods -- private static MaskInterval createBox( final long[] min, final long[] max )