import ij.ImageJ;
import ij.ImagePlus;
import ij.gui.OvalRoi;
import ij.process.ByteProcessor;
import ij.process.ColorProcessor;
import ij.process.FloatProcessor;
import ij.process.ImageProcessor;
import ij.process.ShortProcessor;
import ini.trakem2.imaging.FastIntegralImage;
import mpicbg.trakem2.util.Downsampler;
import mpicbg.trakem2.util.Downsampler.Pair;
import mpicbg.util.Timer;
/**
* License: GPL
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/**
*
*
* @author Stephan Saalfeld <saalfeld@mpi-cbg.de>
* @version 0.1a
*/
public class DownsamplerTest
{
final static int n = 20;
final private static void testShort( ShortProcessor ipShort )
{
final double min = ipShort.getMin();
final double max = ipShort.getMax();
while( ipShort.getWidth() > 32 )
{
ipShort = Downsampler.downsampleShortProcessor( ipShort );
ipShort.setMinAndMax( min, max );
}
}
final private static void testFloat( FloatProcessor ipFloat )
{
final double min = ipFloat.getMin();
final double max = ipFloat.getMax();
while( ipFloat.getWidth() > 32 )
{
ipFloat = Downsampler.downsampleFloatProcessor( ipFloat );
ipFloat.setMinAndMax( min, max );
}
}
final private static void testByte( ByteProcessor ipByte )
{
while( ipByte.getWidth() > 32 )
ipByte = Downsampler.downsampleByteProcessor( ipByte );
}
final private static void testColor( ColorProcessor ipColor )
{
while( ipColor.getWidth() > 32 )
ipColor = Downsampler.downsampleColorProcessor( ipColor );
}
/**
* Test downsampling the pyramid of a short image + byte alpha channel
* including the byte mapping of the short doing the alpha channel in a
* separate loop.
*
* @param ba
*/
final private static void testShortAlphaIndependently( Pair< ShortProcessor, byte[] > ba, ByteProcessor alpha )
{
while( ba.a.getWidth() > 32 )
{
ba = Downsampler.downsampleShort( ba.a );
alpha = Downsampler.downsampleByteProcessor( alpha );
// new ImagePlus( "pixels " + ba.a.getWidth(), ba.a ).show();
// new ImagePlus( "pixels to byte " + ba.a.getWidth(), new ByteProcessor( ba.a.getWidth(), ba.a.getHeight(), ba.b[ 0 ], null ) ).show();
// new ImagePlus( "alpha " + ba.a.getWidth(), new ByteProcessor( ba.a.getWidth(), ba.a.getHeight(), ba.b[ 1 ], null ) ).show();
}
}
/**
* Test downsampling the pyramid of a short image + byte alpha channel
* including the byte mapping of the short all in separate loops.
*
* @param ba
*/
final private static void testShortAlphaByteMappingIndependently( ShortProcessor sp, ByteProcessor alpha )
{
ByteProcessor bp;
while( sp.getWidth() > 32 )
{
sp = Downsampler.downsampleShortProcessor( sp );
bp = ( ByteProcessor )sp.convertToByte( true );
alpha = Downsampler.downsampleByteProcessor( alpha );
// new ImagePlus( "pixels " + ba.a.getWidth(), ba.a ).show();
// new ImagePlus( "pixels to byte " + ba.a.getWidth(), new ByteProcessor( ba.a.getWidth(), ba.a.getHeight(), ba.b[ 0 ], null ) ).show();
// new ImagePlus( "alpha " + ba.a.getWidth(), new ByteProcessor( ba.a.getWidth(), ba.a.getHeight(), ba.b[ 1 ], null ) ).show();
}
}
/**
* Test downsampling the pyramid of a short image + byte alpha channel
* including the byte mapping of the short doing the alpha channel in a
* separate loop.
*
* @param ba
*/
final private static void testFloatAlphaIndependently( Pair< FloatProcessor, byte[] > ba, ByteProcessor alpha )
{
while( ba.a.getWidth() > 32 )
{
ba = Downsampler.downsampleFloat( ba.a );
alpha = Downsampler.downsampleByteProcessor( alpha );
// new ImagePlus( "pixels " + ba.a.getWidth(), ba.a ).show();
// new ImagePlus( "pixels to byte " + ba.a.getWidth(), new ByteProcessor( ba.a.getWidth(), ba.a.getHeight(), ba.b[ 0 ], null ) ).show();
// new ImagePlus( "alpha " + ba.a.getWidth(), new ByteProcessor( ba.a.getWidth(), ba.a.getHeight(), ba.b[ 1 ], null ) ).show();
}
}
/**
* Test downsampling the pyramid of a short image + byte alpha channel
* including the byte mapping of the short doing the alpha channel in a
* separate loop.
*
* @param ba
*/
final private static void testColorAlphaIndependently( Pair< ColorProcessor, byte[][] > ba, ByteProcessor alpha )
{
while( ba.a.getWidth() > 32 )
{
ba = Downsampler.downsampleColor( ba.a );
alpha = Downsampler.downsampleByteProcessor( alpha );
// new ImagePlus( "pixels " + ba.a.getWidth(), ba.a ).show();
// new ImagePlus( "pixels to byte " + ba.a.getWidth(), new ByteProcessor( ba.a.getWidth(), ba.a.getHeight(), ba.b[ 0 ], null ) ).show();
// new ImagePlus( "alpha " + ba.a.getWidth(), new ByteProcessor( ba.a.getWidth(), ba.a.getHeight(), ba.b[ 1 ], null ) ).show();
}
}
final private static void testAlphaOutside( Pair< ByteProcessor, ByteProcessor > ba )
{
while( ba.a.getWidth() > 32 )
{
ba = Downsampler.downsampleAlphaAndOutside( ba.a, ba.b );
// new ImagePlus( "alpha " + ba.a.getWidth(), ba.a ).show();
// new ImagePlus( "outside " + ba.b.getWidth(), ba.b ).show();
}
}
final private static void testOutside( ByteProcessor a )
{
while( a.getWidth() > 32 )
{
a = Downsampler.downsampleOutside( a );
// new ImagePlus( "alpha " + ba.a.getWidth(), ba.a ).show();
// new ImagePlus( "outside " + ba.b.getWidth(), ba.b ).show();
}
}
final private static void testByteIntegral( ByteProcessor ipByte )
{
while( ipByte.getWidth() > 32 )
{
int w = ipByte.getWidth(),
h = ipByte.getHeight();
long[] l = FastIntegralImage.longIntegralImage((byte[])ipByte.getPixels(), w, h);
ipByte = new ByteProcessor(
w/2, h/2,
FastIntegralImage.scaleAreaAverage(l, w+1, h+1, w/2, h/2),
null);
}
}
/**
* @param args
*/
public static void main( final String[] args )
{
new ImageJ();
final Timer timer = new Timer();
final ImagePlus imp = new ImagePlus( "/home/saalfeld/tmp/fetter-example.tif" );
//final ImagePlus imp = new ImagePlus( "/home/albert/Desktop/t2/fetter-example.tif" );
//final ImagePlus imp = new ImagePlus( "/home/saalfeld/Desktop/norway.jpg" );
imp.show();
final ImageProcessor ip = imp.getProcessor().duplicate();
System.out.println( "short" );
final ShortProcessor ipShort = ( ShortProcessor )ip.convertToShort( false );
for ( int i = 0; i < n; ++i )
{
timer.start();
testShort( ipShort );
final long t = timer.stop();
System.out.println( i + ": " + t + "ms" );
}
System.out.println( "downsampleShort() + downsampleByteProcessor() (independent short with byte mapping + alpha)" );
for ( int i = 0; i < n; ++i )
{
final Pair< ShortProcessor, byte[] > ba = new Pair< ShortProcessor, byte[] >( ipShort, ( byte[] )ipShort.convertToByte( true ).getPixels() );
final ByteProcessor alpha = new ByteProcessor( ipShort.getWidth(), ipShort.getHeight(), ( byte[] )ipShort.convertToByte( true ).getPixels(), null );
timer.start();
testShortAlphaIndependently( ba, alpha );
final long t = timer.stop();
System.out.println( i + ": " + t + "ms" );
}
System.out.println( "downsampleShortProcessor() + convertToByte() + downsampleByteProcessor() (independent short + byte mapping + alpha)" );
for ( int i = 0; i < n; ++i )
{
final ByteProcessor alpha = new ByteProcessor( ipShort.getWidth(), ipShort.getHeight(), ( byte[] )ipShort.convertToByte( true ).getPixels(), null );
timer.start();
testShortAlphaByteMappingIndependently( ipShort, alpha );
final long t = timer.stop();
System.out.println( i + ": " + t + "ms" );
}
System.out.println( "float" );
final FloatProcessor ipFloat = ( FloatProcessor )ip.convertToFloat();
for ( int i = 0; i < n; ++i )
{
timer.start();
testFloat( ipFloat );
final long t = timer.stop();
System.out.println( i + ": " + t + "ms" );
}
System.out.println( "independent float with byte mapping + alpha" );
for ( int i = 0; i < n; ++i )
{
final Pair< FloatProcessor, byte[] > ba = new Pair< FloatProcessor, byte[] >( ipFloat, ( byte[] )ipShort.convertToByte( true ).getPixels() );
final ByteProcessor alpha = new ByteProcessor( ipShort.getWidth(), ipShort.getHeight(), ( byte[] )ipShort.convertToByte( true ).getPixels(), null );
timer.start();
testFloatAlphaIndependently( ba, alpha );
final long t = timer.stop();
System.out.println( i + ": " + t + "ms" );
}
System.out.println( "byte" );
final ByteProcessor ipByte = ( ByteProcessor )ip.convertToByte( true );
for ( int i = 0; i < n; ++i )
{
timer.start();
testByte( ipByte );
final long t = timer.stop();
System.out.println( i + ": " + t + "ms" );
}
System.out.println( "2 x byte" );
final ByteProcessor ipByte2 = ( ByteProcessor )ipByte.duplicate();
for ( int i = 0; i < n; ++i )
{
timer.start();
testByte( ipByte );
testByte( ipByte2 );
final long t = timer.stop();
System.out.println( i + ": " + t + "ms" );
}
System.out.println( "color" );
final ColorProcessor ipColor = ( ColorProcessor )ip.convertToRGB();
for ( int i = 0; i < n; ++i )
{
timer.start();
testColor( ipColor );
final long t = timer.stop();
System.out.println( i + ": " + t + "ms" );
}
System.out.println( "independent color with byte mapping + alpha" );
for ( int i = 0; i < n; ++i )
{
final byte[][] rgb = new byte[ 4 ][ ipColor.getWidth() * ipColor.getHeight() ];
ipColor.getRGB( rgb[ 0 ], rgb[ 1 ], rgb[ 2 ] );
final Pair< ColorProcessor, byte[][] > ba = new Pair< ColorProcessor, byte[][] >( ipColor, rgb );
final ByteProcessor alpha = new ByteProcessor( ipShort.getWidth(), ipShort.getHeight(), ( byte[] )ipShort.convertToByte( true ).getPixels(), null );
timer.start();
testColorAlphaIndependently( ba, alpha );
final long t = timer.stop();
System.out.println( i + ": " + t + "ms" );
}
System.out.println( "alpha + outside" );
for ( int i = 0; i < n; ++i )
{
ByteProcessor outside = new ByteProcessor( ipByte.getWidth(), ipByte.getHeight() );
outside.setRoi( new OvalRoi( 100, 100, ipByte.getWidth() - 200, ipByte.getHeight() - 200 ) );
outside.setValue( 255 );
outside.fill(outside.getMask());
final Pair< ByteProcessor, ByteProcessor > ba = new Pair< ByteProcessor, ByteProcessor >( ipByte, outside );
timer.start();
testAlphaOutside( ba );
final long t = timer.stop();
System.out.println( i + ": " + t + "ms" );
}
System.out.println( "outside" );
for ( int i = 0; i < n; ++i )
{
ByteProcessor outside = new ByteProcessor( ipByte.getWidth(), ipByte.getHeight() );
outside.setRoi( new OvalRoi( 100, 100, ipByte.getWidth() - 200, ipByte.getHeight() - 200 ) );
outside.setValue( 255 );
outside.fill(outside.getMask());
timer.start();
testOutside( outside );
final long t = timer.stop();
System.out.println( i + ": " + t + "ms" );
}
// System.out.println( "byte integral" );
// final ByteProcessor ipByteI = ( ByteProcessor )ipShort.convertToByte( true );
//
// for ( int i = 0; i < 10; ++i )
// {
// timer.start();
// testByteIntegral( ipByteI );
// final long t = timer.stop();
// System.out.println( i + ": " + t + "ms" );
// }
}
}