SDDSlib
Loading...
Searching...
No Matches
medianfilter.c
Go to the documentation of this file.
1/**
2 * @file medianfilter.c
3 * @brief Core MEX routine implementing a fast version of the classical 1D running median filter of size W, where W is odd.
4 *
5 * @copyright
6 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
7 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
8 *
9 * @license
10 * This file is distributed under the terms of the Software License Agreement
11 * found in the file LICENSE included with this distribution.
12 *
13 * @author M.A. Little, N.S. Jones, H. Shang, R. Soliday
14 */
15/*this was modified from fastmedfilt1d_core.c wrote by M.A. Little, N.S. Jones
16 following is their documention */
17/*
18 Core MEX routine implementing a fast version of the classical 1D running
19 median filter of size W, where W is odd.
20
21 Usage:
22 m = fastmedfilt1d_core(x, xic, xfc, W2)
23
24 Input arguments:
25 - x Input signal
26 - xic Initial boundary condition
27 - xfc End boundary condition
28 - W2 Half window size (so that window size is W=2*W2+1)
29
30 Output arguments:
31 - m Median filtered signal
32
33 (c) Max Little, 2010. If you use this code, please cite:
34 Little, M.A. and Jones, N.S. (2010),
35 "Sparse Bayesian Step-Filtering for High-Throughput Analysis of Molecular
36 Machine Dynamics"
37 in Proceedings of ICASSP 2010, IEEE Publishers: Dallas, USA.
38
39 This ZIP file contains a fast Matlab implementation of 1D median filtering.
40 With the MEX core routine compiled using a decent compiler, compared against
41 Matlab's own proprietary toolbox implementation, this algorithm easily
42 achieves 10:1 performance gains for large window sizes. Note that, although
43 there are more efficient algorithms used in 2D image processing, these are
44 restricted to integer-valued data.
45
46 If you use this code for your research, please cite [1].
47
48 References:
49
50 [1] M.A. Little, N.S. Jones (2010), Sparse Bayesian Step-Filtering for High-
51 Throughput Analysis of Molecular Machine Dynamics in 2010 IEEE International
52 Conference on Acoustics, Speech and Signal Processing, 2010. ICASSP 2010
53 Proceedings.: Dallas, TX, USA (in press)
54
55 ZIP file contents:
56
57 fastmedfilt1d.m - The main routine. This calls the MEX core routine described
58 below. Ensure this file is placed in the same directory as the MEX files
59 below. Typing 'help fastmedfilt1d' gives usage instructions.
60
61 fastmedfilt1d_core.c - Core routine for performing running median filtering,
62 written in C with Matlab MEX integration.
63
64 fastmedfilt1d_core.mexw32 - Above code compiled as a Matlab version 7 or
65 greater library for direct use with Matlab under Windows 32. Place the
66 library in a directory accessible to Matlab and invoke as with any other
67 function.
68*/
69
70/* H. Shang modified fastmedfilt1d_core.c to be able to call by C routines outside matlab
71 environment. April, 2015
72 modifications: depending on the window size, appending repeating values of the first and last value to
73 make full window size for the boundaries (first and last point).
74*/
75
76#include "mdb.h"
77
78#define SWAP(a, b) \
79 { \
80 register double t = (a); \
81 (a) = (b); \
82 (b) = t; \
83 }
84
85double quickSelect(double *arr, int n) {
86 long low, high;
87 long median;
88 long middle, ll, hh;
89
90 low = 0;
91 high = n - 1;
92 median = (low + high) / 2;
93 while (1) {
94 /* One element only */
95 if (high <= low)
96 return arr[median];
97
98 /* Two elements only */
99 if (high == low + 1) {
100 if (arr[low] > arr[high])
101 SWAP(arr[low], arr[high]);
102 return arr[median];
103 }
104
105 /* Find median of low, middle and high items; swap to low position */
106 middle = (low + high) / 2;
107 if (arr[middle] > arr[high])
108 SWAP(arr[middle], arr[high]);
109 if (arr[low] > arr[high])
110 SWAP(arr[low], arr[high]);
111 if (arr[middle] > arr[low])
112 SWAP(arr[middle], arr[low]);
113
114 /* Swap low item (now in position middle) into position (low+1) */
115 SWAP(arr[middle], arr[low + 1]);
116
117 /* Work from each end towards middle, swapping items when stuck */
118 ll = low + 1;
119 hh = high;
120 while (1) {
121 do {
122 ll++;
123 } while (arr[low] > arr[ll]);
124
125 do {
126 hh--;
127 } while (arr[hh] > arr[low]);
128
129 if (hh < ll)
130 break;
131
132 SWAP(arr[ll], arr[hh]);
133 }
134
135 /* Swap middle item (in position low) back into correct position */
136 SWAP(arr[low], arr[hh]);
137
138 /* Reset active partition */
139 if (hh <= median)
140 low = ll;
141 if (hh >= median)
142 high = hh - 1;
143 }
144}
145
146/**
147 * @brief Applies a median filter to an input signal.
148 *
149 * This function processes the input signal using a sliding window approach to compute the median value for each position.
150 * It handles boundary conditions by replicating the edge values to maintain the window size.
151 *
152 * @param x Input signal array.
153 * @param m Output signal buffer array where the median filtered signal will be stored.
154 * @param n Size of the input signal.
155 * @param W Size of the sliding window (must be an odd number, W = 2*W2 + 1).
156 */
157void median_filter(double *x, double *m, long n, long W) {
158 /* x -- input signal
159 m -- output signal buffer
160 n -- size of input signal
161 W -- size of slding window (must be odd number) W = 2*W2 + 1) */
162 long i, k, idx, W2;
163 double *w;
164 if (W % 2 == 0)
165 W = W + 1;
166 W2 = (W - 1) / 2;
167
168 w = calloc(sizeof(*w), W);
169 for (i = 0; i < n; i++) {
170 for (k = 0; k < W; k++) {
171 idx = i - W2 + k;
172 if (idx < 0) {
173 w[k] = x[0];
174 } else if (idx >= n) {
175 w[k] = x[n - 1];
176 } else {
177 w[k] = x[idx];
178 }
179 }
180 m[i] = quickSelect(w, W);
181 }
182 free(w);
183}
void median_filter(double *x, double *m, long n, long W)
Applies a median filter to an input signal.