平均滤波器和中值滤波器之间的确切差异是什么

时间:2014-10-05 14:13:15

标签: image-processing filtering

我试图理解均值滤波器和中值滤波器的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]);
        }
    }
}

2 个答案:

答案 0 :(得分:2)

看起来您已经从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个元素进行排序,然后在两个集合之间进行交换以达到中位数。

答案 1 :(得分:0)

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

算法的一般伪代码是: enter image description here

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