public static void Convolve(this Convolution2D <float> convolution, Image <float3> image, Image <float3> output) { var imageWidth = image.Width; var outWidth = output.Width; var outputBuffer = output.Buffer; var stride = convolution.Stride; var kernel = convolution.Kernel2D; var pad = convolution.Padding; var outputRow = 0; for (var r = pad.y; r < image.Height - pad.y; r += stride.y) { var rowIndex = r * imageWidth; var outRowIndex = outputRow * outWidth; for (var c = pad.x; c < imageWidth - pad.x; c += stride.x) { var inIndex = rowIndex + c; var outIndex = outRowIndex + c - pad.x; outputBuffer[outIndex] = kernel.Accumulate(image, inIndex); } outputRow++; } }
public static void Convolve(this Convolution2D <float> convolution, Image <byte> image, Image <float> output) { var outputBuffer = output.Buffer; var imageWidth = image.Width; var stride = convolution.Stride; var kernel = convolution.Kernel2D; var pad = convolution.Padding; for (var r = pad.y; r < image.Height - pad.y; r += stride.y) { var rowIndex = r * imageWidth; for (var c = pad.x; c < imageWidth - pad.x; c += stride.x) { var i = rowIndex + c; outputBuffer[i] = kernel.Accumulate(image, i); } } }
public static Padding GetSamePad <TInput, TConvolution>(Image <TInput> input, Convolution2D <TConvolution> convolution) where TInput : struct where TConvolution : struct { var strides = convolution.Stride; var kernel = convolution.Kernel2D; var outHeight = (int)math.ceil((float)(input.Height - kernel.Height + 1) / strides.y); var outWidth = (int)math.ceil((float)(input.Width - kernel.Width + 1) / strides.x); var padding = new Padding(); var hDiff = input.Height - outHeight; var wDiff = input.Width - outWidth; if (hDiff % 2 == 0) { var halfDiff = hDiff / 2; padding.left += halfDiff; padding.right += halfDiff; } else { var halfDiff = (int)math.floor(hDiff / 2); padding.left += halfDiff; padding.right += halfDiff + 1; } if (wDiff % 2 == 0) { var halfDiff = wDiff / 2; padding.top += halfDiff; padding.bottom += halfDiff; } else { var halfDiff = (int)math.floor(wDiff / 2); padding.top += halfDiff; padding.bottom += halfDiff + 1; } return(padding); }
public static Image <TImage> ConvolutionInput <TImage, TConvolution>(Image <TImage> input, Convolution2D <TConvolution> convolution, ConvolutionPadMode mode = ConvolutionPadMode.Same, TImage constantValue = default(TImage), Allocator allocator = Allocator.Persistent) where TImage : struct where TConvolution : struct { var output = default(Image <TImage>); switch (mode) { case ConvolutionPadMode.Same: var padding = GetSamePad(input, convolution); output = Constant(input, padding, constantValue, allocator); break; case ConvolutionPadMode.Valid: output = Constant(input, new Padding(0), constantValue, allocator); break; } return(output); }