Skip to content

Commit 82573a8

Browse files
committed
feat: add Downsample from bdv
1 parent 9e77b3b commit 82573a8

1 file changed

Lines changed: 97 additions & 0 deletions

File tree

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* Copied from bdv.export.Downsample (bigdataviewer-core), since it was removed in
3+
* bigdataviewer-core 10.5.0.
4+
* Original license below.
5+
*
6+
* #%L
7+
* BigDataViewer core classes with minimal dependencies.
8+
* %%
9+
* Copyright (C) 2012 - 2024 BigDataViewer developers.
10+
* %%
11+
* Redistribution and use in source and binary forms, with or without
12+
* modification, are permitted provided that the following conditions are met:
13+
*
14+
* 1. Redistributions of source code must retain the above copyright notice,
15+
* this list of conditions and the following disclaimer.
16+
* 2. Redistributions in binary form must reproduce the above copyright notice,
17+
* this list of conditions and the following disclaimer in the documentation
18+
* and/or other materials provided with the distribution.
19+
*
20+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30+
* POSSIBILITY OF SUCH DAMAGE.
31+
* #L%
32+
*/
33+
package org.janelia.saalfeldlab.n5.spark.util;
34+
35+
import net.imglib2.Cursor;
36+
import net.imglib2.FinalInterval;
37+
import net.imglib2.Interval;
38+
import net.imglib2.RandomAccess;
39+
import net.imglib2.RandomAccessible;
40+
import net.imglib2.RandomAccessibleInterval;
41+
import net.imglib2.algorithm.neighborhood.Neighborhood;
42+
import net.imglib2.algorithm.neighborhood.RectangleNeighborhoodFactory;
43+
import net.imglib2.algorithm.neighborhood.RectangleNeighborhoodUnsafe;
44+
import net.imglib2.algorithm.neighborhood.RectangleShape;
45+
import net.imglib2.type.numeric.RealType;
46+
import net.imglib2.view.Views;
47+
48+
public class Downsample
49+
{
50+
/**
51+
* TODO: Revise. This is probably not very efficient
52+
*/
53+
public static < T extends RealType< T > > void downsample( final RandomAccessible< T > input, final RandomAccessibleInterval< T > output, final int[] factor )
54+
{
55+
assert input.numDimensions() == output.numDimensions();
56+
assert input.numDimensions() == factor.length;
57+
58+
final int n = input.numDimensions();
59+
final RectangleNeighborhoodFactory< T > f = RectangleNeighborhoodUnsafe.< T >factory();
60+
final long[] dim = new long[ n ];
61+
for ( int d = 0; d < n; ++d )
62+
dim[ d ] = factor[ d ];
63+
final Interval spanInterval = new FinalInterval( dim );
64+
65+
final long[] minRequiredInput = new long[ n ];
66+
final long[] maxRequiredInput = new long[ n ];
67+
output.min( minRequiredInput );
68+
output.max( maxRequiredInput );
69+
for ( int d = 0; d < n; ++d )
70+
{
71+
minRequiredInput[ d ] *= factor[ d ];
72+
maxRequiredInput[ d ] *= factor[ d ];
73+
maxRequiredInput[ d ] += factor[ d ] - 1;
74+
}
75+
final RandomAccessibleInterval< T > requiredInput = Views.interval( input, new FinalInterval( minRequiredInput, maxRequiredInput ) );
76+
77+
final RectangleShape.NeighborhoodsAccessible< T > neighborhoods = new RectangleShape.NeighborhoodsAccessible<>( requiredInput, spanInterval, f );
78+
final RandomAccess< Neighborhood< T > > block = neighborhoods.randomAccess();
79+
80+
long size = 1;
81+
for ( int d = 0; d < n; ++d )
82+
size *= factor[ d ];
83+
final double scale = 1.0 / size;
84+
85+
final Cursor< T > out = Views.iterable( output ).localizingCursor();
86+
while( out.hasNext() )
87+
{
88+
final T o = out.next();
89+
for ( int d = 0; d < n; ++d )
90+
block.setPosition( out.getLongPosition( d ) * factor[ d ], d );
91+
double sum = 0;
92+
for ( final T i : block.get() )
93+
sum += i.getRealDouble();
94+
o.setReal( sum * scale );
95+
}
96+
}
97+
}

0 commit comments

Comments
 (0)