【问题标题】:What is exact difference between mean filter and median filter均值滤波器和中值滤波器之间的确切区别是什么
【发布时间】:2014-10-07 05:40:11
【问题描述】:

我正在尝试理解均值滤波器和中值滤波器的 c 代码。 我理解了均值滤波器并实现了。但是对于中值滤波器,我无法理解中值滤波器参考代码之一中使用的以下逻辑。 我想知道为什么在下面的中值滤波器示例中计算最小值和最大值:

#define PAD_LINES 2
void ExecuteMedianFilterReference(cl_uint* p_input, cl_uint* p_output, cl_int width, cl_uint height)
{
    memset(p_output, 0,   width * (height+4));

    // do the Median
    for(cl_uint y = 0; y < height; y++)        // rows loop
    {
        int iOffset = (y+PAD_LINES) * width;
        int iPrev = iOffset - width;
        int iNext = iOffset + width;

        for(int x = 0; x < width; x++)        // columns loop
        {
            unsigned uiRGBA[9];

            //get pixels within aperture
            uiRGBA[0] = p_input[iPrev + x - 1];
            uiRGBA[1] = p_input[iPrev + x];
            uiRGBA[2] = p_input[iPrev + x + 1];

            uiRGBA[3] = p_input[iOffset + x - 1];
            uiRGBA[4] = p_input[iOffset + x];
            uiRGBA[5] = p_input[iOffset + x + 1];

            uiRGBA[6] = p_input[iNext + x - 1];
            uiRGBA[7] = p_input[iNext + x];
            uiRGBA[8] = p_input[iNext + x + 1];

            unsigned uiMin = c4min(uiRGBA[0], uiRGBA[1]);
            unsigned uiMax = c4max(uiRGBA[0], uiRGBA[1]);
            uiRGBA[0] = uiMin;
            uiRGBA[1] = uiMax;

            uiMin = c4min(uiRGBA[3], uiRGBA[2]);
            uiMax = c4max(uiRGBA[3], uiRGBA[2]);
            uiRGBA[3] = uiMin;
            uiRGBA[2] = uiMax;

            uiMin = c4min(uiRGBA[2], uiRGBA[0]);
            uiMax = c4max(uiRGBA[2], uiRGBA[0]);
            uiRGBA[2] = uiMin;
            uiRGBA[0] = uiMax;

            uiMin = c4min(uiRGBA[3], uiRGBA[1]);
            uiMax = c4max(uiRGBA[3], uiRGBA[1]);
            uiRGBA[3] = uiMin;
            uiRGBA[1] = uiMax;

            uiMin = c4min(uiRGBA[1], uiRGBA[0]);
            uiMax = c4max(uiRGBA[1], uiRGBA[0]);
            uiRGBA[1] = uiMin;
            uiRGBA[0] = uiMax;

            uiMin = c4min(uiRGBA[3], uiRGBA[2]);
            uiMax = c4max(uiRGBA[3], uiRGBA[2]);
            uiRGBA[3] = uiMin;
            uiRGBA[2] = uiMax;

            uiMin = c4min(uiRGBA[5], uiRGBA[4]);
            uiMax = c4max(uiRGBA[5], uiRGBA[4]);
            uiRGBA[5] = uiMin;
            uiRGBA[4] = uiMax;

            uiMin = c4min(uiRGBA[7], uiRGBA[8]);
            uiMax = c4max(uiRGBA[7], uiRGBA[8]);
            uiRGBA[7] = uiMin;
            uiRGBA[8] = uiMax;

            uiMin = c4min(uiRGBA[6], uiRGBA[8]);
            uiMax = c4max(uiRGBA[6], uiRGBA[8]);
            uiRGBA[6] = uiMin;
            uiRGBA[8] = uiMax;

            uiMin = c4min(uiRGBA[6], uiRGBA[7]);
            uiMax = c4max(uiRGBA[6], uiRGBA[7]);
            uiRGBA[6] = uiMin;
            uiRGBA[7] = uiMax;

            uiMin = c4min(uiRGBA[4], uiRGBA[8]);
            uiMax = c4max(uiRGBA[4], uiRGBA[8]);
            uiRGBA[4] = uiMin;
            uiRGBA[8] = uiMax;

            uiMin = c4min(uiRGBA[4], uiRGBA[6]);
            uiMax = c4max(uiRGBA[4], uiRGBA[6]);
            uiRGBA[4] = uiMin;
            uiRGBA[6] = uiMax;

            uiMin = c4min(uiRGBA[5], uiRGBA[7]);
            uiMax = c4max(uiRGBA[5], uiRGBA[7]);
            uiRGBA[5] = uiMin;
            uiRGBA[7] = uiMax;

            uiMin = c4min(uiRGBA[4], uiRGBA[5]);
            uiMax = c4max(uiRGBA[4], uiRGBA[5]);
            uiRGBA[4] = uiMin;
            uiRGBA[5] = uiMax;

            uiMin = c4min(uiRGBA[6], uiRGBA[7]);
            uiMax = c4max(uiRGBA[6], uiRGBA[7]);
            uiRGBA[6] = uiMin;
            uiRGBA[7] = uiMax;

            uiMin = c4min(uiRGBA[0], uiRGBA[8]);
            uiMax = c4max(uiRGBA[0], uiRGBA[8]);
            uiRGBA[0] = uiMin;
            uiRGBA[8] = uiMax;

            uiRGBA[4] = c4max(uiRGBA[0], uiRGBA[4]);
            uiRGBA[5] = c4max(uiRGBA[1], uiRGBA[5]);

            uiRGBA[6] = c4max(uiRGBA[2], uiRGBA[6]);
            uiRGBA[7] = c4max(uiRGBA[3], uiRGBA[7]);

            uiRGBA[4] = c4min(uiRGBA[4], uiRGBA[6]);
            uiRGBA[5] = c4min(uiRGBA[5], uiRGBA[7]);

            // convert and copy to output
            p_output[(y+PAD_LINES) * width + x] = c4min(uiRGBA[4], uiRGBA[5]);
        }
    }
}

【问题讨论】:

    标签: image-processing filtering


    【解决方案1】:

    看起来您已经从Intel(或类似的地方)获得了 OpenCL 代码。如果您从此链接下载代码示例,则 zip 文件包含一个名为 user_guide.pdf 的文件,该文件详细解释了代码。

    它所做的是,对于 3x3 邻域,对元素执行部分双调排序。通常,要找到元素列表的中位数,您将对元素进行排序并找到中间的那个。例如,如果您的列表是

    {6, 3, 9, 7, 4, 5, 8, 1, 2} <- 9 elements
    

    你会对它进行排序并得到

    {1, 2, 3, 4, 5, 6, 7, 8, 9} <- middle is the 5th element
    

    中间元素是5

    部分排序允许您在不执行完整排序的情况下找到中间元素,从而执行较少的比较。我无法使用 pdf 中的参考链接,但我确实找到了该论文的副本

    Frederick M. Waltz、Ralf Hack 和 Bruce G. Batchelor。 “使用有限状态机的 3x3 排序滤波器的快速、高效算法”。

    here。如果你单步执行程序,它将前 4 个元素按降序排序,然后将后 5 个元素按升序排序,然后在两组之间进行交换以得出中位数。

    【讨论】:

    • 非常感谢您的回答。我一直在努力理解为什么要进行最小和最大计算,但我得到了答案,因为它是双调排序。
    【解决方案2】:

    中值滤波器的主要思想是逐个遍历信号条目,用相邻条目的中值替换每个条目。我无法完全理解代码,因为没有提供所有方法的详细信息,我理解的是它采用 3 X 3 窗口并以某种方式使用 min 和 max 对其进行排序,以便可以放置中位数窗口的中间。

    该算法的一般伪代码是:

    我还建议您查看以下链接,因为它有多种语言的实现,逻辑可以很容易理解。 http://rosettacode.org/wiki/Median_filter

    【讨论】:

      猜你喜欢
      • 2021-01-04
      • 2012-07-12
      • 2015-09-16
      • 1970-01-01
      • 2011-10-02
      • 1970-01-01
      • 2015-11-06
      • 1970-01-01
      • 2015-07-12
      相关资源
      最近更新 更多