在C - Turlach实施中滚动中位数

Ric*_*h C 15 c algorithm matlab

有谁知道在C中是否有一个干净的Turlach滚动中值算法实现?我在将R版本移植到干净的C版本时遇到了麻烦.有关算法的更多详细信息,请参见此处.

编辑: 正如darkcminor指出的那样,matlab有一个函数medfilt2调用ordf哪个是滚动顺序统计算法的ac实现.我相信算法比O(n ^ 2)快,但它不是开源的,我不想购买图像处理工具箱.

ASh*_*lly 17

在这里用C 实现了滚动中值计算器(Gist).它使用max-median-min堆结构:中位数在堆[0](位于K项数组的中心).在堆[1]处有一个minheap,在堆[-1]处有一个maxheap(使用负索引).
它与来自R源Turlach实现不完全相同:这一个支持即时插入的值,而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); }
   }
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,任何感兴趣的人都可以在 GNU 科学图书馆(GSL;https://www.gnu.org/software/gsl/)的“movstat/medacc.c”中找到此代码,并且可以通过“gsl_movstat_median”访问()`接口。 (3认同)
  • 以下是一些基准:https://github.com/suomela/median-filter - 简而言之,这种方法通常看起来效果很好,但对于某些数据分布,使用基于排序的算法可以做得更好。 (2认同)
  • 当搜索算法的描述时:Turlach 实现实现了 [Härdle,W. Steiger。最佳中值平滑 (1994)](https://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.45.993) 算法 (2认同)