public static Image1f CreateGaussiankernel( float sigma ) { float sigmaSquared = sigma * sigma; float twoSigma = 2.0f * sigma; int radius = twoSigma.CeilToInt(); int diameter = 2 * radius + 1; Image1f kernel = new Image1f( diameter, diameter ); float sum = 0; for( int y = 0; y < diameter; ++y ) { int dy = y - radius; for( int x = 0; x < diameter; ++x ) { int dx = x - radius; float val = ( float )( Math.Exp( -0.5f * ( dx * dx + dy * dy ) / sigmaSquared ) ); sum += val; kernel[ x, y ] = val; } } for( int y = 0; y < diameter; ++y ) { for( int x = 0; x < diameter; ++x ) { kernel[ x, y ] /= sum; } } return kernel; }
public void Apply( Image1f input, Image1f output ) { float[,] controlPoints = new float[ 4, 4 ]; int w_out = output.Width; int h_out = output.Height; int w_in = input.Width; int h_in = input.Height; // scaling coefficients float x_outToIn = Arithmetic.DivideIntsToFloat( w_in, w_out ); float y_outToIn = Arithmetic.DivideIntsToFloat( h_in, h_out ); for( int yOut = 0; yOut < h_out; ++yOut ) { float yInFloat = ( yOut + 0.5f ) * y_outToIn; int yIn0 = yInFloat.FloorToInt() - 1; int yIn1 = yIn0 + 3; for( int xOut = 0; xOut < w_out; ++xOut ) { float xInFloat = ( xOut + 0.5f ) * x_outToIn; int xIn0 = xInFloat.FloorToInt() - 1; int xIn1 = xIn0 + 3; // grab the 16 control points for( int yc = yIn0; yc <= yIn1; ++yc ) { int dy = yc - yIn0; int ycc = Arithmetic.Clamp( yc, 0, h_in ); for( int xc = xIn0; xc <= xIn1; ++xc ) { int dx = xc - xIn0; int xcc = Arithmetic.Clamp( xc, 0, w_in ); controlPoints[ xc, yc ] = input[ xcc, ycc ]; } } // compute Catmull-Rom splines in the x direction float tx = Arithmetic.FractionalPart( xInFloat ); float ty = Arithmetic.FractionalPart( yInFloat ); var v0i = EvaluateSpline( controlPoints[ 0, 0 ], controlPoints[ 0, 1 ], controlPoints[ 0, 2 ], controlPoints[ 0, 3 ], tx ); var v1i = EvaluateSpline( controlPoints[ 1, 0 ], controlPoints[ 1, 1 ], controlPoints[ 1, 2 ], controlPoints[ 1, 3 ], tx ); var v2i = EvaluateSpline( controlPoints[ 2, 0 ], controlPoints[ 2, 1 ], controlPoints[ 2, 2 ], controlPoints[ 2, 3 ], tx ); var v3i = EvaluateSpline( controlPoints[ 3, 0 ], controlPoints[ 3, 1 ], controlPoints[ 3, 2 ], controlPoints[ 3, 3 ], tx ); var vii = EvaluateSpline( v0i, v1i, v2i, v3i, ty ); output[ xOut, yOut ] = vii; } } }
public static void Apply( Image1f input, Image1f output ) { if( input.Size != output.Size ) { throw new ArgumentException( "input and output must be of the same size" ); } float min; float max; input.Pixels.MinMax( f => f, out min, out max ); float reciprocalRange = 1.0f / ( max - min ); for( int k = 0; k < input.NumPixels; ++k ) { float vIn = input[ k ]; float vOut = ( vIn - min ) * reciprocalRange; output[ k ] = vOut; } }
public static Vector2f SnapToEdge( Image1f gradientNorm, Vector2f p, int radius ) { Vector2i q = p.RoundToInt(); float max = float.NegativeInfinity; Vector2f maxQ = Vector2f.Zero; for( int y = q.y - radius; y <= q.y + radius; ++y ) { for( int x = q.x - radius; x <= q.x + radius; ++x ) { float gn = gradientNorm[ x, y ]; if( gn > max ) { max = gn; maxQ = new Vector2f( x, y ); } } } return maxQ; }
public static void CopySubImage( Image1f source, int sx, int sy, Image1f target, int tx, int ty, int width, int height ) { int sw = source.Width; int sh = source.Height; int tw = target.Width; int th = target.Height; if( sx < 0 || sy < 0 || sx >= sw || sy >= sh ) { throw new IndexOutOfRangeException( "Source origin must be inside source image" ); } if( tx < 0 || ty < 0 || tx >= tw || ty >= th ) { throw new IndexOutOfRangeException( "Target origin must be inside target image" ); } int tx0 = tx; int tx1 = Math.Min( tx + width, tw ); int ty0 = ty; int ty1 = Math.Min( ty + height, th ); for( int y = ty0; y < ty1; ++y ) { int dy = y - ty0; int iy = sy + dy.Clamp( 0, sh ); for( int x = tx0; x < tx1; ++x ) { int dx = x - tx0; int ix = ( sx + dx ).Clamp( 0, sw ); target[ x, y ] = source[ ix, iy ]; } } }
public static void Apply( Image1f input, Image1f output ) { int w_out = output.Width; int h_out = output.Height; int w_in = input.Width; int h_in = input.Height; // scaling coefficients float x_outToIn = Arithmetic.DivideIntsToFloat( w_in, w_out ); float y_outToIn = Arithmetic.DivideIntsToFloat( h_in, h_out ); for( int yOut = 0; yOut < h_out; ++yOut ) { float yInFloat = ( yOut + 0.5f ) * y_outToIn; for( int xOut = 0; xOut < w_out; ++xOut ) { float xInFloat = ( xOut + 0.5f ) * x_outToIn; output[ xOut, yOut ] = input.BilinearSample( xInFloat, yInFloat ); } } }