我试图理解均值滤波器和中值滤波器的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]);
}
}
}
答案 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排序它以便中位数可以放入窗户的中间。
算法的一般伪代码是:
我还建议您查看以下链接,因为它具有各种语言的实现,可以轻松理解逻辑。 http://rosettacode.org/wiki/Median_filter