C / C++中的快速中值滤波器,用于“UINT16”2D阵列



>有谁知道 C++ 中 16 位(无符号短)数组的快速中值过滤算法?

http://nomis80.org/ctmf.html

这个看起来很有前途,但它似乎只适用于字节数组。有谁知道如何修改它以使用短裤或替代算法?

本文中的技术依赖于为8位像素通道创建具有256个箱的直方图。转换为每通道 16 位需要具有 65536 个箱的直方图,并且图像的每一列都需要直方图。将内存需求提高 256 会使该算法总体上效率较低,但对于当今的硬件来说仍然可能可行。

使用他们提出的将直方图分解为粗略和细部分的优化,应该会进一步将运行时命中率降低到仅 16 倍。

对于较小的半径值,我认为您会发现传统的中值过滤方法将更具性能。

快速中位数搜索 - ANSI C 实现 (PDF) 是 C 语言的内容,它是一篇标题为"快速中值搜索:ANSI C 实现"的论文。作者声称它是O(log(n)),他还提供了一些代码,也许它会帮助你。它并不比你建议的代码更好,但也许值得一看。

std::vector<unsigned short> v{4, 2, 5, 1, 3};
std::vector<unsigned short> h(v.size()/2+1);
std::partial_sort_copy(v.begin(), v.end(), h.begin(), h.end());
int median = h.back();

在 O(N·log(N/2+1)) 中运行,并且不会修改您的输入。

本文介绍了一种以每像素 O(log r) 时间运行的图像的中值过滤方法,其中 r 是过滤器半径,适用于任何数据类型(8 位整数或双精度

):

快速中值和双侧滤波

我知道

这个问题有点老了,但我也对中位数过滤感兴趣。 如果一个人正在处理信号或图像,那么处理窗口的数据将有很大的重叠。 这是可以利用的。

我在这里发布了一些基准代码:C++中的一维移动中值滤波

它是基于模板的,因此它应该适用于大多数 POD 数据类型。

根据我的结果std::nth_element对于移动中位数的性能很差,因为它每次都必须对值窗口进行排序。

但是,使用保持排序的值池,可以通过 3 操作执行中位数。

  1. 从池中删除最旧的值(调用 std::lower_bound)
  2. 将新值插入池(调用 std::lower_bound)
  3. 在历史记录缓冲区中存储新值

中位数现在是池中的中间值。

我希望有人觉得这很有趣并贡献他们的想法!

参见以下论文中的等式4和5。 复杂度为 O(N*W),其中 W 是滤波器的宽度,N 是样本数。

请参阅通过矢量中值滤波降低噪声。

最新更新