精华内容
下载资源
问答
  • 均值滤波处理图像,matlab代码,可以实现图像去除噪点。
  • 借鉴他人的资源进行集合和整理了一下,高斯滤波分为一维高斯滤波和二维高斯滤波,并且和OPENCV的高斯滤波的时间进行对比了一下,比OPENCV的要慢很多
  • C# 图像处理 源代码 均值滤波 中值滤波 边缘提取 锐化测试通过非常好用
  • 描述均值滤波均值滤波是典型的线性滤波算法,它是指在图像上对目标像素给一个模板,该模板包括了其周围的临近像素(以目标像素为中心的周围个像素,构成一个滤波模板,即去掉目标像素本身),再用模板中的全体像素的...

    描述

    均值滤波

    均值滤波是典型的线性滤波算法,它是指在图像上对目标像素给一个模板,该模板包括了其周围的临近像素(以目标像素为中心的周围个像素,构成一个滤波模板,即去掉目标像素本身),再用模板中的全体像素的平均值来代替原来像素值。

    均值滤波也称为线性滤波,其采用的主要方法为邻域平均法。线性滤波的基本原理是用均值代替原图像中的各个像素值,即对待处理的当前像素点(x,y),选择一个模板,该模板由其近邻的若干像素组成,求模板中所有像素的均值,再把该均值赋予当前像素点(x,y),作为处理后图像在该点上的灰度g(x,y),即g(x,y)=/m ∑f(x,y) m为该模板中包含当前像素在内的像素总个数。

    均值滤波介绍

    滤波是滤波是将信号中特定波段频率滤除的操作,是从含有干扰的接收信号中提取有用信号的一种技术。

    均值滤波是典型的线性滤波算法,它是指在图像上对目标像素给一个模板,该模板包括了其周围的临近像素(如×模板:以目标象素为中心的周围个象素,构成一个滤波模板,即去掉目标象素本身),再用模板中的全体像素的平均值来代替原来像素值。

    均值滤波效果:平滑线性滤波处理降低了图像的“尖锐”变化。由于典型的随机噪声由灰度级的急剧变化组成,因此常见的平滑处理的应用就是降低噪声。均值滤波器的主要应用是去除图像中的不相关细节,其中“不相关”是指与滤波器模板尺寸相比较小的像素区域。然而,由于图像的边缘也是由图像灰度的尖锐变化带来的特性,所以均值滤波处理还是存在着边缘模糊的负面效应。

    均值滤波算法实现(C语言)

    // junzhilvbo.cpp : 定义控制台应用程序的入口点。

    //

    #include “stdafx.h”

    #include “stdlib.h”

    #include “string.h”

    #define DATA_X //数字图像水平像素个数

    #define DATA_Y //数字图像竖直像素个数

    void OpenFile(const char *cFilePath , int nOriginalData[DATA_Y][DATA_X])

    {

    printf(“正在获取数据。。。。。。\n”);

    FILE *fp ;

    fp = fopen(cFilePath , “r”);

    if(NULL == fp)

    {

    printf(“open file failed! \n”);

    return ;

    }

    unsigned char *pData = (unsigned char *)malloc(sizeof(unsigned char)*DATA_X*DATA_Y);

    if(NULL == pData)

    {

    printf(“memory malloc failed!\n”);

    return ;

    }

    fread(pData , sizeof(unsigned char)*DATA_X*DATA_Y , , fp);

    int count_x = ;

    int count_y = ;

    for(;count_y 《 DATA_Y ; count_y++)

    {

    for(; count_x 《 DATA_X ;count_x++)

    {

    nOriginalData[count_y][count_x] = pData[count_y*DATA_Y+count_x];

    }

    }

    free(pData);

    fclose(fp);

    return ;

    }

    void SaveFile(const char *cFilePath , int nResultData[DATA_Y][DATA_X])

    {

    printf(“正在保存数据。。。。。。\n”);

    int count_x,count_y;

    FILE *fp ;

    fp = fopen(cFilePath , “w”);

    if(NULL == fp)

    {

    printf(“open file failed! \n”);

    return ;

    }

    for(count_y=;count_y《DATA_Y;count_y++)

    {

    for(count_x=;count_x《DATA_X;count_x++)

    {

    fwrite(&nResultData[count_y][count_x],,,fp);

    }

    }

    fclose(fp);

    printf(“文件保存成功! \n”);

    return ;

    }

    bool JunZhiLvBo(const int nOriginalData[DATA_Y][DATA_X], int nResultData[DATA_Y][DATA_X])

    {

    printf(“正在进行均值滤波。。。。。。\n”);

    int count_x ,count_y ;

    /**模版滤波计算,不计算边缘像素*/

    for(count_y = ; count_y 《 DATA_Y ; count_y++)

    {

    for(count_x = ; count_x 《 DATA_X ;count_x++)

    {

    nResultData[count_y][count_x] = (int)((nOriginalData[count_y-][count_x-]+

    nOriginalData[count_y-][count_x] +

    nOriginalData[count_y-][count_x+]+

    nOriginalData[count_y][count_x-] +

    nOriginalData[count_y][count_x] +

    nOriginalData[count_y][count_x+] +

    nOriginalData[count_y+][count_x-]+

    nOriginalData[count_y+][count_x] +

    nOriginalData[count_y+][count_x+])/);

    }

    }

    /*对四个边缘直接进行赋值处理*/

    for(count_x=;count_x《DATA_X;count_x++) //水平边缘像素等于原来像素灰度值

    {

    nResultData[][count_x]=nOriginalData[][count_x];

    nResultData[DATA_Y-][count_x]=nOriginalData[DATA_Y-][count_x];

    }

    for(count_y=;count_y《DATA_Y-;count_y++) //竖直边缘像素等于原来像素灰度值

    {

    nResultData[count_y][]=nOriginalData[count_y][];

    nResultData[count_y][DATA_X-]=nOriginalData[count_y][DATA_X-];

    }

    return true ;

    }

    int _tmain(int argc, _TCHAR* argv[])

    {

    int nOriginalData[DATA_Y][DATA_X]; //保存原始图像灰度值

    int nResultData[DATA_Y][DATA_X]; //保存滤波后的灰度值

    memset(nOriginalData,,sizeof(nOriginalData)); //初始化数组

    memset(nResultData,,sizeof(nResultData));

    char cOpenFilePath[] = “Lena.raw”; //图像文件路径

    OpenFile(cOpenFilePath,nOriginalData);

    if(!JunZhiLvBo(nOriginalData,nResultData)) //滤波计算

    {

    printf(“操作失败!\n”);

    return ;

    }

    char cSaveFilePath[] = “Result.raw”; //文件保存路径

    SaveFile(cSaveFilePath,nResultData);

    return ;

    }

    均值滤波算法效果对比

    均值滤波之前: 均值滤波之后:

    39ad9217f1104261c40205e187374407.png

    打开APP阅读更多精彩内容

    点击阅读全文

    展开全文
  • 均值滤波(Mean filtering)

    千次阅读 2021-11-21 16:10:42
    均值滤波是典型的线性滤波算法,是指用当前像素点周围 n*n个像素值的均值来代替当前像素值。使用该方法遍历处理图像内的每一个像素点,即可完成整幅图像的均值滤波。 2.基本原理  如图2-1,我们希望对第5行第5列...

    1.概念介绍

     均值滤波是典型的 线性滤波算法,是指用当前像素点周围nxn个像素值的均值来代替当前像素值。使用该方法遍历处理图像内的每一个像素点,可完成整幅图像的均值滤波。

    2.基本原理

     如图2-1,我们对第5行第5列的像素点进行均值滤波时,首先需要考虑需要对周围多少个像素点去取平均值。通常情况下,我们会以该当前像素为中心,对行数和列数相等的一块区域内的所有像素点的像素取平均值
     例如,我们可以以当前像素点的像素周围3x3区域内所有像素点的像素取平均值,也可以对周围5x5区域内所有像素点的像素值取平均值。
    在这里插入图片描述
    图2-1  一幅图像的像素值示例

     当前像素点的位置为第5行第5列时,我们对其周围5*5区域内的像素值取平均,计算方法如下:
    像素点新值=
    [(197+25+106+156+159)
    (149+40+107+5+71)+
    (163+198+226+223+156) +
    (222+37+68+193+157)+
    (42+72+250+41+75)]/25 = 126

    计算得到新值以后,我们将新值作为当前像素点均值滤波后的像素值。我们针对图2-1的每一个像素点计算其周围5x5区域内的像素值均值,并将其作为当前像素点的新值,即可得到当前图像的均值滤波结果。

    然而图像的边界并不存在5x5的领域区域。如图2-1的左上角第1行第1列上的像素点,其像素值为23。如果以其为中心点取周围5x5领域,则5x5领域的部分区域位于图像外部。但是图像外部是没有像素点和像素值的,显然是无法计算该点的领域均值的。

    因此,针对边缘的像素点,可以只取图像内存在的周围领域点的像素值均值。如图2-2所示,计算左上角的均值滤波结果时,仅取图中灰色背景的33领域内的像素值的平均值。计算方法如下:
    像素点新值=
    [(23+158+140)+
    (238+0+67)+
    (199+197+25)]/9
    =116
    在这里插入图片描述
    图2-2  边界点的处理

     除此之外,我们还可以扩展当前图像的周围像素点。例如,可以将当前9
    7大小的图像扩展为13*11大小的图像,如图2-3所示。
    在这里插入图片描述
    图2-3  扩展边缘

     在完成图像边缘拓展后,我们可以在新增的行列内填充不同的像素值。在此基础上,再针对9x7的原始图像计算其5x5领域内像素点的像素值均值。OpenCV提供了多种边界处理方式,我们可以根据实际需要选用不同的边界处理模式。

     针对第5行第5列的像素点,其运算过程相当于一个额内部值是1/25的55矩阵进行相乘运算,从而得到均值滤波的结果为126。如图2-4所示。
    在这里插入图片描述
    图2-4  针对第 5 行第 5 列像素点均值滤波的运算示意图

    根据上述运算,针对每一个像素点,都是与一个内部值均为1/25的5
    5举证相乘,得到均值滤波的计算结果。示意图如图2-4所示
    在这里插入图片描述
    图1-4  针对每一个像素点均值滤波的运算示意图

    将使用到的5x5矩阵一般化,可以得到如下图2-5的结果。
    在这里插入图片描述
    图2-5  将矩阵一般化

    在Opencv中,将图1-5右侧的矩阵称为卷积核,其一般形式如下图2-6所示。其中M和N分别对应高度和宽度,一般情况下M和N的值是相等的,常用的3x3、5x5和7x7。如果M和N的值越大,参与运算的值就越大,参与运算的像素点的数量就越多,图像失真就越严重
    在这里插入图片描述
    图2-6  卷积核

    3.函数语法

    在OpenCV中,实现均值滤波的函数是cv2.blur(),其语法格式为:dst = cv2.blur( src, ksize, anchor, borderType )
    参数解析
    dst:返回值,表示进行均值滤波后得到的处理结果。
    src:需要处理的图像,即原始图像。它可以有任意数量的通道,并能对各个通道独立进行处理。图像深度应该是CV_8U、CV_16U、CV_16S、CV_32F 或者 CV_64F 中的一种。
    ksize:滤波核的大小。滤波核的大小是指在均值处理的过程中,其领域图像的高度和宽度。例如,其值可以为(5,5),表示以5*5大小的领域均值作为图像均值滤波处理的结果。
    anchor:锚点,默认值是(-1, -1),表示当前计算均值的点位于核的中心点位置。该值使用默认值即可,在特殊情况下可以指定不同的点作为锚点。
    borderType:边界样式,该值决定了以何种方式处理边界,其值如下表所示。一般情况下不需要考虑该值的取值,直接采用默认值即可。

    类型说明
    cv2.BORDER_CONSTANTiiiiii abcdefgh iiiiiii,特定值 i
    cv2.BORDER_REPLICATEaaaaaa abcdefgh hhhhhhh
    cv2.BORDER_REFLECTfedcba abcdefgh hgfedcb
    cv2.BORDER_WRAPcdefgh abcdefgh abcdefg
    cv2.BORDER_REFLECT_101gfedcb abcdefgh gfedcba
    cv2.BORDER_TRANSPARENTuvwxyz absdefgh ijklmno
    cv2.BORDER_REFLECT101与 BORDER_REFLECT_101 相同
    cv2.BORDER_DEFAULT与 BORDER_REFLECT_101 相同
    cv2.BORDER_ISOLATED不考虑 ROI(Region of Interest,感兴趣区域)以外的区域

    通常情况下,使用均值滤波函数时,对于锚点 anchor 和边界样式 borderType,直接采用其
    默认值即可。因此,函数 cv2.blur()的一般形式为:dst = cv2.blur( src, ksize)

    4.程序示例

    读取一幅噪声图像,使用函数 cv2.blur()对图像使用三种不同大小的卷积核进行均值滤波处理,得到去噪图像,并显示原始图像和去噪图像。

    import cv2
    Gn=cv2.imread("Gaussian_noise.jpg") 
    Mf_a=cv2.blur(Gn,(2,2))
    Mf_b=cv2.blur(Gn,(5,5))
    Mf_c=cv2.blur(Gn,(10,10))
    cv2.imshow("噪声图像",Gn)
    cv2.imshow("使用2×2的卷积核进行均值滤波",Mf_a)
    cv2.imshow("使用5×5的卷积核进行均值滤波",Mf_b)
    cv2.imshow("使用10×10的卷积核进行均值滤波",Mf_c)
    cv2.waitKey()
    cv2.destroyAllWindows()
    

    运行上述程序会分别显示噪声图像和使用不同卷积核进行均值滤波的去噪图像
    在这里插入图片描述
    图4-1  噪声图像

    在这里插入图片描述
    图4-2  使用2x2的卷积核进行均值滤波的图像

    在这里插入图片描述
    图4-3  使用5x5的卷积核进行均值滤波的图像

    在这里插入图片描述
    图4-4  使用10x10的卷积核进行均值滤波的图像

    在这里插入图片描述
    图4-5  不含噪声的原始图像

    从使用不同大小的卷积核进行均值滤波处理图像可以发现:卷积核越大,图像的失真情况越明显

    卷积核越大,参与到均值运算中的像素就会越多,即当前计算的算的是更多点的像素值的平均值,去噪效果越好,当然花费的计算时间也会越长,同时让图像失真越严重。因此在实际处理中,要在失真和去噪效果之间取得平衡,选取合适大小的卷积核

    展开全文
  • end end subplot(1,3,2) imshow(uint8(imagedd)) title('均值滤波') %% 再进行自适应均值滤波,进行对比 imagenn=double(imagen); iamgee=double(rgb2gray(image)); %取未加噪声的原图像的灰度 imagedd=imagenn; ...

    直接看代码

    %% 导入原图像,并添加高斯噪声
    image=imread('aft.jpg');
    imagen=rgb2gray(image);
    [width,height]=size(imagen);
    r1=rand(width,height);%用于产生高斯噪声
    r2=rand(width,height);
    x=0.1*sqrt(-2*log(r1)).*cos(2*pi*r2); %产生了噪声
    imagen=x+double(imagen)/255;%为了加上高斯噪声,需要将图像变为double型
    imagen=uint8(255*imagen);   %再转回图像的格式
    subplot(1,3,1);
    imshow(imagen);
    title('原图像');
    %先进行均值滤波,看效果
    imagen=double(imagen);
    k1=3;%k1阶均值滤波
    imagedd=imagen;
    a=ones(k1,k1);
    for i=1:width-k1+1
        for j=1:height-k1+1
            pattern=imagen(i:i+k1-1,j:j+k1-1).*a;
            means=sum(sum(pattern));
            imagedd(i+(k1-1)/2,j+(k1-1)/2)=means/(k1*k1);
        end
    end
    subplot(1,3,2)
    imshow(uint8(imagedd))
    title('均值滤波')
    %% 再进行自适应均值滤波,进行对比
    imagenn=double(imagen);
    iamgee=double(rgb2gray(image)); %取未加噪声的原图像的灰度
    imagedd=imagenn;
    imagemean=imagenn;
    imagevar=imagenn;
    n=7;%滤波器阶数为7
    sigma=(imagenn-iamgee).^2; %噪声方差
    for i=1:width-n+1
            for j=1:height-n+1
                pattern=imagenn(i:i+n-1,j:j+n-1);
                patterns=reshape(pattern,1,length(pattern(:)));
                means=mean(patterns);%求均值
                imagemean(i+(n-1)/2,j+(n-1)/2)=means;
                vars=var(patterns,1);%求方差
                imagevar(i+(n-1)/2,j+(n-1)/2)=vars;
            end
    end
    da=(sigma<1);%噪声方差接近于0时不处理
    dc=~da&(abs(sigma-imagevar)<=100); %噪声方差与局部方差接近时,均值滤波
    db=~dc; %略有调整
    imagedd(da)=imagenn(da);
    imagedd(db)=imagemean(db);  
    imagedd(dc)=imagenn(dc)-(sigma(dc)./imagevar(dc).*(imagenn(dc)-imagemean(dc)));   
    imagedd=uint8(imagedd);
    
    subplot(1,3,3);
    imshow(imagedd);
    title('自适应均值滤波');
    
    
    

    在这里插入图片描述

    展开全文
  • 用C#开发的的一种图像处理软件,在VS2005下编译通过,能正常运行,实现的功能有均值滤波,中值滤波,边缘提取,锐化。
  • 均值滤波实现及优化

    2021-04-11 17:07:24
    均值滤波广泛的运用于图像处理,可以用来去除图片噪声。我们今天主要讲解一下什么是均值滤波,以及我们如何对原始的均值滤波进行算法层面的加速优化。 一 均值滤波的分类 均值滤波我们可以细分成4类: 1 算术均值...

    均值滤波广泛的运用于图像处理,可以用来去除图片噪声。我们今天主要讲解一下什么是均值滤波,以及我们如何对原始的均值滤波进行算法层面的加速优化。

    一 均值滤波的分类
    均值滤波我们可以细分成4类:
      1 算术均值滤波器:计算滑动窗口内像素的均值。

                         f(x,y)=\frac{1}{mn}\sum g(x,t)

      2 几何均值滤波器:

                       f(x,y)=\frac{1}{mn}\prod g(x,t)

      3 谐波均值滤波器:

                      f(x,y) = \frac{mn}{\sum \frac{1}{g(x,t)}}

       4 谐谐波均值滤波器:当Q等于0时就变成均值滤波器 当Q等于-1时就是谐波均值滤波器

                    f(x,y)=\frac{\sum g(x,t))^{^{Q+1}}}{\sum g(x,t))^{^{Q}}}

    本章我们主要介绍算术均值滤波器,介绍算术均值滤波器的实现和优化。

    二 算术均值滤波器

    • 均值滤波的定义及效果

    算术均值滤波器的定义很简单,我们假设滑动窗口大小是3*3, 我们使用3*3的窗口在原始输入图片上进行滑动,每滑动一次就计算滑动窗口中9个像素的均值作为目标图像像素。    

            

          Fig 1 均值滤波算法示意图

    均值滤波效果:我们输入一张图片,然后使用均值滤波进行滤波,得到我们的滤波后的图像。右图是我们用5*5的滑动窗口进行均值滤波后的结果,左边是我们对应的原始图像。

        

        Fig 2 kernel 5*5 均值滤波效果对比

    • 均值滤波问题

    均值滤波存在两个明显的问题

    <1> 某个突变像素回影响到周围像素的值

    <2> 均值滤波会导致边缘信息丢失

    这两个问题可以用中值滤波得到解决,但是中值滤波计算时间消耗比较大 。边缘信息会丢失的问题提出了一种改进的均值滤波器: 首先设定一个阈值, 当中心像素点的像素值与平均值差的绝对值大于阈值的时候才做滤波处理。这样既可以对噪声进行平滑,图像细节上的损失也很小。

    三 均值滤波的实现及优化

    本文的重点是介绍均值滤波的实现以及算法层面的优化,相应的会给出均值滤波不同优化版本的C代码实现。均值滤波的计算主要分为两个部分,一个是加法运算,一个是除法运算。我们优化的目标就是减少加法和除法运算的次数。我们是基于5*5的均值滤波为例进行算法层面的优化。

    (1)方案一:按照均值滤波定义的方式来实现均值滤波,如Fig 1所示。

    static void BlurU8_5x5_C(DdrPoint* pDdrPoint, BlurU8Param* pParam)
    {
        float sum = 0.0;
        int dstChannel = pParam->dstChannel;
        int dstWidth = pParam->dstWidth;
        int dstHeight = pParam->dstHeight;
        int dstStride = pParam->dstStride;
        int srcWidth = pParam->srcWidth;
        int srcHeight = pParam->srcHeight;
        int srcStride = pParam->srcStride;
        int wSizeWidth = pParam->wSizeWidth;
        int wSizeHeight = pParam->wSizeHeight;
        int kSize = wSizeWidth * wSizeHeight;
        for (int k = 0; k < dstChannel; ++k)
        {
            int srcWidthTmp = srcWidth + (wSizeWidth / 2) * 2;
            int srcHeightTmp = srcHeight + (wSizeHeight / 2) * 2;
    
            unsigned char* pSrcTmpU8 = pDdrPoint->pSrcU8 + k * srcWidth * srcHeight;
            unsigned char* pDstTmpU8 = pDdrPoint->pDstU8 + k * dstWidth * dstHeight;
            unsigned char* pTmpBuffer = (unsigned char*)malloc(srcWidthTmp * srcHeightTmp);
            memset(pTmpBuffer, 0, srcWidthTmp * srcHeightTmp);
            unsigned char* pSrcTmpBuffer = pTmpBuffer + srcWidthTmp + (wSizeWidth / 2);
            for (int i = 0; i < srcHeight; ++i)
            {
                memcpy((pSrcTmpBuffer + i * srcWidthTmp), (pSrcTmpU8 + i * srcWidth), srcWidth);
            }
    
            for (int r = 0; r < dstHeight; ++r)
            {
                for (int c = 0; c < dstWidth; ++c)
                {
                    sum = 0.0;
    
                    // SUM
                    for (int i = r - wSizeHeight / 2; i <= r + wSizeHeight / 2; ++i)
                    {
                        for (int j = c - wSizeWidth / 2; j <= c + wSizeWidth / 2; ++j)
                        {
                            sum += *(pSrcTmpBuffer + i * srcWidthTmp + j);
                        }
                    }
    
                    // AVE STORE
                    *(pDstTmpU8 + r * dstStride + c) = (int)((sum + kSize / 2) / kSize);
                }
            }
    
            free(pTmpBuffer);
        }
    }

    这样的实现方式可以实现均值滤波的效果但是效率上是有问题的,可以发现这样实现方案,存在着大量的重复计算的过程。当滑动窗口进行滑动的时候,相邻两个窗口之间存在着大量重叠的像素,该版本的均值滤波对这部分的代码做了重复计算。针对这个问题我们推出版本2的均值滤波。

    (2)方案二:我们可以发现当滑动窗口从左向右滑动的时候,每一次滑动前后两个窗口之间,像素集合只改变了左右两列元素。所以我们可以将窗口像素和的结果保存在一个变量中,每次滑动时候减去最左侧移除的像素值,加上最右侧新加入的像素值就可以。

       

       Fig 3 方案2算法示意图

    static void BlurU8_5x5_C(DdrPoint* pDdrPoint, BlurU8Param* pParam)
    {
        float sum = 0.0;
        int dstChannel = pParam->dstChannel;
        int dstWidth = pParam->dstWidth;
        int dstHeight = pParam->dstHeight;
        int dstStride = pParam->dstStride;
        int srcWidth = pParam->srcWidth;
        int srcHeight = pParam->srcHeight;
        int srcStride = pParam->srcStride;
        int wSizeWidth = pParam->wSizeWidth;
        int wSizeHeight = pParam->wSizeHeight;
        int kSize = wSizeWidth * wSizeHeight;
    
        for (int k = 0; k < dstChannel; ++k)
        {
            int srcWidthTmp = srcWidth + (wSizeWidth / 2) * 2;
            int srcHeightTmp = srcHeight + (wSizeHeight / 2) * 2;
    
            unsigned char* pSrcTmpU8 = pDdrPoint->pSrcU8 + k * srcWidth * srcHeight;
            unsigned char* pDstTmpU8 = pDdrPoint->pDstU8 + k * dstWidth * dstHeight;
            unsigned char* pTmpBuffer = (unsigned char*)malloc(srcWidthTmp * srcHeightTmp);
            memset(pTmpBuffer, 0, srcWidthTmp * srcHeightTmp);
            unsigned char* pSrcTmpBuffer = pTmpBuffer + (wSizeHeight / 2) * srcWidthTmp + (wSizeWidth / 2);
            for (int i = 0; i < srcHeight; ++i)
            {
                memcpy((pSrcTmpBuffer + i * srcWidthTmp), (pSrcTmpU8 + i * srcWidth), srcWidth);
            }
    
            for (int r = 0; r < dstHeight; ++r)
            {
                sum = 0.0;
    
                sum += *(pSrcTmpBuffer + r * srcWidthTmp - 2*srcWidthTmp - 2);
                sum += *(pSrcTmpBuffer + r * srcWidthTmp - 2*srcWidthTmp - 1);
                sum += *(pSrcTmpBuffer + r * srcWidthTmp - 2*srcWidthTmp);
                sum += *(pSrcTmpBuffer + r * srcWidthTmp - 2*srcWidthTmp + 1);
                sum += *(pSrcTmpBuffer + r * srcWidthTmp - 2*srcWidthTmp + 2);
                sum += *(pSrcTmpBuffer + r * srcWidthTmp - srcWidthTmp - 2);
                sum += *(pSrcTmpBuffer + r * srcWidthTmp - srcWidthTmp - 1);
                sum += *(pSrcTmpBuffer + r * srcWidthTmp - srcWidthTmp);
                sum += *(pSrcTmpBuffer + r * srcWidthTmp - srcWidthTmp + 1);
                sum += *(pSrcTmpBuffer + r * srcWidthTmp - srcWidthTmp + 2);
                sum += *(pSrcTmpBuffer + r * srcWidthTmp - 2);
                sum += *(pSrcTmpBuffer + r * srcWidthTmp - 1);
                sum += *(pSrcTmpBuffer + r * srcWidthTmp);
                sum += *(pSrcTmpBuffer + r * srcWidthTmp + 1);
                sum += *(pSrcTmpBuffer + r * srcWidthTmp + 2);
                sum += *(pSrcTmpBuffer + r * srcWidthTmp + srcWidthTmp - 2);
                sum += *(pSrcTmpBuffer + r * srcWidthTmp + srcWidthTmp - 1);
                sum += *(pSrcTmpBuffer + r * srcWidthTmp + srcWidthTmp);
                sum += *(pSrcTmpBuffer + r * srcWidthTmp + srcWidthTmp + 1);
                sum += *(pSrcTmpBuffer + r * srcWidthTmp + srcWidthTmp + 2);
                sum += *(pSrcTmpBuffer + r * srcWidthTmp + 2*srcWidthTmp - 2);
                sum += *(pSrcTmpBuffer + r * srcWidthTmp + 2*srcWidthTmp - 1);
                sum += *(pSrcTmpBuffer + r * srcWidthTmp + 2*srcWidthTmp);
                sum += *(pSrcTmpBuffer + r * srcWidthTmp + 2*srcWidthTmp + 1);
                sum += *(pSrcTmpBuffer + r * srcWidthTmp + 2*srcWidthTmp + 2);
                *(pDstTmpU8 + r * dstStride) = (int)((sum + kSize / 2) / kSize);
    
                for (int c = 1; c < dstWidth; ++c)
                {
                    // SUM
                    sum -= *(pSrcTmpBuffer + r * srcWidthTmp + c - 2);
                    sum -= *(pSrcTmpBuffer + r * srcWidthTmp + c - srcWidthTmp - 2);
                    sum -= *(pSrcTmpBuffer + r * srcWidthTmp + c + srcWidthTmp - 2);
                    sum -= *(pSrcTmpBuffer + r * srcWidthTmp + c - 2*srcWidthTmp - 2);
                    sum -= *(pSrcTmpBuffer + r * srcWidthTmp + c + 2*srcWidthTmp - 2);
                    sum += *(pSrcTmpBuffer + r * srcWidthTmp + c + 1);
                    sum += *(pSrcTmpBuffer + r * srcWidthTmp + c - srcWidthTmp + 1);
                    sum += *(pSrcTmpBuffer + r * srcWidthTmp + c + srcWidthTmp + 1);
                    sum += *(pSrcTmpBuffer + r * srcWidthTmp + c - 2*srcWidthTmp + 1);
                    sum += *(pSrcTmpBuffer + r * srcWidthTmp + c + 2*srcWidthTmp + 1);
    
                    // AVE STORE
                    *(pDstTmpU8 + r * dstStride + c) = (int)((sum + kSize / 2) / kSize);
                }
            }
    
            free(pTmpBuffer);
        }
    }

    (3) 方案3:经过方案2的优化之后,我们发现相比方案1我们的效率有所提升,但是单独就滑动窗口左右两侧的像素计算还是存在重复。所以我们改进了一下,减少左右两侧像素的重复计算。相比方案2我们将为图像的每一列申请一个缓存buf, 用于存储列方向的累加和。计算均值时首先是行方向的累加,就是将相应的5个buf累加。列方向移动时,需要更新buf内的值。

      

      Fig 4 方案3算法示意图

    static void BlurU8_5x5_C(DdrPoint* pDdrPoint, BlurU8Param* pParam)
    {
    	float sum = 0.0;
    	int dstChannel = pParam->dstChannel;
    	int dstWidth = pParam->dstWidth;
    	int dstHeight = pParam->dstHeight;
    	int dstStride = pParam->dstStride;
    	int srcWidth = pParam->srcWidth;
    	int srcHeight = pParam->srcHeight;
    	int srcStride = pParam->srcStride;
    	int wSizeWidth = pParam->wSizeWidth;
    	int wSizeHeight = pParam->wSizeHeight;
    	int kSize = wSizeWidth * wSizeHeight;
    
    	for (int k = 0; k < dstChannel; ++k)
    	{
    		int srcWidthTmp = srcWidth + (wSizeWidth / 2) * 2;
    		int srcHeightTmp = srcHeight + (wSizeHeight / 2) * 2;
    
    		int* sumTmp = (int*)malloc(srcWidthTmp * sizeof(int));
    		unsigned char* pSrcTmpU8 = pDdrPoint->pSrcU8 + k * srcWidth * srcHeight;
    		unsigned char* pDstTmpU8 = pDdrPoint->pDstU8 + k * dstWidth * dstHeight;
    		unsigned char* pTmpBuffer = (unsigned char*)malloc(srcWidthTmp * srcHeightTmp);
    		memset(pTmpBuffer, 0, srcWidthTmp * srcHeightTmp);
    		unsigned char* pSrcTmpBuffer = pTmpBuffer + (wSizeHeight / 2) * srcWidthTmp;
    		for (int i = 0; i < srcHeight; ++i)
    		{
    			memcpy((pSrcTmpBuffer + (wSizeWidth / 2) + i * srcWidthTmp), (pSrcTmpU8 + i * srcWidth), srcWidth);
    		}
    
    		memset(sumTmp, 0, srcWidthTmp * sizeof(int));
    
    		for (int i = 0; i < srcWidthTmp; ++i)
    		{
    			sumTmp[i] += *(pSrcTmpBuffer - 2 * srcWidthTmp + i);
    			sumTmp[i] += *(pSrcTmpBuffer - srcWidthTmp + i);
    			sumTmp[i] += *(pSrcTmpBuffer + i);
    			sumTmp[i] += *(pSrcTmpBuffer + srcWidthTmp + i);
    			sumTmp[i] += *(pSrcTmpBuffer + 2 * srcWidthTmp + i);
    		}
    
    		for (int r = 0; r < dstHeight; ++r)
    		{
    			int index = 2;
    			sum = 0.0;
    
    			sum = sumTmp[0] + sumTmp[1] + sumTmp[2] + sumTmp[3] + sumTmp[4];
    			*(pDstTmpU8 + r * dstStride) = (int)((sum + kSize / 2) / kSize);
    
    			for (int c = 1; c < dstWidth; ++c)
    			{
    				int index = (wSizeWidth / 2) + c - 3;
    				SUM
    				sum -= sumTmp[index];
    	
    				sum += sumTmp[index+5];
    
    				// AVE STORE
    				*(pDstTmpU8 + r * dstStride + c) = (int)((sum + kSize / 2) / kSize);
    			}
    
    			for (int i = 0; i < srcWidthTmp; ++i)
    			{
    				sumTmp[i] -= *(pSrcTmpBuffer + r * srcWidthTmp - 2 * srcWidthTmp + i);
    				sumTmp[i] += *(pSrcTmpBuffer + r * srcWidthTmp + 3 * srcWidthTmp + i);
    			}
    		}
    
    		free(pTmpBuffer);
    	}
    }

    (4) 方案4:经过上述上个步骤我们已经对均值滤波优化有了一个大幅度的提升,以上三个部分是针对加法部分优化,适用于任何情况。如果我们的图片输入输出类型都是8bit, 我们还可以对我们的均值滤波中的除法运算进行优化。我们可以提前建立一张表,用于存储除法所有可能的结果,然后就可以将除法运算改成查找表,实现性能上的提升。

    int divisionRes[255*25];
    static void BlurU8_5x5_C(DdrPoint* pDdrPoint, BlurU8Param* pParam)
    {
            int res = -1;
            for (int i = 0; i < 255 * 25; ++i)
           {
                if (i % 25 == 0)
               {
                   ++res;
               }
               divisionRes[i] = res;
            }
    	float sum = 0.0;
    	int dstChannel = pParam->dstChannel;
    	int dstWidth = pParam->dstWidth;
    	int dstHeight = pParam->dstHeight;
    	int dstStride = pParam->dstStride;
    	int srcWidth = pParam->srcWidth;
    	int srcHeight = pParam->srcHeight;
    	int srcStride = pParam->srcStride;
    	int wSizeWidth = pParam->wSizeWidth;
    	int wSizeHeight = pParam->wSizeHeight;
    	int kSize = wSizeWidth * wSizeHeight;
    
    	for (int k = 0; k < dstChannel; ++k)
    	{
    		int srcWidthTmp = srcWidth + (wSizeWidth / 2) * 2;
    		int srcHeightTmp = srcHeight + (wSizeHeight / 2) * 2;
    
    		int* sumTmp = (int*)malloc(srcWidthTmp * sizeof(int));
    		unsigned char* pSrcTmpU8 = pDdrPoint->pSrcU8 + k * srcWidth * srcHeight;
    		unsigned char* pDstTmpU8 = pDdrPoint->pDstU8 + k * dstWidth * dstHeight;
    		unsigned char* pTmpBuffer = (unsigned char*)malloc(srcWidthTmp * srcHeightTmp);
    		memset(pTmpBuffer, 0, srcWidthTmp * srcHeightTmp);
    		unsigned char* pSrcTmpBuffer = pTmpBuffer + (wSizeHeight / 2) * srcWidthTmp;
    		for (int i = 0; i < srcHeight; ++i)
    		{
    			memcpy((pSrcTmpBuffer + (wSizeWidth / 2) + i * srcWidthTmp), (pSrcTmpU8 + i * srcWidth), srcWidth);
    		}
    
    		memset(sumTmp, 0, srcWidthTmp * sizeof(int));
    
    		for (int i = 0; i < srcWidthTmp; ++i)
    		{
    			sumTmp[i] += *(pSrcTmpBuffer - 2 * srcWidthTmp + i);
    			sumTmp[i] += *(pSrcTmpBuffer - srcWidthTmp + i);
    			sumTmp[i] += *(pSrcTmpBuffer + i);
    			sumTmp[i] += *(pSrcTmpBuffer + srcWidthTmp + i);
    			sumTmp[i] += *(pSrcTmpBuffer + 2 * srcWidthTmp + i);
    		}
    
    		for (int r = 0; r < dstHeight; ++r)
    		{
    			int index = 2;
    			sum = 0.0;
    
    			sum = sumTmp[0] + sumTmp[1] + sumTmp[2] + sumTmp[3] + sumTmp[4];
    			*(pDstTmpU8 + r * dstStride + c) = divisionRes[int(sum + kSize / 2)];
    
    			for (int c = 1; c < dstWidth; ++c)
    			{
    				int index = (wSizeWidth / 2) + c - 3;
    				SUM
    				sum -= sumTmp[index];
    	
    				sum += sumTmp[index+5];
    
    				// AVE STORE
    				*(pDstTmpU8 + r * dstStride + c) = divisionRes[int(sum + kSize / 2)];
    			}
    
    			for (int i = 0; i < srcWidthTmp; ++i)
    			{
    				sumTmp[i] -= *(pSrcTmpBuffer + r * srcWidthTmp - 2 * srcWidthTmp + i);
    				sumTmp[i] += *(pSrcTmpBuffer + r * srcWidthTmp + 3 * srcWidthTmp + i);
    			}
    		}
    
    		free(pTmpBuffer);
    	}
    }

        关于均值滤波的NEON优化,详见下一篇《均值滤波NEON实现及优化》。

     

     

    展开全文
  • 滤波算法——均值滤波,中值滤波,一阶(αβ)滤波,卡尔曼滤波 因工作涉及到数据滤波(滤噪)处理,汇总了一些网上简单的滤波算法,方便日后查看。 滤波算法包括:均值滤波,中值滤波,一阶(αβ)滤波,卡尔曼滤波。 ...
  • OpenCV——均值滤波

    2021-06-11 15:34:27
    均值滤波将滤波器内所有的像素值都看作中心像素值的测量,将滤波器内所有的像数值的平均值作为滤波器中心处图像像素值。滤波器内的每个数据表示对应的像素在决定中心像素值的过程中所占的权重,由于滤波器内所有的...
  • 1. 均值滤波先创建一个 medfilter.m 文件,代码如下:function [output] = meansfilter(input, radius)%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% input: 噪声图像% r: 图像块半径%% Auther: Gao Zheng jie% Email: ...
  • K近邻均值滤波

    2021-04-18 10:27:26
    subplot(1,2,2),imshow( uint8(m)),title('普通均值滤波'); %2 计算三种算法的峰值信噪比 B=8; %编码一个像素用多少二进制位 MAX=2^B-1; %图像有多少灰度级 I=double(I); l=double(l); m=double(m); % psnr2 = 32....
  • 实例三、滑动均值滤波(Moving Average)四、C语言面向面向对象实现滑动均值滤波 一、背景 在实际的数据采集中,我们经常会取多次数据的均值来减小误差。 二、平均值滤波 1.算法介绍 平均值滤波算法是比较常用,也...
  • 非局部均值滤波matlab

    2021-04-23 18:09:03
    深入剖析传统神经网络非均匀性校正方法收敛速度慢以及易产生“鬼影”现象的主要原因,在 此基础上,提出一种基于非局部均值滤波和神经网络的红外焦平面阵列非均匀性校正......512 的图像,大概在一台普通 PC 上要运行 ...
  • PCL 点云均值滤波

    2021-09-24 20:18:10
    点云均值滤波
  • %均值滤波%方法一:filter2clear all;figureI=rgb2gray(imread('132.jpg'));I=imnoise(I,'salt& pepper',0.1); %加入椒盐噪声K1=filter2(fspecial('average',3),I)/255; %进行3*3均值滤波K2=filter2(fspecial('...
  • 040920108 均值滤波

    2021-04-23 15:44:35
    040920108/bgrickerwavelet.m040920108/change.m040920108/GaussFilterMatrix.m040920108/hw7_b.m040920108/jiangdifen.m040920108/jiangdifen1.m040920108/jiaquanFilter.m040920108/jiaquanfilter1.asv040920108/j...
  • 高斯滤波 中值滤波 均值滤波

    千次阅读 2021-02-25 10:27:32
    中值模板的卷积对去除椒盐噪声有比较好的作用但均值滤波的降噪效果不佳。对于高斯噪声通过高斯滤波去除噪声。 中值滤波,将模板内的像素数据,按从小到大的顺序排列,取中间的像素替换原始像素的卷积操作。注:如果
  • 计算均值滤波时,需要每次求数组的和,再求均值,一般先放入一个数组,循环移出最后一个旧的值循环移入新的值一般原来的做法/******************************************************************************//***...
  • python手写均值滤波

    2021-01-11 22:48:40
    本文实例为大家分享了python手写均值滤波的具体代码,供大家参考,具体内容如下原理与卷积类似,设置一个n*n的滤波模板,滤波模板内的值累加除以模板的尺寸大小取平均为滤波后的值。代码如下:import cv2 as cv...
  • 由于椒盐噪声存在,算数均值滤波表现不良好,会让滤波后的图像处于“灰蒙蒙”的状态 修正的阿尔法均值滤波去除了“极端像素点”,再进行平均滤波,效果就要比算术均值滤波好很多了。 源代码 picture=imread('ckt-...
  • matlab均值滤波实现

    万次阅读 多人点赞 2018-10-14 22:04:11
    一、噪声添加 椒盐噪声: I_noise=double(imnoise(I,'salt ...二、均值滤波原理 主要思想为邻域平均法,即用几个像素灰度的平均值来代替每个像素的灰度。有效抑制加性噪声。 缺点:容易引起图像模糊,可以对其进行改...
  • 本文实例为大家分享了opencv+python实现均值滤波的具体代码,供大家参考,具体内容如下原理均值滤波其实就是对目标像素及周边像素取平均值后再填回目标像素来实现滤波目的的方法,当滤波核的大小是3×3 3\times 33×...
  • 文章目录滤波原理相关与卷积边界处理均值滤波理论基础自定义滤波函数实现 滤波原理 空间滤波器有一个邻域和对该邻域包围的图像像素执行的预定义操作组成。滤波产生一个新像素,新像素的坐标等于邻域中心的坐标,像素...
  • 用MATLAB编程实现均值滤波算法?关注:69答案:2手机版解决时间 2021-01-26 22:33提问者女人不需要倾国倾城2021-01-26 07:49用MATLAB编程实现均值滤波算法? (采用3×3的窗口) 要求简洁 明了最佳答案二级知识专家闪光的...
  • 《实验三均值滤波和中值滤波》由会员分享,可在线阅读,更多相关《实验三均值滤波和中值滤波(2页珍藏版)》请在人人文库网上搜索。1、实验三 均值滤波和中值滤波实验目的进一步了解 MatLab 软件 /语言,学会使用 ...
  • subplot(1,2,2),imshow( uint8(m)),title('普通均值滤波'); %2 计算三种算法的峰值信噪比 B=8; %编码一个像素用多少二进制位 MAX=2^B-1; %图像有多少灰度级 I=double(I); l=double(l); m=double(m); % psnr2 = 32....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 25,015
精华内容 10,006
关键字:

均值滤波