有人知道在C中是否有一个干净的Turlach滚动中值算法实现?我在将R版本移植到干净的C版本时遇到了麻烦。有关算法的详细信息,请参阅here。
修改
正如darkcminor指出的那样,matlab有一个函数medfilt2
,它调用ordf
,它是滚动顺序统计算法的c实现。我相信算法比O(n ^ 2)快,但它不是开源的,我不想购买图像处理工具箱。
答案 0 :(得分:17)
我已实施rolling median calculator in C here (Gist)。它使用max-median-min堆结构:中位数在堆[0](位于K项数组的中心)。堆[1]处有一个minheap,堆[-1]处有一个maxheap(使用负索引)。
它与Turlach implementation from the R source不完全相同:这个版本支持即时插入值,而R版本同时作用于整个缓冲区。但我相信时间的复杂性是一样的。它可以很容易地用于实现整个缓冲区版本(可能需要添加一些代码来处理R的“endrules”)。
接口:
//Customize for your data Item type
typedef int Item;
#define ItemLess(a,b) ((a)<(b))
#define ItemMean(a,b) (((a)+(b))/2)
typedef struct Mediator_t Mediator;
//creates new Mediator: to calculate `nItems` running median.
//mallocs single block of memory, caller must free.
Mediator* MediatorNew(int nItems);
//returns median item (or average of 2 when item count is even)
Item MediatorMedian(Mediator* m);
//Inserts item, maintains median in O(lg nItems)
void MediatorInsert(Mediator* m, Item v)
{
int isNew = (m->ct < m->N);
int p = m->pos[m->idx];
Item old = m->data[m->idx];
m->data[m->idx] = v;
m->idx = (m->idx+1) % m->N;
m->ct += isNew;
if (p > 0) //new item is in minHeap
{ if (!isNew && ItemLess(old, v)) { minSortDown(m, p*2); }
else if (minSortUp(m, p)) { maxSortDown(m,-1); }
}
else if (p < 0) //new item is in maxheap
{ if (!isNew && ItemLess(v, old)) { maxSortDown(m, p*2); }
else if (maxSortUp(m, p)) { minSortDown(m, 1); }
}
else //new item is at median
{ if (maxCt(m)) { maxSortDown(m,-1); }
if (minCt(m)) { minSortDown(m, 1); }
}
}
答案 1 :(得分:2)
OpenCV有medianBlur功能,似乎可以做你想要的。我知道这是一个滚动的中位数。我不能说具体是否是“Turlach滚动中位数”。它速度非常快,并且在可用时支持多线程。