1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
|
double piSquare = Math.PI * Math.PI;
int preCalculationScale = 10;
int a = 5;
double[] sinc = new double[ a * preCalculationScale + 2 ];;
int scale = 100;
red = 0x00ff0000;
green = 0x0000ff00;
double[] preCalculateSinc( int max, int scale )
{
double[] sinc = new double[ max * scale + 2 ];
for ( int i = 0; i < sinc.length; ++i )
{
double x = ( double )i / ( double )preCalculationScale;
sinc[ i ] = sinc( x, max );
}
return sinc;
}
double sinc( double x, double a )
{
if ( x == 0 )
return 1;
else
return (( a * Math.sin( Math.PI * x ) * Math.sin( Math.PI * x / a ) ) / ( piSquare * x * x ));
}
double sinc2( double x )
{
double y = x < 0 ? -preCalculationScale * x : preCalculationScale * x;
int yi = ( int )y;
double d = y - yi;
return ( sinc[ yi + 1 ] - sinc[ yi ] ) * d + sinc[ yi ];
}
sinc = preCalculateSinc( a, preCalculationScale );
ip = new ColorProcessor( a * scale, 2 * scale );
for ( int x = 0; x < ip.getWidth(); ++x )
{
v = sinc( ( double )x / scale, a );
ip.putPixel( x, scale - ( int )Math.round( v * scale ), green );
v = sinc2( ( double )x / scale );
yi = scale - ( int )Math.round( v * scale );
ip.putPixel( x, yi, ip.get( x, yi ) | red );
}
new ImagePlus( "Lanczos kernel", ip ).show();
ipKernel = new ColorProcessor( 2 * a * scale, 2 * a * scale );
impKernel = new ImagePlus( "Lanczos Kernel", ipKernel );
impKernel.show();
for ( int y = 0; y < ipKernel.getHeight(); ++y )
{
vSinc = sinc( ( double )y / scale - a, a );
vSinc2 = sinc2( ( double )y / scale - a );
for ( int x = 0; x < ipKernel.getWidth(); ++x )
{
v = vSinc * sinc( ( double )x / scale - a, a );
rgb = ( int )Math.round( 127 + v * 127 ) << 8;
v = vSinc2 * sinc2( ( double )x / scale - a );
rgb |= ( int )Math.round( 127 + v * 127 ) << 16;
ipKernel.putPixel( x, y, rgb );
}
impKernel.updateAndDraw();
}
|