关于中值滤波算法,以及C语言实现(转)

源:关于中值滤波算法,以及C语言实现

1、什么是中值滤波?

中值滤波是对一个滑动窗口内的诸像素灰度值排序,用其中值代替窗口中心象素的原来灰度值,它是一种非线性的图像平滑法,它对脉冲干扰级椒盐噪声的抑制效果好,在抑制随机噪声的同时能有效保护边缘少受模糊。

中值滤波可以过滤尖峰脉冲。目的在于我们对于滤波后的数据更感兴趣。滤波后的数据保留的原图像的变化趋势,同时去除了尖峰脉冲对分析造成的影响。

以一维信号的中值滤波举例。对灰度序列80、120、90、200、100、110、70,如果按大小顺序排列,其结果为70、80、90、10O、110、120、200,其中间位置上的灰度值为10O,则该灰度序列的中值即为100。一维信号中值滤波实际上就是用中值代替规定位置(一般指原始信号序列中心位置)的信号值。对前面所举的序列而言,中值滤波的结果是用中值100替代序列80、120、90、200、100、110、70中的信号序列中心位置值200,得到的滤波序列就是80、120、90、100、100、110、70。如果在此序列中200是一个噪声信号,则用此方法即可去除这个噪声点。

二维中值滤波算法是:对于一幅图像的象素矩阵,取以目标象素为中心的一个子矩阵窗口,这个窗口可以是3*3 ,5*5 等根据需要选取,对窗口内的象素灰度排序,取中间一个值作为目标象素的新灰度值。窗口示例如ooooxoooo上面x为目标象素,和周围o组成3*3矩阵Array,然后对这9个元素的灰度进行排序,以排序后的中间元素Array[4]为x的新灰度值,如此就完成对象素x的中值滤波,再迭代对其他需要的象素进行滤波即可。

图像处理中,中值滤波的实现方法

1:通过从图像中的某个采样窗口取出奇数个数据进行排序

2:用排序后的中值取代要处理的数据即可

中值滤波的算法实现过程,重点是排序,最常用的冒泡排序~~

把滤波区间的数据从小到大进行排序,然后取中值,(如果是奇数个数据,那么中值就只有一个了,如果偶数个数据,中值有两个,可以对两个数据再求平均)

下面是一个C语言实现中值滤波的函数:

unsigned char GetMedianNum(int * bArray, int iFilterLen)
{
    int i,j;// 循环变量
    unsigned char bTemp;

    // 用冒泡法对数组进行排序
    for (j = 0; j < iFilterLen - 1; j ++)
    {
        for (i = 0; i < iFilterLen - j - 1; i ++)
        {
            if (bArray[i] > bArray[i + 1])
            {
                // 互换
                bTemp = bArray[i];
                bArray[i] = bArray[i + 1];
                bArray[i + 1] = bTemp;
            }
        }
    }

    // 计算中值
    if ((iFilterLen & 1) > 0)
    {
        // 数组有奇数个元素,返回中间一个元素
        bTemp = bArray[(iFilterLen + 1) / 2];
    }
    else
    {
        // 数组有偶数个元素,返回中间两个元素平均值
        bTemp = (bArray[iFilterLen / 2] + bArray[iFilterLen / 2 + 1]) / 2;
    }

    return bTemp;
}
注:bArray 是一个整形指针,我们传入的一般是一个数组,用来存储待排序的数据
&nbsp; &nbsp; iFilterLen 是滤波器的长度
&nbsp; &nbsp;用在图像处理中时,由于像素的取值范围是0~255,刚好是unsigned char 的范围,所以函数的返回值是unsigned char,如果我们要处理的数是float型,或其他类型,返回值也可以更改~~返回值是bTemp,也即是我们想得到的中值
<span style="color: rgb(51, 51, 51);">下面是一个完整的C语言程序,用在图像处理中</span>
/*************************************************************************
 * 函数名称:
 *   MedianFilter()
 * 参数:
 *   int   iFilterH            - 滤波器的高度
 *   int   iFilterW            - 滤波器的宽度
 *   int   iFilterMX        - 滤波器的中心元素X坐标
 *   int   iFilterMY        - 滤波器的中心元素Y坐标
 * 说明:
 *   该函数对DIB图像进行中值滤波。
 ************************************************************************/
#define iFilterW 1
#define iFilterH 1
#define iFilterMX 1
#define iFilterMY 1
#define WIDTHBYTES(bits)    (((bits) + 31) / 32 * 4)

unsigned char GetMedianNum(int * bArray, int iFilterLen);
void MedianFilter(unsigned char *pImg1,unsigned char *pImg,int nWidth,int nHeight)
{
    unsigned char   *lpSrc;                            // 指向源图像的指针
    unsigned char   *lpDst;                             // 指向要复制区域的指针
    int         aValue[iFilterH*iFilterW];            // 指向滤波器数组的指针
    int            i,j,k,l;                            // 循环变量
    int            lLineBytes;                            // 图像每行的字节数
    lLineBytes = WIDTHBYTES(nWidth * 8);
    for ( i=0;i<nWidth;i++,pImg++ )
        (*pImg)=0;
    // 开始中值滤波
    // 行(除去边缘几行)
    for(i = iFilterMY; i < nHeight - iFilterH + iFilterMY + 1; i++)
    {
        // 列(除去边缘几列)
        for(j = iFilterMX; j < nWidth - iFilterW + iFilterMX + 1; j++)
        {
            // 指向新DIB第i行,第j个象素的指针
            lpDst = pImg + lLineBytes * (nHeight - 1 - i) + j;

            // 读取滤波器数组
            for (k = 0; k < iFilterH; k++)
            {
                for (l = 0; l < iFilterW; l++)
                {
                    // 指向DIB第i - iFilterMY + k行,第j - iFilterMX + l个象素的指针
                    lpSrc = pImg1 + lLineBytes * (nHeight - 1 - i + iFilterMY - k) + j - iFilterMX + l;

                    // 保存象素值
                    aValue[k * iFilterW + l] = *lpSrc;
                }
            }

            // 获取中值
            * lpDst = GetMedianNum(aValue, iFilterH * iFilterW);
        }
    }

}

unsigned char GetMedianNum(int * bArray, int iFilterLen)
{
    int        i,j;            // 循环变量
    unsigned char bTemp;

    // 用冒泡法对数组进行排序
    for (j = 0; j < iFilterLen - 1; j ++)
    {
        for (i = 0; i < iFilterLen - j - 1; i ++)
        {
            if (bArray[i] > bArray[i + 1])
            {
                // 互换
                bTemp = bArray[i];
                bArray[i] = bArray[i + 1];
                bArray[i + 1] = bTemp;
            }
        }
    }

    // 计算中值
    if ((iFilterLen & 1) > 0)
    {
        // 数组有奇数个元素,返回中间一个元素
        bTemp = bArray[(iFilterLen + 1) / 2];
    }
    else
    {
        // 数组有偶数个元素,返回中间两个元素平均值
        bTemp = (bArray[iFilterLen / 2] + bArray[iFilterLen / 2 + 1]) / 2;
    }

    return bTemp;
}
时间: 2024-09-30 13:03:41

关于中值滤波算法,以及C语言实现(转)的相关文章

关于中值滤波算法,以及C语言实现

1.什么是中值滤波? 中值滤波是对一个滑动窗口内的诸像素灰度值排序,用其中值代替窗口中心象素的原来灰度值,它是一种非线性的图像平滑法,它对脉冲干扰级椒盐噪声的抑制效果好,在抑制随机噪声的同时能有效保护边缘少受模糊. 中值滤波可以过滤尖峰脉冲.目的在于我们对于滤波后的数据更感兴趣.滤波后的数据保留的原图像的变化趋势,同时去除了尖峰脉冲对分析造成的影响. 以一维信号的中值滤波举例.对灰度序列80.120.90.200.100.110.70,如果按大小顺序排列,其结果为70.80.90.10O.110

实时高速实现改进型中值滤波算法_爱学术_免费下载

[摘要]在图像采集和处理过程中会引入噪声,必须先对图像进行预处理.本文介绍一种快速中值滤波算法,该算法在硬件平台上实现实时处理功能.综合考虑,选择现场可编程门阵列(FPGA)作为硬件平台,采用硬件描述语言Verilog实现改进型中值滤波算法.经Modelsim仿真结果表明:基于FPGA硬件平台实现改进型中值滤波算法不仅速度快,而且实时处理效果佳,提高了图像处理的效率. [作者] 杨晶  王元庆 转载至爱学术:https://www.ixueshu.com/document/29bcda14996

数字图像处理之快速中值滤波算法

快速中值滤波算法 中值滤波算法: 在图像处理中,在进行如边缘检测这样的进一步处理之前,通常需要首先进行一定程度的降噪.中值滤波是一种非线性数字滤波器技术,经常用于去除图像或者其它信号中的噪声.这个设计思想就是检查输入信号中的采样并判断它是否代表了信号,使用奇数个采样组成的观察窗实现这项功能.观察窗口中的数值进行排序,位于观察窗中间的中值作为输出.然后,丢弃最早的值,取得新的采样,重复上面的计算过程.中值滤波是图像处理中的一个常用步骤,它对于斑点噪声和椒盐噪声来说尤其有用.保存边缘的特性使它在不希

高效中值滤波(采用copyMakeBorder处理边界像素)

修改了之前滤波中的中值滤波算法,采用copyMakeBorder处理边界像素 void MedianBlur(const Mat &image_Src, Mat &image_Dst, int width_Aperture) { /////////////////////////////重新分配图像(如果需要)///////////////////////////////////////////// int width_Dst=image_Src.cols; int height_Dst=

数字图像处理------中值滤波

一 中值滤波概念 中值滤波算法以某像素的领域图像区域中的像素值的排序为基础,将像素领域内灰度的中值代替该像素的值[1]: 如:以3*3的领域为例求中值滤波中像素5的值 图1 1)int pixel[9]中存储像素1,像素2...像素9的值: 2)对数组pixel[9]进行排序操作: 3)像素5的值即为数组pixel[9]的中值pixel[4]. 中值滤波对处理椒盐噪声非常有效. 二 中值滤波代码实现 项目工程:https://github.com/ranjiewwen/Everyday_Prac

VC++高斯滤波\中值滤波实现图像模糊处理

一.算法 高斯模糊算法 详见:高斯模糊,基本思想就是利用高斯函数,将一个坐标点的所有邻域的加权平均值设置为这些点的颜色值. 中值滤波算法就更简单了:将一个坐标点的所有邻域的平均值设置为这些点的像素值. 二.算法的代码实现 高斯函数: 使用宏定义来替换: #define PI<span style="white-space:pre"> </span>3.1415926 //高斯模糊函数 #define GAUSS_FUN(x, y) (exp(-(x*x)/(do

中值滤波C语言优化

中值滤波C语言优化 图像平滑是图像预处理的基本操作,本文首先用不同的方法对一张图片做预处理比较它们效果的不同,然后针对中值滤波,实现了一种快速实现.(其实是copy的opencv实现,呵呵).因为opencv的实现方法感觉太好了,今天就特别写下来.既有备忘的作用,同时如果谁看到这篇文章,也可以借鉴下opencv的实现.   1 原始图像 2 均值滤波图像 3 中值滤波图像 4 双边滤波图像 5 高斯滤波图像     上图的代码 void CDialogTest2013Dlg::OnBnClick

中值滤波的快速算法

我想学过图像处理的人没有人会不知道中值滤波的,最早的时候我是在冈萨雷斯的图像处理课本[1]中学到的,后来在看Sonka的书[2]的时候又看到了中值滤波的介绍,下面我试着结合课本所学和网上的资料自己整理一篇中值滤波的介绍. Jeremy Lin 中值滤波器是一种统计排序滤波器,由Tukey于1971年在文献[3]中提出.所谓的统计排序滤波器是一种非线性的空间滤波器,它的响应基于图像滤波器包围的图像区域中像素的排序,然后用统计排序结果决定的值代替中心像素的值.除了中值滤波器外,最大值滤波器和最小值滤

基于记忆性的中值滤波O(r)与O(1)复杂度的算法实现

本文参考博客:https://www.cnblogs.com/Imageshop/archive/2013/04/26/3045672.html 原生的中值滤波是基于排序算法的,这样的算法复杂度基本在O(r2)左右,当滤波半径较大时,排序算法就显得很慢.对此有多种改进算法,这里介绍经典 的Huang算法与O(1)算法,两者都是基于记忆性的算法,只是后者记性更强. 排序算法明显的一个不足之处就是无记忆性.当核向右移动一列后,只是核的最左和最右列数据发生了变化,中间不变的数据应当被存储起来,而排序算