C-Turlach实现中的滚动中间带

C-Turlach实现中的滚动中间带,c,algorithm,matlab,C,Algorithm,Matlab,有人知道C语言中是否有Turlach滚动中值算法的干净实现吗?我无法将R版本移植到干净的C版本。有关该算法的更多详细信息,请参阅 编辑: 正如darkcminor所指出的,matlab有一个函数medfilt2,它调用ordf,这是滚动顺序统计算法的c实现。我相信该算法比O(n^2)快,但它不是开源的,我不想购买图像处理工具箱。OpenCV有一个功能,似乎可以实现您想要的功能。我知道这是一个滚动中间带。我不能说它是否是“Turlach滚动中间带”。不过它速度非常快,并且在可用时支持多线程。我已经

有人知道C语言中是否有Turlach滚动中值算法的干净实现吗?我无法将R版本移植到干净的C版本。有关该算法的更多详细信息,请参阅

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

OpenCV有一个功能,似乎可以实现您想要的功能。我知道这是一个滚动中间带。我不能说它是否是“Turlach滚动中间带”。不过它速度非常快,并且在可用时支持多线程。

我已经实现了一个。它使用max-median-min堆结构:中位数位于堆[0](位于K项数组的中心)。在堆[1]处有一个minheap,在堆[-1]处有一个maxheap(使用负索引)。
它与不完全相同:此版本支持动态插入值,而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); }
   }
}
//自定义数据项类型
typedef int项;
#定义无项(a,b)((a)ctN);
INTP=m->pos[m->idx];
项目旧=m->数据[m->idx];
m->data[m->idx]=v;
m->idx=(m->idx+1)%m->N;
m->ct+=isNew;
如果(p>0)//新项在minHeap中
{if(!isNew&&ItemLess(old,v)){minSortDown(m,p*2);}
else如果(minSortUp(m,p)){maxSortDown(m,-1);}
}
else if(p<0)//新项在maxheap中
{if(!isNew&&ItemLess(v,old)){maxSortDown(m,p*2);}
else如果(maxSortUp(m,p)){minsorttown(m,1);}
}
否则//新项目处于中间值
{if(maxCt(m)){maxSortDown(m,-1);}
if(minCt(m)){minSortDown(m,1);}
}
}

检查这个问题:还有恒定时间中值滤波算法。scikits.image中有一个2D的实现,带有一个八角形的过滤区域。我可以确认这是可行的,而且速度很快。如果能够弹出不插入的元素(以容纳缺少的值)并指定任意的百分位数,那就太好了。不过,这些可能是简单的调整。干得好!实现poploster()将很容易:堆中最旧项的位置是
p=pos[(idx ct+N)%N]
。如果它在minheap中,将其交换到最后,然后执行排序关闭以确保交换的项位于正确的位置:
If(p>0){exchange(p,minCt);m->ct--;minSortDown(p*2);
。否则,对maxheap执行相同的操作-除了处理p==0的特殊情况外,您需要执行
maxSortDown(p*2 | |-1)
。实现“KthPercentile"这会有点棘手,但也不太糟糕。对于介于0.0和1.0之间的K,
heap
将指向元素KN。
maxCt
将是ctk,
minCt
将是ct-1-maxCt。棘手的部分是初始化pos数组,以便正确分布初始元素。这类似于:对于每个i:point pos[i]到maxheap上的下一个元素,直到它包含到目前为止超过K%的项,然后转移到minheap。以下是一些基准:-简而言之,这种方法在一般情况下似乎工作得很好,但对于某些数据分布,使用基于排序的算法可能会做得更好。请注意,任何感兴趣的人,这段代码都可以也可在GNU科学图书馆(GSL;)的
movstat/medacc.c
中找到,并可通过
GSL\u movstat\u media()
界面访问。