Skip to content

Commit 2f7697f

Browse files
authored
Merge pull request #224 from hanslovsky/fix-concatenate
Fix Views.concatenate for axis other than last dimension
2 parents 54f5e86 + 527ac99 commit 2f7697f

File tree

2 files changed

+70
-14
lines changed

2 files changed

+70
-14
lines changed

src/main/java/net/imglib2/view/Views.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1450,7 +1450,9 @@ public static < T > IntervalView< T > expandBorder( final RandomAccessibleInterv
14501450
* @return {@link RandomAccessibleInterval} of concatenated sources.
14511451
*/
14521452
@SafeVarargs
1453-
public static < T > RandomAccessibleInterval< T > concatenate( final int concatenationAxis, final RandomAccessibleInterval< T >... sources )
1453+
public static < T > RandomAccessibleInterval< T > concatenate(
1454+
final int concatenationAxis,
1455+
final RandomAccessibleInterval< T >... sources )
14541456
{
14551457
return concatenate( concatenationAxis, StackView.StackAccessMode.DEFAULT, sources );
14561458
}
@@ -1467,7 +1469,9 @@ public static < T > RandomAccessibleInterval< T > concatenate( final int concate
14671469
* {@link RandomAccessibleInterval}s to be concatenated.
14681470
* @return {@link RandomAccessibleInterval} of concatenated sources.
14691471
*/
1470-
public static < T > RandomAccessibleInterval< T > concatenate( final int concatenationAxis, final List< ? extends RandomAccessibleInterval< T > > sources )
1472+
public static < T > RandomAccessibleInterval< T > concatenate(
1473+
final int concatenationAxis,
1474+
final List< ? extends RandomAccessibleInterval< T > > sources )
14711475
{
14721476
return concatenate( concatenationAxis, StackView.StackAccessMode.DEFAULT, sources );
14731477
}
@@ -1489,7 +1493,10 @@ public static < T > RandomAccessibleInterval< T > concatenate( final int concate
14891493
* @return {@link RandomAccessibleInterval} of concatenated sources.
14901494
*/
14911495
@SafeVarargs
1492-
public static < T > RandomAccessibleInterval< T > concatenate( final int concatenationAxis, final StackView.StackAccessMode mode, final RandomAccessibleInterval< T >... sources )
1496+
public static < T > RandomAccessibleInterval< T > concatenate(
1497+
final int concatenationAxis,
1498+
final StackView.StackAccessMode mode,
1499+
final RandomAccessibleInterval< T >... sources )
14931500
{
14941501
return concatenate( concatenationAxis, mode, Arrays.asList( sources ) );
14951502
}
@@ -1510,7 +1517,10 @@ public static < T > RandomAccessibleInterval< T > concatenate( final int concate
15101517
* {@link RandomAccessibleInterval}s to be concatenated.
15111518
* @return {@link RandomAccessibleInterval} of concatenated sources.
15121519
*/
1513-
public static < T > RandomAccessibleInterval< T > concatenate( final int concatenationAxis, final StackView.StackAccessMode mode, final List< ? extends RandomAccessibleInterval< T > > sources )
1520+
public static < T > RandomAccessibleInterval< T > concatenate(
1521+
final int concatenationAxis,
1522+
final StackView.StackAccessMode mode,
1523+
final List< ? extends RandomAccessibleInterval< T > > sources )
15141524
{
15151525

15161526
assert sources.size() > 0;
@@ -1520,7 +1530,8 @@ public static < T > RandomAccessibleInterval< T > concatenate( final int concate
15201530
for ( long index = source.min( concatenationAxis ); index <= source.max( concatenationAxis ); ++index )
15211531
hyperSlices.add( Views.hyperSlice( source, concatenationAxis, index ) );
15221532

1523-
return Views.stack( mode, hyperSlices );
1533+
RandomAccessibleInterval< T > stacked = Views.stack( mode, hyperSlices );
1534+
return Views.moveAxis( stacked, stacked.numDimensions() - 1, concatenationAxis );
15241535
}
15251536

15261537
}

src/test/java/net/imglib2/view/ConcatenateViewTest.java

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,12 @@
3434

3535
package net.imglib2.view;
3636

37+
import java.util.Arrays;
38+
import java.util.List;
3739
import java.util.Random;
3840

41+
import net.imglib2.img.Img;
42+
import net.imglib2.util.ValuePair;
3943
import org.junit.Assert;
4044
import org.junit.Test;
4145

@@ -47,29 +51,66 @@
4751
import net.imglib2.util.Intervals;
4852
import net.imglib2.util.Pair;
4953

54+
import static org.junit.Assert.assertArrayEquals;
55+
5056
/**
57+
* Tests {@link Views#concatenate(int, RandomAccessibleInterval[])}
5158
*
5259
* @author Philipp Hanslovsky
5360
*
5461
*/
5562
public class ConcatenateViewTest
5663
{
5764

58-
private final long[] dim = new long[] { 3, 4, 5, 6 };
59-
60-
private final long divider = 3;
61-
62-
private final int axis = 3;
65+
@Test
66+
public void testConcatenateSimple() {
67+
// setup
68+
Img<ByteType> a = ArrayImgs.bytes( new byte[]{ 1, 2, 3, 4 }, 2, 2 );
69+
Img<ByteType> b = ArrayImgs.bytes( new byte[]{ 7, 8 }, 1, 2 );
70+
Img<ByteType> expected = ArrayImgs.bytes( new byte[]{ 1, 2, 7, 3, 4, 8 }, 3, 2 );
71+
// process
72+
RandomAccessibleInterval< ByteType > result = Views.concatenate( 0, a, b );
73+
// test
74+
assertImageEquals( expected, result );
75+
}
6376

6477
@Test
6578
public void testConcatenate()
79+
{
80+
testConcatenateImpl( new long[] { 3, 4, 5, 6 }, 3, 3 );
81+
}
82+
83+
@Test
84+
public void testConcatenateFirstAxis()
85+
{
86+
testConcatenateImpl( new long[] { 6, 5, 4, 3 }, 0, 3 );
87+
}
88+
89+
private static void testConcatenateImpl( long[] dim, int axis, long divider )
90+
{
91+
// setup
92+
final Img< ByteType > img = createRandomImage( dim );
93+
final List< RandomAccessibleInterval< ByteType > > parts = splitImage( img, axis, divider );
94+
// process
95+
final RandomAccessibleInterval< ByteType > concatenated = Views.concatenate( axis, parts );
96+
// test
97+
assertImageEquals( img, concatenated );
98+
}
99+
100+
private static ArrayImg< ByteType, ByteArray > createRandomImage( long[] dim )
66101
{
67102
final long numElements = Intervals.numElements( dim );
68103
final Random rng = new Random();
69104
final byte[] data = new byte[ ( int ) numElements ];
70105
rng.nextBytes( data );
71-
final ArrayImg< ByteType, ByteArray > img = ArrayImgs.bytes( data, dim );
106+
return ArrayImgs.bytes( data, dim );
107+
}
72108

109+
private static List< RandomAccessibleInterval< ByteType > > splitImage(
110+
RandomAccessibleInterval< ByteType > img,
111+
int axis,
112+
long divider )
113+
{
73114
final long[] min = Intervals.minAsLongArray( img );
74115
final long[] max = Intervals.maxAsLongArray( img );
75116
final long[] min1 = min.clone();
@@ -83,10 +124,14 @@ public void testConcatenate()
83124
final IntervalView< ByteType > interval1 = Views.interval( img, min1, max1 );
84125
final IntervalView< ByteType > interval2 = Views.interval( img, min2, max2 );
85126

86-
final RandomAccessibleInterval< ByteType > concatenated = Views.concatenate( axis, interval1, interval2 );
127+
return Arrays.asList( interval1, interval2 );
128+
}
87129

88-
for ( final Pair< ByteType, ByteType > p : Views.flatIterable( Views.interval( Views.pair( img, concatenated ), img ) ) )
130+
private static void assertImageEquals(
131+
RandomAccessibleInterval< ByteType > expected,
132+
RandomAccessibleInterval< ByteType > actual )
133+
{
134+
for ( final Pair< ByteType, ByteType > p : Views.interval( Views.pair( expected, actual ), expected ) )
89135
Assert.assertEquals( p.getA().getInteger(), p.getB().getInteger() );
90136
}
91-
92137
}

0 commit comments

Comments
 (0)