public static float[] MedianFilter(float[] input, int size)
{
if (input == null)
throw new ArgumentNullException();
if (input.Length <= 0)
throw new ArgumentException("Input array must have length longer than zero.");
if (input.Length <= size)
throw new ArgumentException("Input array must be longer then or equal to mask size.");
if (size < 3)
throw new ArgumentException("Size must be bigger then 3.");
if (size % 2 == 0)
throw new ArgumentException("Size must be odd.");
// Allocate output
float[] output = new float[input.Length];
// Find buffer size
int bSize = 0;
int errCode = 0;
errCode = ippsFilterMedianGetBufferSize(size, IppDataType.ipp32f, &bSize);
ErrorHandling.HandleReturnValue(errCode);
byte[] buffer = new byte[bSize];
// Do the actual filtering
errCode = 0;
int halfFilterSize = (size - 1) / 2;
fixed (float* pInput = &input[halfFilterSize])
fixed (float* pOutput = &output[0])
fixed (byte* pBuffer = &buffer[0])
{
errCode = ippsFilterMedian_32f(pInput, pOutput, input.Length - halfFilterSize, size, null, null, pBuffer);
}
ErrorHandling.HandleReturnValue(errCode);
// Return only valid part
int validLength = input.Length - size + 1;
float[] outputValidRegion = new float[validLength];
Array.Copy(output, halfFilterSize, outputValidRegion, 0, validLength);
return outputValidRegion;
}
///
/// Median filters the input array using a median filter of provided length.
/// There are no borders (or edge artifacts) as the input is considered circular.
/// If the filter length is 3 and the input is of length n, then each output element is computed as:
/// output[0] = median( input[n], input[0], input[1]) (Note the warp around to input element n)
/// output[1] = median( input[0], input[1], input[2])
/// output[2] = median( input[1], input[2], input[3])
/// ...
/// output[n-1] = median( input[n-2], input[n-1], input[n])
/// output[n] = median( input[n-1], input[n], input[0]) (Note the warp around to input element 0)
///
///
///
///
public static float[] MedianFilterCircular(float[] input, int size)
{
if (input == null)
throw new ArgumentNullException();
if (input.Length <= 0)
throw new ArgumentException("Input array must have length longer than zero.");
if (input.Length <= size)
throw new ArgumentException("Input array must be longer then or equal to mask size.");
if (size < 3)
throw new ArgumentException("Size must be bigger then 3.");
if (size % 2 == 0)
throw new ArgumentException("Size must be odd.");
// Allocate output
float[] output = new float[input.Length];
// Find buffer size
int bSize = 0;
int errCode = 0;
errCode = ippsFilterMedianGetBufferSize(size, IppDataType.ipp32f, &bSize);
ErrorHandling.HandleReturnValue(errCode);
byte[] buffer = new byte[bSize];
// Do the actual filtering
errCode = 0;
fixed (float* pDlySrc = &input[input.Length - size + 1])
fixed (float* pInput = &input[0])
fixed (float* pOutput = &output[0])
fixed (byte* pBuffer = &buffer[0])
{
errCode = ippsFilterMedian_32f(pInput, pOutput, input.Length, size, pDlySrc, null, pBuffer);
}
ErrorHandling.HandleReturnValue(errCode);
// Swap the two parts of the output to make the filtering centered
int halfFilterSize = (size - 1) / 2;
float[] outputReordered = new float[output.Length];
Array.Copy(output, halfFilterSize, outputReordered, 0, output.Length - halfFilterSize);
Array.Copy(output, 0, outputReordered, output.Length - halfFilterSize, halfFilterSize);
return outputReordered;
}