第二章 基本图像处理(Image Processing)
主要内容:
- 图像的表示----介绍图像是如何表示的,以及所有基本操作的作用对象
- 高斯滤波-----滤波操作的原理与应用
- 图像金字塔-----高斯和拉普拉斯
- 边缘检测-----Sobel算子和Laplace算子
1、图像的表示
图像是由一个个的像素表示的,一个图像的像素点可以用 (x,y) 来表示位置,v来表示像素值(灰度图像的话表示一个0~255的值),因此整个图像的表示就是 {(x,y,v)} 像素点的集合。我在之前看很多图像处理的书,基本都是这样介绍的,但是CMU的课件上提出了一个我认为特别好的介绍,是把图像作为一个函数来介绍,f(x,y)=v,函数的自变量为像素点位置,函数值为像素值,画出来的函数图像如下(它把不同的像素值赋予了对应的颜色)。这个表示对后续的边缘检测、特征点获取理解帮助很大。
图像的变换基本有两个方面,一是不改变大小,改变像素点的值(即改变函数f(x,y)的值),这个操作是基于像素点的(CMU课件2.0_Point_Processing这一节对此举了不少例子 )。第二种是改变大小和像素值,这种操作一般可以改成描述为两部,第一步更改特定像素的值,第二步,在集合中删除掉部分像素点。(比如高斯图像金字塔)
2、高斯滤波
为什么需要滤波?我的理解是使图像更平滑(或者说更模糊),同时去除掉了一些噪声的干扰,为什么可以做到这样,我的理解是滤波本质上相当于把一个像素的值,跟他周围的像素值紧密联系起来,那么一个干扰点会把他的干扰分散到周围像素上,干扰强度缩小,而其本身受周围像素影响,包含了周围像素的特征,干扰强度更是大大减小,因此干扰项便不存在。
OK,CMU的课件上来讲了一个均值滤波的例子(CMU课件2.0_Box_Filter)。均值滤波的滤波器是左下这种样子的,滤波操作的公式
滤波操作的基本公式如下:h[m,n]是经过滤波操作之后,(m,n)位置处的像素值,相当于f(m+k,n+l)*g(k,l)的和,k,l是滤波器的大小,g(0,0)是中心位置。均值滤波其实就是把每个像素值,变成已它为中心,绘制1个3*3的矩形,矩形内的所有像素值的平均值。
除了均值滤波,还有中值滤波比较常见(CMU课件上没写),而且我之前应用比较多,对其颇有好感,中值滤波的原理其实根均值滤波一样,画一个矩阵,但是中值滤波中取的的是像素的中位数,这其实更适合去噪,因为我们噪声一般都是像素值比周围突出的点(这样我们人眼才能看出来他是噪声,如果隐藏在周围像素点,隐藏的比较好,那就不是噪声了),这样中值化后,它就不存在了。然后就是CMU课件中疯狂介绍的高斯滤波。
为什么是高斯滤波?首先需要明白高斯分布,高中和本科数学都学过正态分布,高斯分布其实就是正态分布,那么正态分布当初的那些性质就适合高斯分布(关于正态分布和高斯分布的介绍请移步 http://blog.csdn.net/rns521/article/details/6953591)。通过上面的介绍,其实滤波操作就是对像素进行取周围所有像素的加权和,根据经验我们知道距离该像素点越远的点对当前像素影响越小,但是无论中值滤波还是均值滤波均没考虑才到这一点,而一维高斯分布值是通过终将向两端不断减少的,二维高斯分布是向四面八方递减,那么把高斯分布作为滤波器,就可以实现不同距离的像素点的影响不同这一目的。下图左边是二维高斯分布,右边是一维高斯分布(两张图片来源于下述博客,此外关于高斯滤波的滤波矩阵推导见 http://blog.csdn.net/lonelyrains/article/details/46463987)。
那么高斯滤波有什么作用呢?CMU的课件给出了一个特别有意思的例子,就是去实现一个简单的移轴摄影,就是怎么样把左边的图像变成右边的图像。其实很简单,把第二幅图像中跟第一幅图像一样清晰的像素块取出来,加上第一幅图像中剩余的像素点,做一次高斯滤波。
课件上给出的解决方案:
3、图像金字塔
提出图像金字塔的主要目的是为了压缩图像。比如把一个图像压缩到1/2,可以怎么办?
高斯金字塔解决方案:1、将原图做一次高斯滤波 2、把做完高斯滤波图像的所有偶数行列全去掉。
整个方法看上去很不错,但是存在一个问题,怎么还原?我们先复原大小(位置值先用0表示,然后再做一次类似逆滤波的操作),但是这个时候还原回去之后,数据会存在误差。Laplacian金字塔就是把误差保存下来——其实是每次高斯滤波之后丢弃的数据。用代码去实现整个压缩过程如下:
for i from 0 to sacle:
li=blur(fi) #对图像fi做一次滤波
hi=li-fi #保存丢失信息,Laplacian金字塔
fi+1=subSample(li) #更改图像大小 ######复原代码
for i for scale to 0:
li=unSample(fi) #大小复原
fi+1=li+hi #加上误差
4、边缘检测
什么是边缘?从图像上来说是像素值的分解线,从第一小节中的二维函数图像中来看,就是周围函数值发生突然变化的像素点就是边缘。这样目的就明确了,找到附近函数值变化比较大的点,高中学的导数的定义就是函数的变化率,导数大的地方函数值变化大。问题在于图像函数是无法用表达式表达出来,因此不能用既定的求导公式去计算,在高等数学的极限和中学数学中,我们学过用下面这个公示去近似导数
CMU的课件(4.0_Image_Gradients_And_Gradient_Filtering)中列出了下面的一个例子,假设下面这一行数据是某个图像中的x方向一行的像素值,利用近似导数的方法求某个像素点附件的x导数,其实相当于乘以了右侧的过滤器。假设成了多个过滤器,即跟X在同一列上的相邻像素的近似梯度值,这样,如果这个梯度值比较大,其实就相当于这块有一条近似垂直的边界线(y方向)。
图像都是二维的,因此求x方向梯度值大的求出来都是近似垂直的边界,同时需要再利用同样的方法在求一遍y方向的梯度值变化,最后把梯度值转换成灰度值。这就是Sobel算子的原理
在CMU的课件中,还提到了一点,当然也是实际应用中非常重要的一点,Sobel算子对噪声比教敏感,因此需要在处理之前进行去噪(高斯滤波等)。
在介绍完Sobel算子之后,CMU的课件又介绍了Laplace过滤器。Laplace的原理在于求像素点的二阶导数(实际上是二阶梯度,表达式没有,二阶导数求不出来o(╯□╰)o),二阶导数是对一阶导数求导的结果,二阶导数为0,意味着一阶导数再次取到了极值,一阶导数表示灰度值的变换情况,一阶导数取到了极值,也就是说原图在此灰度值变换巨大。下图是截取自CMU课件中关于Laplace过滤器推倒的过程。
下面这张图展示了图像经过Sobel算子和Laplace过滤器之后的不同,可以看到利用Laplace过滤器的中间为0的这个特性,可以更好的定位边缘。
第二章 基本图像处理(Image Processing)的更多相关文章
- 学习opencv中文版教程——第二章
学习opencv中文版教程——第二章 所有案例,跑起来~~~然而并没有都跑起来...我只把我能跑的都尽量跑了,毕竟看书还是很生硬,能运行能出结果,才比较好. 越着急,心越慌,越是着急,越要慢,越是陌生 ...
- 第二章 Qt常用工具的介绍
第二章 Qt常用工具的介绍 (1)No.1 qmake 相信编写过Makefile的开发人员,随着工程中源码的级数递增和以类型.功能.模块组织源码的子目录的增多,都不愿意重复机械地手工编写这个工程管理 ...
- Python3-Cookbook总结 - 第二章:字符串和文本
第二章:字符串和文本 几乎所有有用的程序都会涉及到某些文本处理,不管是解析数据还是产生输出. 这一章将重点关注文本的操作处理,比如提取字符串,搜索,替换以及解析等. 大部分的问题都能简单的调用字符串的 ...
- C# Language Specification 5.0 (翻译)第二章 词法结构
程序 C# 程序(program)由至少一个源文件(source files)组成,其正式称谓为编译单元(compilation units)[1].每个源文件都是有序的 Unicode 字符序列.源 ...
- 《细说PHP》第四版 样章 第二章 PHP的应用与发展 1
<细说PHP>第四版 样章 第二章 PHP的应用与发展 1 学习任何编程语言之前,先了解一下它的应用与发展是很有必要的.从Web开发的历史看来,PHP.Python和Ruby几乎是同时出现 ...
- ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第二章:利用模型类创建视图、控制器和数据库
在这一章中,我们将直接进入项目,并且为产品和分类添加一些基本的模型类.我们将在Entity Framework的代码优先模式下,利用这些模型类创建一个数据库.我们还将学习如何在代码中创建数据库上下文类 ...
- 《Django By Example》第二章 中文 翻译 (个人学习,渣翻)
书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:翻译完第一章后,发现翻译第二章的速 ...
- Jenkins入门系列之——02第二章 Jenkins安装与配置
2014-12-08:已不再担任SCM和CI的职位,Jenkins的文章如无必要不会再维护. 写的我想吐血,累死了. 网页看着不爽的,自己去下载PDF.有问题请留言! Jenkins入门系列之——03 ...
- Python黑帽编程 2.0 第二章概述
Python黑帽编程 2.0 第二章概述 于 20世纪80年代末,Guido van Rossum发明了Python,初衷据说是为了打发圣诞节的无趣,1991年首次发布,是ABC语言的继承,同时也是一 ...
随机推荐
- bootstrap file input 官方文档翻译
file Input官方文档 中文翻译 file input 特性 1.这个插件会把简单的html文件变成一个更好用的文件选择输入控件,通过一个html的文件输入框,能兼容那些不支持jquery或js ...
- ceph集群安装
所有 Ceph 部署都始于 Ceph 存储集群.一个 Ceph 集群可以包含数千个存储节点,最简系统至少需要一个监视器和两个 OSD 才能做到数据复制.Ceph 文件系统. Ceph 对象存储.和 C ...
- cent os 直接访问谷歌的脚本实现
https://github.com/DingGuodong/GoogleHostsFileForLinux/blob/master/replaceLocalHostsFileAgainstGfw.s ...
- jmeter JDBC 连接数据库
1.添加JDBC Connection Configuration 2.添加JDBC Request 3.添加查看结果树 4. 设置下列参数:Database URL:jdbc:mysql://hos ...
- Spring+SpringMVC+MyBatis+easyUI整合优化篇(六)easyUI与富文本编辑器UEditor整合
日常啰嗦 本来这一篇和接下来的几篇是打算讲一下JDBC和数据库优化的,但是最近很多朋友加我好友也讨论了一些问题,我发现大家似乎都是拿这个项目作为练手项目,作为脚手架来用的,因此呢,改变了一下思路,JD ...
- javascript原型的意义
prototype属性: 这个属性包含一个对象(以下简称"prototype对象"),所有实例对象需要共享的属性和方法,都放在这个对象里面:那些不需要共享的属性和方法,就放在构造函 ...
- 核心J2EE模式 - 截取过滤器
核心J2EE模式 - 截取过滤器 背景 呈现层请求处理机制接收许多不同类型的请求,这些请求需要不同类型的处理.一些请求被简单转发到适当的处理程序组件,而其他请求必须在进一步处理之前进行修改,审核或未压 ...
- Web前端相关资源
Web前端相关 GRUNT: js task runner Sea.js: js模块化 knockout.js:MVVM开发前台,绑定技术 Angular.js: 使用超动感HTML & JS ...
- 【转载】 stm32之PWM
发现这位博主的博客被大量的转发,我也转载一篇,谁叫人家写的好呢. 原文地址:http://blog.sina.com.cn/s/blog_49cb42490100s6uh.html 脉冲宽度调制(PW ...
- 单片机下载芯片max232,ch340,pl2303,hl340与下载接线
开发板上的下载口位置一般都有很多 340,232等芯片,这些芯片都是干嘛用的呢? 普及:TTL电平 : 二进制电平,+5V等价于逻辑"1",0V等价于逻辑"0&qu ...