@ -6,8 +6,6 @@
namespace ImageProcessorCore.Samplers
{
using System ;
using System.Collections.Generic ;
using System.Threading.Tasks ;
/// <summary>
/// Provides methods that allow the resampling of images using various algorithms.
@ -54,58 +52,57 @@ namespace ImageProcessorCore.Samplers
/// </returns>
protected Weights [ ] PrecomputeWeights ( int destinationSize , int sourceSize )
{
float xscale = destinationSize / ( float ) sourceSize ;
float width ;
float scale = ( float ) destinationSize / sourceSize ;
IResampler sampler = this . Sampler ;
float fwidth = sampler . Radius ;
float fscale ;
float radius = sampler . Radius ;
double left ;
double right ;
double weight = 0 ;
int n = 0 ;
int k ;
double weight ;
int index ;
int sum ;
Weights [ ] result = new Weights [ destinationSize ] ;
// When expand ing, broaden the effective kernel support so that we still
// When shrink ing, broaden the effective kernel support so that we still
// visit every source pixel.
if ( x scale < 0 )
if ( scale < 1 )
{
width = sampler . R adius / x scale;
fs cale = 1 / x scale;
float width = r adius / scale ;
float filterS cale = 1 / scale ;
// Make the weights slices, one source for each column or row.
for ( int i = 0 ; i < destinationSize ; i + + )
{
float centre = i / x scale;
float centre = i / scale ;
left = Math . Ceiling ( centre - width ) ;
right = Math . Floor ( centre + width ) ;
float sum = 0 ;
result [ i ] = new Weights ( ) ;
List < Weight > builder = new List < Weight > ( ) ;
result [ i ] = new Weights
{
Sum = 0 ,
Values = new Weight [ ( int ) Math . Floor ( 2 * width + 1 ) ]
} ;
for ( double j = left ; j < = right ; j + + )
{
weight = centre - j ;
weight = sampler . GetValue ( ( float ) weight / fscale ) / fscale ;
weight = sampler . GetValue ( ( float ) ( weight / filterScale ) ) / filterS cale ;
if ( j < 0 )
{
n = ( int ) - j ;
i ndex = ( int ) - j ;
}
else if ( j > = sourceSize )
{
n = ( int ) ( ( sourceSize - j ) + sourceSize - 1 ) ;
i ndex = ( int ) ( ( sourceSize - j ) + sourceSize - 1 ) ;
}
else
{
n = ( int ) j ;
i ndex = ( int ) j ;
}
sum + + ;
builder . Add ( new Weight ( n , ( float ) weight ) ) ;
sum = ( int ) result [ i ] . Sum + + ;
result [ i ] . Values [ sum ] = new Weight ( index , ( float ) weight ) ;
}
result [ i ] . Values = builder . ToArray ( ) ;
result [ i ] . Sum = sum ;
}
}
else
@ -113,122 +110,46 @@ namespace ImageProcessorCore.Samplers
// Make the weights slices, one source for each column or row.
for ( int i = 0 ; i < destinationSize ; i + + )
{
float centre = i / xscale ;
left = Math . Ceiling ( centre - fwidth ) ;
right = Math . Floor ( centre + fwidth ) ;
float sum = 0 ;
result [ i ] = new Weights ( ) ;
float centre = i / scale ;
left = Math . Ceiling ( centre - radius ) ;
right = Math . Floor ( centre + radius ) ;
result [ i ] = new Weights
{
Sum = 0 ,
Values = new Weight [ ( int ) ( radius * 2 + 1 ) ]
} ;
List < Weight > builder = new List < Weight > ( ) ;
for ( double j = left ; j < = right ; j + + )
{
weight = centre - j ;
weight = sampler . GetValue ( ( float ) weight ) ;
if ( j < 0 )
{
n = ( int ) - j ;
i ndex = ( int ) - j ;
}
else if ( j > = sourceSize )
{
n = ( int ) ( ( sourceSize - j ) + sourceSize - 1 ) ;
i ndex = ( int ) ( ( sourceSize - j ) + sourceSize - 1 ) ;
}
else
{
n = ( int ) j ;
i ndex = ( int ) j ;
}
sum + + ;
builder . Add ( new Weight ( n , ( float ) weight ) ) ;
sum = ( int ) result [ i ] . Sum + + ;
result [ i ] . Values [ sum ] = new Weight ( index , ( float ) weight ) ;
}
result [ i ] . Values = builder . ToArray ( ) ;
result [ i ] . Sum = sum ;
}
}
return result ;
}
//protected Weights[] PrecomputeWeights(int destinationSize, int sourceSize)
//{
// IResampler sampler = this.Sampler;
// float ratio = sourceSize / (float)destinationSize;
// float scale = ratio;
// // When shrinking, broaden the effective kernel support so that we still
// // visit every source pixel.
// if (scale < 1)
// {
// scale = 1;
// }
// float scaledRadius = (float)Math.Ceiling(scale * sampler.Radius);
// Weights[] result = new Weights[destinationSize];
// // Make the weights slices, one source for each column or row.
// Parallel.For(
// 0,
// destinationSize,
// i =>
// {
// float center = ((i + .5f) * ratio) - 0.5f;
// int start = (int)Math.Ceiling(center - scaledRadius);
// if (start < 0)
// {
// start = 0;
// }
// int end = (int)Math.Floor(center + scaledRadius);
// if (end > sourceSize)
// {
// end = sourceSize;
// if (end < start)
// {
// end = start;
// }
// }
// float sum = 0;
// result[i] = new Weights();
// List<Weight> builder = new List<Weight>();
// for (int a = start; a < end; a++)
// {
// float w = sampler.GetValue((a - center) / scale);
// if (w < 0 || w > 0)
// {
// sum += w;
// builder.Add(new Weight(a, w));
// }
// }
// // Normalise the values
// if (sum > 0 || sum < 0)
// {
// builder.ForEach(w => w.Value /= sum);
// }
// result[i].Values = builder.ToArray();
// result[i].Sum = sum;
// });
// return result;
//}
/// <summary>
/// Represents the weight to be added to a scaled pixel.
/// </summary>
protected class Weight
protected struct Weight
{
/// <summary>
/// The pixel index.
/// </summary>
public readonly int Index ;
/// <summary>
/// Initializes a new instance of the <see cref="Weight"/> class.
/// </summary>
@ -241,9 +162,14 @@ namespace ImageProcessorCore.Samplers
}
/// <summary>
/// Gets or sets the result of the interpolation algorithm.
/// Gets the pixel index.
/// </summary>
public int Index { get ; }
/// <summary>
/// Gets the result of the interpolation algorithm.
/// </summary>
public float Value { get ; set ; }
public float Value { get ; }
}
/// <summary>
@ -262,4 +188,4 @@ namespace ImageProcessorCore.Samplers
public float Sum { get ; set ; }
}
}
}
}