2015-08-22 16:13:12 Kena_M 阅读数 3908
  • 机器学习之概率与统计推断

    本课程讲解机器学习算法所需概率和统计推断知识。概率部分包括概率公理及推论、条件概率、贝叶斯公式、随机变量及其概率函数(CDF/pdf)、常用概率分布及其均值、方差;统计推断部分包括大数定律和中心极限定理、极大似然估计、贝叶斯估计,估计的评价、偏差-方差平衡。课程还会讲解假设检验的基本概念。

    20464 人正在学习 去看看 AI100讲师

​忙里偷闲,整理了一下之前看的材料和自己实现的代码,这次说说均值滤波的事儿。

之前写过关于中值滤波的函数,传送门<<请戳我。


均值滤波,说简单点无非是一个盒子滤波器,从左上到右下划过整个图像,看似简单,可是当仔细研究,会发现,这一机械式的循环过程中包含了大量的重复计算,,,对于我这种重度强迫症患者,,,简直不能忍,,,,


来看一个快速的均值滤波算法思路:

因为一个数据集合的均值仅与该集合中的元素值的累加和有关,与分布形式无关,所以均值滤波采用邻域的累加值来维持交集内的像素的累加和。即:

average=sumN×M

在同一行上,当从一个象素 g(x,y) 移动到下一个象素 g(x+1,y) 时,累加和的变化为:

sum=sumj=M/2M/2g(xN2,y+j)+j=M/2M/2g(x+1+N2,y+j)

其中:
j=M/2M/2g(xN2,y+j)是去掉的左边列的像素的累加和;
j=M/2M/2g(x+1+N2,y+j)是新添的右边列的象素的累加和;
在考虑换行时,相邻行之间象素的邻域也有大量的重叠区域,如何记录从一行换到下一行的交集信息呢?分析可知,实际上改变了邻域中按列的累加和,因此,还需要一个数据结构记录邻域中每列的累加和,水平滑动时去左添右,垂直换行时去上添下。

请看图加深理解

均值滤波

好了,有这些就够了,下面上代码

/**
 * @brief Fast mean filter
 * @param src
 * @param width
 * @param height
 * @param maskw
 * @param maskh
 */
void meanBlur(unsigned char* src, int width, int height, int maskw, int maskh)
{
    int i, j, l, temp;
    int width1 = width + maskw - 1;
    int height1 = height + maskh - 1;
    int *sumCol = NULL;
    int *psum, *ps;
    int masksz = maskw * maskh;
    unsigned char *pCurOrg, *pCurObj, *pu, *pd;
    unsigned char *src1 = NULL;
    sumCol = Malloc(int, width1);
    memset(sumCol, 0, width1 * sizeof(int));
    src1 = Malloc(unsigned char, width1 * height1);
    //获得带边界扩展的图像副本
    boundaryExtention(src, src1, width, height, maskw, maskh, width1, height1);
    //清空原图像数据
    memset(src, 0, width * height * sizeof(unsigned char));
    //构造首个横向滑窗列
    //sumCol[i] = sum(和滑窗等高的每一列像素灰度)
    for(i = 0, psum = sumCol; i < width1; i++, psum++)
        for(j = 0, pCurOrg = src1 + i; j < maskh; j++, pCurOrg += width1)
            *psum += *pCurOrg;
    for(i = 0, pCurObj = src; i < height; i++)
    {
        psum = sumCol;
        temp = 0;
        temp = sumVect(sumCol, maskw);
        pCurObj = src + i * width;
        *pCurObj++ = temp / masksz;
        for(j = 1; j < width; j++, psum++)
        {
            temp = temp - *psum + *(psum + maskw);
            *pCurObj++ = temp / masksz;
        }
        for(pu = src1 + i * width1, pd = src1 + (i + maskh) * width1, ps = sumCol, l = 0; l < width1; l++, ps++, pd++, pu++)
            *ps = *ps + *pd - *pu;
    }
    free(sumCol);
    free(src1);
}

其中,boundaryExtention()为边界扩展函数,采用复制最近元素的方式进行扩展;sumVect()是求指定长度向量的和,再次都贴出来吧。

/**
* @brief Generate a boundary-extended image to mask by boundary-replicate;
* @param src
* @param dst
* @param width
* @param height
* @param nwidth
* @param nheight
* @param new_w
* @param new_h
*/
void boundaryExtention(unsigned char* src, unsigned char *dst, int width, int height, int nwidth, int nheight, int new_w, int new_h )
{
   int i;
   int half_nw, half_nh;
   unsigned char *pCurOrg, *pCurObj;
   if(nwidth / 2 != (nwidth - 1) / 2)
   {
       printf("The mask window width is not odd !\n");
       return;
   }
   if(nheight / 2 != (nheight - 1) / 2)
   {
       printf("The mask window height is not odd !\n");
       return;
   }
   half_nw = nwidth / 2;
   half_nh = nheight / 2;
   if(new_w != width + nwidth - 1 || new_h != height + nheight - 1)
   {
       printf("The extended image space caculated is wrong!");
       return;
   }
   memset(dst, 0, new_w * new_h * sizeof(unsigned char));

   //水平对拷
   for(i = 0, pCurOrg = src, pCurObj = dst + half_nw; i < half_nh; i++)
   {
       memcpy(pCurObj, pCurOrg, width);
       pCurObj = pCurObj + new_w;
   }

   for(i = 0, pCurOrg = src, pCurObj = dst + half_nh * new_w + half_nw; i < height; i++)
   {
       memcpy(pCurObj, pCurOrg, width);
       pCurOrg = pCurOrg + width;
       pCurObj = pCurObj + new_w;
   }
   for(i = 0, pCurOrg = src + (height - 1) * width, pCurObj = dst + (height + half_nh) * new_w + half_nw; i < half_nh; i++)
   {
       memcpy(pCurObj, pCurOrg, width);
       pCurObj = pCurObj + new_w;
   }

   //垂直对拷
   for(i = 0, pCurOrg = dst + half_nw, pCurObj = dst; i < new_h; i++)
   {
       memset(pCurObj, *pCurOrg, half_nw);
       pCurOrg += new_w;
       pCurObj += new_w;
   }
   for(i = 0, pCurOrg = dst + width + half_nw-1 , pCurObj = dst + width + half_nw; i < new_h; i++)
   {
       memset(pCurObj, *pCurOrg, half_nw);
       pCurOrg += new_w;
       pCurObj += new_w;
   }
   return;
}
/**
* @brief add the vect
* @param vect
* @param length
* @return the sum
*/
int sumVect(int *vect, int length)
{
   int result=0;
   int *p,*pend;
   for(p=vect,pend=vect+length;p<pend;p++)
       result += *p;
return result;
}

经测试,该均值滤波与OpenCV和的结果都是一致的,对于512*512的lena灰度图,耗时3~4ms,,,OpenCV 开挂用了Intel 的IPP库,高富帅,比不起,,,

2018-09-02 23:27:36 Eastmount 阅读数 19739
  • 机器学习之概率与统计推断

    本课程讲解机器学习算法所需概率和统计推断知识。概率部分包括概率公理及推论、条件概率、贝叶斯公式、随机变量及其概率函数(CDF/pdf)、常用概率分布及其均值、方差;统计推断部分包括大数定律和中心极限定理、极大似然估计、贝叶斯估计,估计的评价、偏差-方差平衡。课程还会讲解假设检验的基本概念。

    20464 人正在学习 去看看 AI100讲师

该系列文章是讲解Python OpenCV图像处理知识,前期主要讲解图像入门、OpenCV基础用法,中期讲解图像处理的各种算法,包括图像锐化算子、图像增强技术、图像分割等,后期结合深度学习研究图像识别、图像分类应用。希望文章对您有所帮助,如果有不足之处,还请海涵~

该系列在github所有源代码:https://github.com/eastmountyxz/ImageProcessing-Python
PS:请求帮忙点个Star,哈哈,第一次使用Github,以后会分享更多代码,一起加油。

同时推荐作者的C++图像系列知识:
[数字图像处理] 一.MFC详解显示BMP格式图片
[数字图像处理] 二.MFC单文档分割窗口显示图片
[数字图像处理] 三.MFC实现图像灰度、采样和量化功能详解
[数字图像处理] 四.MFC对话框绘制灰度直方图
[数字图像处理] 五.MFC图像点运算之灰度线性变化、灰度非线性变化、阈值化和均衡化处理详解
[数字图像处理] 六.MFC空间几何变换之图像平移、镜像、旋转、缩放详解
[数字图像处理] 七.MFC图像增强之图像普通平滑、高斯平滑、Laplacian、Sobel、Prewitt锐化详解

前文参考:
[Python图像处理] 一.图像处理基础知识及OpenCV入门函数
[Python图像处理] 二.OpenCV+Numpy库读取与修改像素
[Python图像处理] 三.获取图像属性、兴趣ROI区域及通道处理

本篇文章主要讲解Python调用OpenCV实现图像平滑,包括四个算法:均值滤波、方框滤波、高斯滤波和中值滤波。全文均是基础知识,希望对您有所帮助。知识点如下:
1.图像平滑
2.均值滤波
3.方框滤波
4.高斯滤波
5.中值滤波

PS:本文介绍图像平滑,想让大家先看看图像处理的效果,后面还会补充一些基础知识供大家学习。文章参考自己的博客及网易云课堂李大洋老师的讲解,强烈推荐大家学习。

PSS:2019年1~2月作者参加了CSDN2018年博客评选,希望您能投出宝贵的一票。我是59号,Eastmount,杨秀璋。投票地址:https://bss.csdn.net/m/topic/blog_star2018/index

五年来写了314篇博客,12个专栏,是真的热爱分享,热爱CSDN这个平台,也想帮助更多的人,专栏包括Python、数据挖掘、网络爬虫、图像处理、C#、Android等。现在也当了两年老师,更是觉得有义务教好每一个学生,让贵州学子好好写点代码,学点技术,"师者,传到授业解惑也",提前祝大家新年快乐。2019我们携手共进,为爱而生。

一.图像平滑

1.图像增强
图像增强是对图像进行处理,使其比原始图像更适合于特定的应用,它需要与实际应用相结合。对于图像的某些特征如边缘、轮廓、对比度等,图像增强是进行强调或锐化,以便于显示、观察或进一步分析与处理。图像增强的方法是因应用不同而不同的,研究内容包括:(参考课件和左飞的《数字图像处理》)

2.图像平滑
图像平滑是一种区域增强的算法,平滑算法有邻域平均法、中指滤波、边界保持类滤波等。在图像产生、传输和复制过程中,常常会因为多方面原因而被噪声干扰或出现数据丢失,降低了图像的质量(某一像素,如果它与周围像素点相比有明显的不同,则该点被噪声所感染)。这就需要对图像进行一定的增强处理以减小这些缺陷带来的影响。
简单平滑-邻域平均法

3.邻域平均法
图像简单平滑是指通过邻域简单平均对图像进行平滑处理的方法,用这种方法在一定程度上消除原始图像中的噪声、降低原始图像对比度的作用。它利用卷积运算对图像邻域的像素灰度进行平均,从而达到减小图像中噪声影响、降低图像对比度的目的。
但邻域平均值主要缺点是在降低噪声的同时使图像变得模糊,特别在边缘和细节处,而且邻域越大,在去噪能力增强的同时模糊程度越严重。

首先给出为图像增加噪声的代码。

# -*- coding:utf-8 -*-
import cv2
import numpy as np

#读取图片
img = cv2.imread("test.jpg", cv2.IMREAD_UNCHANGED)
rows, cols, chn = img.shape

#加噪声
for i in range(5000):    
    x = np.random.randint(0, rows) 
    y = np.random.randint(0, cols)    
    img[x,y,:] = 255

cv2.imshow("noise", img)
           
#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()

输出结果如下所示:



二.均值滤波

1.原理
均值滤波是指任意一点的像素值,都是周围N*M个像素值的均值。例如下图中,红色点的像素值为蓝色背景区域像素值之和除25。

其中红色区域的像素值均值滤波处理过程为: ((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

其中5*5的矩阵称为核,针对原始图像内的像素点,采用核进行处理,得到结果图像。

提取1/25可以将核转换为如下形式:

2.代码
Python调用OpenCV实现均值滤波的核心函数如下:
result = cv2.blur(原始图像,核大小)
其中,核大小是以(宽度,高度)表示的元祖形式。常见的形式包括:核大小(3,3)和(5,5)。
K=19[111111111](1) K=\frac{1}{9}\left[ \begin{matrix} 1 & 1 & 1 \\ 1 & 1 & 1 \\ 1 & 1 & 1 \end{matrix} \right] \tag{1}
K=125[1111111111111111111111111](2) K=\frac{1}{25}\left[ \begin{matrix} 1 & 1 & 1 & 1 & 1 \\ 1 & 1 & 1 & 1 & 1 \\ 1 & 1 & 1 & 1 & 1 \\ 1 & 1 & 1 & 1 & 1 \\ 1 & 1 & 1 & 1 & 1 \\ \end{matrix} \right] \tag{2}

代码如下所示:

#encoding:utf-8
import cv2  
import numpy as np  
import matplotlib.pyplot as plt
 
#读取图片
img = cv2.imread('test01.png')
source = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
 
#均值滤波
result = cv2.blur(source, (5,5))
 
#显示图形
titles = ['Source Image', 'Blur Image']  
images = [source, result]  
for i in xrange(2):  
   plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray')  
   plt.title(titles[i])  
   plt.xticks([]),plt.yticks([])  
plt.show()  

输出结果如下图所示:

核设置为(10,10)和(20,20)会让图像变得更加模糊。

如果设置为(1,1)处理结果就是原图,核中每个权重值相同,称为均值。



三.方框滤波

方框滤波和均值滤波核基本一致,区别是需不需要均一化处理。OpenCV调用boxFilter()函数实现方框滤波。函数如下:
result = cv2.boxFilter(原始图像, 目标图像深度, 核大小, normalize属性)
其中,目标图像深度是int类型,通常用“-1”表示与原始图像一直;核大小主要包括(3,3)和(5,5),如下所示。

K=19[111111111](3) K=\frac{1}{9}\left[ \begin{matrix} 1 & 1 & 1 \\ 1 & 1 & 1 \\ 1 & 1 & 1 \end{matrix} \right] \tag{3}
K=125[1111111111111111111111111](4) K=\frac{1}{25}\left[ \begin{matrix} 1 & 1 & 1 & 1 & 1 \\ 1 & 1 & 1 & 1 & 1 \\ 1 & 1 & 1 & 1 & 1 \\ 1 & 1 & 1 & 1 & 1 \\ 1 & 1 & 1 & 1 & 1 \\ \end{matrix} \right] \tag{4}

normalize属性表示是否对目标图像进行归一化处理。当normalize为true时需要执行均值化处理,当normalize为false时,不进行均值化处理,实际上为求周围各像素的和,很容易发生溢出,溢出时均为白色,对应像素值为255。

在图像简单平滑中,算法利用卷积模板逐一处理图像中每个像素,这一过程可以形象地比作对原始图像的像素一一进行过滤整理,在图像处理中把邻域像素逐一处理的算法过程称为滤波器。平滑线性滤波器的工作原理是利用模板对邻域内像素灰度进行加权平均,也称为均值滤波器。

代码如下所示:

#encoding:utf-8
import cv2  
import numpy as np  
import matplotlib.pyplot as plt
 
#读取图片
img = cv2.imread('test01.png')
source = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
 
#方框滤波
result = cv2.boxFilter(source, -1, (5,5), normalize=1)
 
#显示图形
titles = ['Source Image', 'BoxFilter Image']  
images = [source, result]  
for i in xrange(2):  
   plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray')  
   plt.title(titles[i])  
   plt.xticks([]),plt.yticks([])  
plt.show()  

代码中使用5*5的核,normalize=1表示进行归一化处理,此时与均值滤波相同,输出结果如下图所示:

下面是图像左上角处理前后的像素结果:

print(source[0:3, 0:3, 0])
#[[115 180 106]
# [ 83 152  72]
# [ 55  58  55]]
print(result[0:3, 0:3, 0])
#[[92 90 78]
# [92 89 77]
# [82 80 72]]

如果省略参数normalize,则默认是进行归一化处理。如果normalize=0则不进行归一化处理,像素值为周围像素之和,图像更多为白色。

#encoding:utf-8
import cv2  
import numpy as np  
import matplotlib.pyplot as plt
 
#读取图片
img = cv2.imread('test01.png')
source = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
 
#方框滤波
result = cv2.boxFilter(source, -1, (5,5), normalize=0)
 
#显示图形
titles = ['Source Image', 'BoxFilter Image']  
images = [source, result]  
for i in xrange(2):  
   plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray')  
   plt.title(titles[i])  
   plt.xticks([]),plt.yticks([])  
plt.show() 

输出结果如下图所示:

上图很多像素为白色,因为图像求和结果几乎都是255。如果设置的是2*2矩阵,只取四个像素结果要好些。
result = cv2.boxFilter(source, -1, (2,2), normalize=0)



四.高斯滤波

为了克服简单局部平均法的弊端(图像模糊),目前已提出许多保持边缘、细节的局部平滑算法。它们的出发点都集中在如何选择邻域的大小、形状和方向、参数加平均及邻域各店的权重系数等。
图像高斯平滑也是邻域平均的思想对图像进行平滑的一种方法,在图像高斯平滑中,对图像进行平均时,不同位置的像素被赋予了不同的权重。高斯平滑与简单平滑不同,它在对邻域内像素进行平均时,给予不同位置的像素不同的权值,下图的所示的 3 * 3 和 5 * 5 领域的高斯模板。

高斯滤波让临近的像素具有更高的重要度,对周围像素计算加权平均值,较近的像素具有较大的权重值。如下图所示,中心位置权重最高为0.4。

Python中OpenCV主要调用GaussianBlur函数,如下:
dst = cv2.GaussianBlur(src, ksize, sigmaX)
其中,src表示原始图像,ksize表示核大小,sigmaX表示X方向方差。注意,核大小(N, N)必须是奇数,X方向方差主要控制权重。

K(3,3)=[0.050.10.050.10.40.10.050.10.05](5) K(3,3)=\left[ \begin{matrix} 0.05 & 0.1 & 0.05 \\ 0.1 & 0.4 & 0.1 \\ 0.05 & 0.1 & 0.05 \end{matrix} \right] \tag{5}
K(5,5)=[1121113431248421343111211](4) K(5,5)=\left[ \begin{matrix} 1 & 1 & 2 & 1 & 1 \\ 1 & 3 & 4 & 3 & 1 \\ 2 & 4 & 8 & 4 & 2 \\ 1 & 3 & 4 & 3 & 1 \\ 1 & 1 & 2 & 1 & 1 \\ \end{matrix} \right] \tag{4}

代码如下:

#encoding:utf-8
import cv2  
import numpy as np  
import matplotlib.pyplot as plt
 
#读取图片
img = cv2.imread('test01.png')
source = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
 
#高斯滤波
result = cv2.GaussianBlur(source, (3,3), 0)

#显示图形
titles = ['Source Image', 'GaussianBlur Image']  
images = [source, result]  
for i in xrange(2):  
   plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray')  
   plt.title(titles[i])  
   plt.xticks([]),plt.yticks([])  
plt.show()  

输出结果如下所示:

如果使用15*15的核,则图形将更加模糊。



五.中值滤波

1.概念
在使用邻域平均法去噪的同时也使得边界变得模糊。而中值滤波是非线性的图像处理方法,在去噪的同时可以兼顾到边界信息的保留。选一个含有奇数点的窗口W,将这个窗口在图像上扫描,把窗口中所含的像素点按灰度级的升或降序排列,取位于中间的灰度值来代替该点的灰度值。 例如选择滤波的窗口如下图,是一个一维的窗口,待处理像素的灰度取这个模板中灰度的中值,滤波过程如下:

如下图所示,将临近像素按照大小排列,取排序像素中位于中间位置的值作为中值滤波的像素值。

2.代码
OpenCV主要调用medianBlur()函数实现中值滤波。图像平滑里中值滤波的效果最好。
dst = cv2.medianBlur(src, ksize)
其中,src表示源文件,ksize表示核大小。核必须是大于1的奇数,如3、5、7等。

代码如下所示:

#encoding:utf-8
import cv2  
import numpy as np  
import matplotlib.pyplot as plt
 
#读取图片
img = cv2.imread('test01.png')
 
#高斯滤波
result = cv2.medianBlur(img, 3)

#显示图像
cv2.imshow("source img", img)
cv2.imshow("medianBlur", result)

#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()

输出结果如下图所示:

常用的窗口还有方形、十字形、圆形和环形。不同形状的窗口产生不同的滤波效果,方形和圆形窗口适合外轮廓线较长的物体图像,而十字形窗口对有尖顶角状的图像效果好。中值滤波对于消除孤立点和线段的干扰十分有用,尤其是对于二进噪声,但对消除高斯噪声的影响效果不佳。对于一些细节较多的复杂图像,可以多次使用不同的中值滤波。

希望文章对大家有所帮助,如果有错误或不足之处,还请海涵。
(By:Eastmount 2018-09-01 早8点 https://blog.csdn.net/Eastmount/)

2013-06-10 17:01:54 insaneguy 阅读数 1195
  • 机器学习之概率与统计推断

    本课程讲解机器学习算法所需概率和统计推断知识。概率部分包括概率公理及推论、条件概率、贝叶斯公式、随机变量及其概率函数(CDF/pdf)、常用概率分布及其均值、方差;统计推断部分包括大数定律和中心极限定理、极大似然估计、贝叶斯估计,估计的评价、偏差-方差平衡。课程还会讲解假设检验的基本概念。

    20464 人正在学习 去看看 AI100讲师

滤波

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


均值滤波

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


效果

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


实验

使用OpenCV进行实验的部分代码:

	IplImage *pImgTmp = cvCloneImage(m_pImg);

	// 第二种边界处理:对边界特殊处理
	for (i = 0; i < m_pImg->width; i++)
	{
		for (j = 0; j < m_pImg->height; j++)
		{
			CvScalar color;
			CvScalar colorTmp;
			int m, n, cnt = 0;
			color.val[0] = color.val[1] = color.val[2] = 0;		
			for (m = i - nKernelSize/2; m <= i+nKernelSize/2; m++)
			{
				for (n = j-nKernelSize/2; n <= j+nKernelSize/2; n++)
				{
					// 处理边界和中心像素
					if ( (m == i && n == j) || m < 0 || m >= m_pImg->width 
						|| n < 0 || n >= m_pImg->height )
						continue;
					
					cvGetPixel(pImgTmp, n, m, colorTmp);
					color.val[0] += colorTmp.val[0];
					color.val[1] += colorTmp.val[1];
					color.val[2] += colorTmp.val[2];
					cnt++;
				}
			}
			// 取邻域中像素的平均值
			color.val[0] /= cnt;
			color.val[1] /= cnt;
			color.val[2] /= cnt;
			cvSetPixel(m_pImg, j, i, color);
		}
	}
	cvReleaseImage(&pImgTmp);



其中cvGetPixel和cvSetPixel的定义为:

void  cvGetPixel(const IplImage* pIplImg, int row, int col, CvScalar &color)
{
	if (col >= pIplImg->width || col < 0 ||
		row >= pIplImg->height || row < 0 )
		return;
	
	uchar *p = ((uchar*)(pIplImg->imageData + pIplImg->widthStep * row + col * 3));
	color = cvScalar(p[0], p[1], p[2]);
}

void  cvSetPixel(IplImage* pIplImg, int row, int col, CvScalar color)
{
	if (col >= pIplImg->width || col < 0 ||
		row >= pIplImg->height || row < 0 )
		return;
	
	uchar *p = ((uchar*)(pIplImg->imageData + pIplImg->widthStep * row + col * 3));
	p[2] = color.val[2];
	p[1] = color.val[1];
	p[0] = color.val[0];
}


测试图原图:



3×3模板结果:



5×5模板结果:



21×21模板结果:



参考

http://baike.baidu.com/view/1220844.htm

http://page.renren.com/601107605/note/803745240


2020-03-16 09:29:03 Ibelievesunshine 阅读数 282
  • 机器学习之概率与统计推断

    本课程讲解机器学习算法所需概率和统计推断知识。概率部分包括概率公理及推论、条件概率、贝叶斯公式、随机变量及其概率函数(CDF/pdf)、常用概率分布及其均值、方差;统计推断部分包括大数定律和中心极限定理、极大似然估计、贝叶斯估计,估计的评价、偏差-方差平衡。课程还会讲解假设检验的基本概念。

    20464 人正在学习 去看看 AI100讲师

一. 均值滤波简介和原理

        均值滤波,是图像处理中常用的手段,从频率域观点来看均值滤波是一种低通滤波器,高频信号将会去掉。均值滤波可以帮助消除图像尖锐噪声,实现图像平滑,模糊等功能。理想的均值滤波是用每个像素和它周围像素计算出来的平均值替换图像中每个像素。

        以3*3均值滤波器为例,均值滤波器算法原理如下图:

          

                          ↑


二. 用均值滤波器对椒盐噪声污染后的图像去噪

        python 源码:

import cv2

import numpy as np

# mean filter

def mean_filter(img, K_size=3):

    H, W, C = img.shape

    # zero padding

    pad = K_size // 2

    out = np.zeros((H + pad * 2, W + pad * 2, C), dtype=np.float)

    out[pad: pad + H, pad: pad + W] = img.copy().astype(np.float)

    tmp = out.copy()

    # filtering

    for y in range(H):

        for x in range(W):

            for c in range(C):

                out[pad + y, pad + x, c] = np.mean(tmp[y: y + K_size, x: x + K_size, c])

    out = out[pad: pad + H, pad: pad + W].astype(np.uint8)

    return out

# Read image

img = cv2.imread("../paojie_sp1.jpg")

# Mean Filter

out = mean_filter(img, K_size=5)

# Save result

cv2.imwrite("out.jpg", out)

cv2.imshow("result", out)

cv2.waitKey(0)

cv2.destroyAllWindows()


三. 实验结果:

          

                    原图  ↑

          

                    模板大小5*5,均值滤波后的图像 ↑

        可以看到,均值滤波后,图像中噪声虽然有所减弱,但是图像变模糊了。因为均值滤波器过滤掉了图像中的高频分量,所以图像的边缘都变模糊了。(去除一定量椒盐噪声,可以考虑使用中值滤波)


四. 参考内容:

        https://www.jianshu.com/p/8a507f44d68d

        https://www.cnblogs.com/wojianxin/p/12501891.html

2019-09-16 20:12:07 weixin_44225182 阅读数 946
  • 机器学习之概率与统计推断

    本课程讲解机器学习算法所需概率和统计推断知识。概率部分包括概率公理及推论、条件概率、贝叶斯公式、随机变量及其概率函数(CDF/pdf)、常用概率分布及其均值、方差;统计推断部分包括大数定律和中心极限定理、极大似然估计、贝叶斯估计,估计的评价、偏差-方差平衡。课程还会讲解假设检验的基本概念。

    20464 人正在学习 去看看 AI100讲师

均值滤波
代码:

 t=imread('a1.jpg');
[m,n,z]=size(t);
t1=imnoise(t,'gaussian',0,0.02);
imshow(t1),title('加入高斯噪声后')
t2=t;
for i=1:m-2
for j=1:n-2
t2(i+1,j+1,:)=round(t2(i,j,:)/9+t2(i,j+1,:)/9+t2(i,j+2,:)/9+t2(i+1,j,:)/9+t2(i+1,j+1,:)/9+t2(i+1,j+2,:)/9+t2(i+2,j,:)/9+t2(i+2,j+1,:)/9+t2(i+2,j+2,:)/9);
end
end
figure,
subplot(1,2,1),imshow(t2),title('3*3均值滤波');
t3=t;
for i=1:m-4
for j=1:n-4
t3(i+2,j+2,:)=round(t3(i,j,:)/25+t3(i,j+1,:)/25+t3(i,j+2,:)/25+t3(i,j+3,:)/25+t3(i,j+4,:)/25+t3(i+1,j,:)/25+t3(i+1,j+1,:)/25+t3(i+1,j+2,:)/25+t3(i+1,j+3,:)/25+t3(i+1,j+4,:)/25+t3(i+2,j,:)/25+t3(i+2,j+1,:)/25+...
t3(i+2,j+2,:)/25+t3(i+2,j+3,:)/25+t3(i+2,j+4,:)/25+t3(i+3,j,:)/25+t3(i+3,j+1,:)/25+t3(i+3,j+2,:)/25+t3(i+3,j+3,:)/25+t3(i+3,j+4,:)/25+...
t3(i+4,j,:)/25+t3(i+4,j+1,:)/25+t3(i+4,j+2,:)/25+t3(i+4,j+3,:)/25+t3(i+4,j+4,:)/25);
end
end
subplot(1,2,2),imshow(t3),title('5*5均值滤波');
t1=imnoise(t,'salt & pepper',0.3);
figure,imshow(t1),title('加入椒盐噪声后')
t2=t;
for i=1:m-2
for j=1:n-2
t2(i+1,j+1,:)=round(t2(i,j,:)/9+t2(i,j+1,:)/9+t2(i,j+2,:)/9+t2(i+1,j,:)/9+t2(i+1,j+1,:)/9+t2(i+1,j+2,:)/9+t2(i+2,j,:)/9+t2(i+2,j+1,:)/9+t2(i+2,j+2,:)/9);
end
end
figure,
subplot(1,2,1),imshow(t2),title('3*3均值滤波');
t3=t;
for i=1:m-4
for j=1:n-4
t3(i+2,j+2,:)=round(t3(i,j,:)/25+t3(i,j+1,:)/25+t3(i,j+2,:)/25+t3(i,j+3,:)/25+t3(i,j+4,:)/25+t3(i+1,j,:)/25+t3(i+1,j+1,:)/25+t3(i+1,j+2,:)/25+t3(i+1,j+3,:)/25+t3(i+1,j+4,:)/25+t3(i+2,j,:)/25+t3(i+2,j+1,:)/25+...
t3(i+2,j+2,:)/25+t3(i+2,j+3,:)/25+t3(i+2,j+4,:)/25+t3(i+3,j,:)/25+t3(i+3,j+1,:)/25+t3(i+3,j+2,:)/25+t3(i+3,j+3,:)/25+t3(i+3,j+4,:)/25+...
t3(i+4,j,:)/25+t3(i+4,j+1,:)/25+t3(i+4,j+2,:)/25+t3(i+4,j+3,:)/25+t3(i+4,j+4,:)/25);
end
end
subplot(1,2,2),imshow(t3),title('5*5均值滤波');

效果图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

更多

获取更多资料、代码,微信公众号:海轰Pro
回复 海轰 即可

均值滤波器的常见应用是pinghu

博文 来自: u011620352
没有更多推荐了,返回首页