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; }