-
Notifications
You must be signed in to change notification settings - Fork 3
/
medfilt.c
68 lines (57 loc) · 1.79 KB
/
medfilt.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/**
* Moving Median Filter.
* @author CHEVALLIER Yves <[email protected]>
*/
#include <stdint.h>
#include <stdlib.h>
#include "medfilt.h"
static void swap(MedfiltNode **a, MedfiltNode **b)
{
// Swap two node references in the sorted table.
MedfiltNode *temp = *a;
*a = *b;
*b = temp;
// Preserve index. Used to retrive the node position in the sorted table.
size_t index = (*a)->index;
(*a)->index = (*b)->index;
(*b)->index = index;
}
void medfilt(MedfiltData *data, float input, float *median, float *min, float *max)
{
// New value replaces the oldest
MedfiltNode *n = data->kernel;
MedfiltNode *node = data->oldest;
node->value = input;
data->oldest = node->parent;
# define VAL(x) (n[x].sorted->value)
// Sort the kernel
// Check neigbhour to the right
for (size_t i = node->index; i < data->length - 1 && VAL(i) > VAL(i + 1); i++) {
swap(&n[i].sorted, &n[i + 1].sorted);
}
// Check neigbhour to the left
for (size_t i = node->index; i > 0 && VAL(i) < VAL(i - 1); i--) {
swap(&n[i].sorted, &n[i - 1].sorted);
}
// Get kernel information from sorted entries
*min = VAL(0);
*max = VAL(data->length - 1);
*median = VAL(data->length / 2);
# undef VAL
}
void medfilt_init(MedfiltData *data, MedfiltNode *nodes, size_t length, float init)
{
data->kernel = nodes;
data->length = length;
// Linked list initialization
data->oldest = &data->kernel[length - 1];
for (size_t i = 0; i < length; i++) {
data->kernel[i] = (MedfiltNode) {
.value = init,
.parent = data->oldest,
.index = i,
.sorted = &data->kernel[i]
};
data->oldest = &data->kernel[i];
}
}