图像处理找图像对称

2017-12-03 17:28:28 arryCC 阅读数 3945

数字图像处理


一、学习内容总结

1. 第一章 绪论

本章主要有几个目的:

  1. 定义我们称之为数字图像处理领域的范围;
  2. 通过考察几个领域,给出图像处理技术状况的概念;
  3. 讨论图像处理用到的几种方法;
  4. 概述通用目的的典型图像处理系统的组成。

1.1 什么是数字图像处理

我们给出一些定义:

  • 强度灰度:一幅图像可以被定义为一个二维函数 f(x,y),其中 x,y 是空间(平面)坐标,而在任何一处的幅值 f 被称为在该点的灰度或强度。
  • 数字图像:当 x,y 或灰度值 f有限的离散数值时,称该图像为数字图像。也就是说数字图像是由有限数量的元素组成,每个元素都有特定的位置和幅值。这些元素被称为图画元素图像元素像素
  • 数字图像处理 : 指用特定的计算机来处理数字图像。

本书中将数字图像处理界定为其输入和输出都是图像的处理。

1.2 使用数字图像处理领域的实例

  • 伽马射线成像:医学和天文。
  • X射线成像:最早用于成像的电磁辐射源之一,医学诊断。
  • 紫外波段成像 :荧光显微镜。
  • 可见光及红外线成像 :可见显微镜技术,遥感,天气预测和预报,红外卫星图像,自动视觉检测,检测丢失的部件,指纹图像。
  • 微波波段成像 :雷达。
  • 无线电波段成像 :天文学和医学(核磁共振)。
  • 其他方式 :声波成像,电子显微镜方法,(由计算机产生的)合成图像。

1.3 数字图像处理的基本步骤

这里写图片描述

1.4 图像处理系统的组成

这里写图片描述

2. 第二章 数字图像处理基础

本章主要介绍数字图像处理一些基本概念

2.1 视觉感知要素

  • 人眼的结构

    重点介绍视网膜里的两类光感受器

    • 锥状体 :对颜色高度敏感,这种视觉称为白昼视觉或者亮视觉。高照明水平下执行。
    • 杆状体 :没有彩色感觉,对低照明度敏感,称为暗视觉或微光视觉。低照明水平下执行。
  • 亮度适应与辨别

    • 亮度适应现象 :视觉系统不能同时在一个范围内工作,它是通过改变其整个灵敏度来完成这一较大变动的。
    • 韦伯比 :较大:亮度辨别能力较差;反之,较好。
  • 感知亮度 不是简单的强度的函数

    • 视觉系统往往会在不同强度区域的边界处出现“下冲”或“上冲”现象。
    • 同时对比、错觉

2.2 光和电磁波谱

  • 电磁波是能量的一种,任何有能量的物体都会释放电磁波谱。它可以用 波长 (λ)、频率(v)或能量(E) 来描述,其中

λ=c/v

E=hv

  • 光是一种特殊的电磁辐射,可以被人眼感知。
    • 单色光 是没有颜色的光,也成为无色光。唯一属性就是它的强度或者大小,用 灰度级 来表示。单色图像常被称为 灰度图像
    • 彩色光源 的质量可以用发光强度、光通量和亮度 来表示。

2.3 图像感知和获取

  • 图像获取方式

    • 使用单个传感器来获取图像
    • 使用条带传感器获取图像
    • 使用传感器阵列获取图像
  • 简单的图像形成模型

    用形如 f(x,y) 的二维函数来表示图像,那么:

    0<f(x,y)<

    f(x,y) 可以用两个分量来表征:

    • 入射分量 入射到被观察场景的光源照射总量,用i(x,y) 表示;
    • 反射分量 场景中物体所反射的光照总量,用r(x,y) 表示。

    所以有:

    f(x,y)=i(x,y)r(x,y),0<i(x,y)<,0<r(x,y)<1

2.4 图像取样和量化

  • 取样和量化的基本概念

    • 取样 :对坐标值进行数字化
    • 量化 : 对幅值数字化

    数字图像的质量在很大程度上取决于取样和量化中所用的样本数灰度级

  • 数字图像表示

    用数列矩阵来表示一幅数字图像。在实数矩阵中,每个元素称为图像单元、图像元素或像素。

    对比度 一幅图像最高和最低灰度级间的灰度差为对比度。

    存储数字图像所用的比特数为:

    b=M×N×k,M=Nb=N2k

    灰度级数L=2k

  • 空间和灰度分辨率

    • 空间分辨率 :图像中可辨别的最小细节的度量。在数量上,表示每单位距离线对数和每单位距离点数是最通用的度量(必须针对空间单位来规定才有意义)。
    • 灰度分辨率 :指在灰度级中可分辨的最小变化。
  • 图像内插

    用已知数据来估计未知位置的数据处理。是基本的图像重取样方法。可以处理图像的放大和缩小。

2.5 像素间的基本关系

  • 相邻像素

    位于坐标 (x,y) 处的像素 p 有4个水平和垂直上的相邻像素,用 N4(p) 表示;有四个对角相邻像素,用 ND(p) 表示。如果 p 位于图像边界,则某些邻点可能 落在图像外边。

  • 邻接性、连通性、区域和边界

    • 4邻接、8邻接、混合邻接
  • 距离度量

    • 欧氏距离(圆)
    • D4 城市街区距离(菱形)
    • 棋盘距离(正方形)

2.6 常用数学工具介绍

  • 阵列和矩阵操作
  • 线性操作和非线性操作
  • 算术操作
  • 集合和逻辑操作
    • 基本集合操作
    • 逻辑操作
    • 模糊集合
  • 空间操作
    • 单像素操作
    • 邻域操作
    • 几何空间变换与图像配准
  • 向量和矩阵操作
  • 图像变换

3.第三章

3.1 背景知识

  • 空间域 就是简单的包含图像像素的平面。空间域处理可用以下方式表示:

g(x,y)=T[f(x,y)],T(x,y)

  • 灰度变换函数
    s=T(r),r,s

3.2 基本灰度变换函数

  • 图像反转

    得到灰度范围为 [0,L1] 的一幅图像的反转图像:(得到等效的照片底片)

    s=L1r

  • 对数变换

    对数变换的通用形式:

    s=clog(1+r)

    扩展图像中暗像素的值,同时压缩更高灰度级的值。反对数变换的作用与此相反。

这里写图片描述

  • 幂律变换(伽马)变换

    基本形式:

    s=crγ

    γ<1 变亮,大于1变暗,c=γ=1 恒等变换。

这里写图片描述
* 分段线性变换函数
* 对比度拉伸:扩展图像灰度级动态范围处理,因此它可以跨越记录介质和显示装置的全部灰度范围。

根据$r,s$ 的取值,变换可以为线性函数和阈值处理函数。
  • 灰度级分层:突出特定图像灰度范围的亮度。有两种方法:

    • 突出范围 [A,B] 内的灰度,并将所有其他灰度降低到一个更低的级别;
    • 突出范围[A,N] 内的灰度,并保持所有其他灰度级不变。
  • 比特平面分层:突出特定比特为整个图像外观作贡献。

    • 4个高阶比特平面,特别是最后两个比特平面,包含了在视觉上很重要的大多数数据。
    • 低阶比特平面在图像中贡献更精细的灰度细节。

    得出结论:储存四个高阶比特平面将允许我们以可接受的细节来重建原图像。这样可减少50%的存储量。

3.3 直方图的处理

  • 理论基础:若一幅图像的像素倾向于占据可能的灰度级并且分布均匀,则该图像会有高对比度的外观并展示灰色调的较大变化。

  • 直方图均衡:

    • 灰度范围为 [0,L1] 的数字图像的直方图是离散函数 h(rk)=nk,其中 rk 是第 k 级灰度值,nk 是图像中灰度为rk 的像素的个数。
    • 通过转换函数T(rk)变换,得到直方图均衡化。
    • 应用:自适应对比度增强。
  • 直方图匹配:用于处理后有特殊直方图的方法。

  • 局部直方图处理:以图像中每个像素邻域中的灰度分布为基础设计变换函数,来增强图像中小区域的细节。

  • 在图像增强中使用直方图统计:提供这样一种增强图像的方法:

    在仅处理均值和方差时,实际上直接从取样值来估计它们,不必计算直方图。这些估计被称为取样均值和取样方差。

3.4 空间滤波基础

  • 空间滤波机理

    • 空间滤波器的组成:
    • 一个邻域
    • 对该邻域包围的图像像素执行的预定义操作

    滤波产生的是一个新像素,新像素的坐标等于邻域中心的坐标,像素的值是滤波操作的结果。

  • 空间相关与卷积

    • 相关:滤波器模板移过图像并计算每个位置乘积之和的处理。一个大小为m×n 的滤波器与一幅图像 f(x,y) 做相关操作,可表示为w(x,y)f(x,y)
    • 卷积:与相关机理相似,但滤波器首先要旋转180o 一个大小为m×n 的滤波器与一幅图像 f(x,y) 做j卷积操作,可表示为w(x,y)f(x,y)

3.5 平滑空间滤波器

用于模糊处理和降低噪声。

  • 平滑线性滤波器(均值滤波器)

    它使用滤波器确定的邻域内像素的平均灰度值代替图像中每个像素的值。应用:

    • 降低噪声
    • 灰度级数量不足而引起的伪轮廓效应的平滑处理
    • 去除图像的不相关细节
  • 统计排序(非线性)滤波器

    最有代表性的是中值滤波器 ,特点:

    • 将像素邻域内灰度的中值(在中值计算中,包括原像素值)代替该像素的值;
    • 对处理脉冲噪声(椒盐噪声)非常有效。

3.6 锐化空间滤波器

  • 拉普拉斯算子:最简单的各向同性微分算子,是一个线性算子。因其为微分算子,因此强调的是图像中灰度的 突变而不是灰度级缓慢变换的区域。

  • 非锐化隐蔽和高提升滤波:从原图像中减去一部分非锐化的版本。步骤:

    • 模糊原图像
    • 从原图像减去模糊图像
    • 将模板加到原图像上
  • 梯度:图像处理中的一阶微分用梯度实现。对于函数f(x) ,在坐标(x,y) 处的梯度定义为二维列向量。它指出在位置f(x,y)f的最大变化率方向。

    应用:边缘增强。

4.第四章

本章主要为傅里叶变换的原理打一个基础,并介绍在基本的图像滤波中如何使用傅里叶变换。

4.1. 基本概念

  • 傅里叶概念:任何周期函数都可以表示为不同频率的正弦和或余弦和的形式,每个正弦项和或余弦项乘以不同的系数(傅里叶级数)。
  • 傅里叶变换:在非周期函数用正弦和或余弦和乘以加权函数的积分来表示的公式。
  • 介绍复数、傅里叶级数、冲击及其取样特征、连续函数的傅里叶变换以及之前提过的卷积。

4.2. 取样与取样函数中的傅里叶变换

  • 取样

    在连续函数f(x,y) 中模拟取样的一种方法是:用一个ΔT 单位间隔的冲击串作为取样函数去乘以f(t) .

  • 取样函数的傅里叶变换

    空间域来两个函数乘积的傅里叶变换是两个函数在频率域的卷积。

  • 取样定理

    如果以超过函数最高频率的两倍的取样来获取样本,连续的带限函数可以完全从它的样本集来恢复。

4.3. DFT小结

在课本上,作者给了我们详细的总结:

这里写图片描述
这里写图片描述
这里写图片描述

4.4. 频率域滤波

  • 步骤
    • 等到填充参数PQ
    • 形成大小为P×Q 的填充后的图像fp(x,y)
    • (1)x+y 乘以fp(x,y)移到其变换中心
    • 计算上一步骤的DTF,得到F(u,v)
    • 生成实的、对称的滤波函数H(u,v)
    • 得到处理后的图像gp(x,y)
    • gp(x,y) 的做上限提取M×N区域 ,得到最终的处理结果g(x,y)
  • 空间域与频率域间的纽带是卷积定理。

4.5. 使用频率域滤波器平滑图像

三种低通滤波器来平滑图像

  • 定义总结

这里写图片描述

  • 特性
    • 理想低通滤波器(ILFP)
    • 特性:模糊和振铃。
    • 布特沃斯低通滤波器(BLPF)
    • 特性:随着阶数增高,其振铃和负值变明显。(一阶时无)
    • 高斯低通滤波器(GLPF)
    • 特性:无振铃

4.6. 使用频率域滤波器锐化图像

  • 三种高通滤波器来锐化图像
    • 定义总结

这里写图片描述
* 特性

* 理想高通滤波器(IHPF)
  * 有振铃
* 布特沃斯高通滤波器(BHPF)
  * 比IHPF更平滑
* 高斯低通滤波器(GHPF)
  * 比前两个更平滑,即使微小物体和细线条得到的结果也比较其清晰
  • 其他方式

    • 拉普拉斯算子
    • 钝化模板、高提升滤波和高频强调滤波
    • 同态滤波

4.7.选择性滤波器

处理指定频段或者频率域的小区域

  • 带阻滤波器和带通滤波器

    • 带阻滤波器
      这里写图片描述

    • 带通滤波器

    • 通过1减去带阻得到。

  • 陷波滤波器:拒绝事先定义的关于频率矩形中心的一个邻域的频率。

    • 陷波带阻滤波器

    用中心已被平移到陷波滤波中心的高通滤波器的乘积来构造。

    • 陷波带通滤波器

    通过1减去带阻得到。

2017-04-15 19:34:01 m0_37264397 阅读数 61094

    傅立叶变换在图像处理中有非常重要的作用。因为不仅傅立叶分析涉及图像处理很多方面,傅立 叶改进算法,比如离散余弦变换,gabor与小波在图像处理中也有重要的分量。傅立叶变换在图像处理的重要作用:

   1.图像增强与图像去噪

      绝 大部分噪音都是图像的高频分量,通过低通滤波器来滤除高频——噪声; 边缘也是图像的高频分量,可以通过添加高频分量来增强原始图像的边缘;

  2.图像分割之边缘检测

     提 取图像高频分量

  3.图像特征提取:

     形状特征:傅里叶描述子

     纹 理特征:直接通过傅里叶系数来计算纹理特征

     其他特征:将提取的特征值进行傅里叶变 换来使特征具有平移、伸缩、旋转不变性

  4.图像压缩

     可以直接通过傅里叶系数来压缩数据;常用的离散余弦变换是傅立叶变换的实变换;傅立叶变换。

    傅里叶变换是将 时域信号分解为不同频率的正弦信号或余弦函数叠加之和。连续情况下要求原始信号在一个周期内满足绝对可积条件。离散情况下,傅里叶变换一定存在。冈萨雷斯 版<图像处理>里面的解释非常形象:一个恰当的比喻是将傅里叶变换比作一个玻璃棱镜。棱镜是可以将光分解为不同颜色的物理仪器,每个成分的颜 色由波长(或频率)来决定。傅里叶变换可以看作是数学上的棱镜,将函数基于频率分解为不同的成分。当我们考虑光时,讨论它的光谱或频率谱。同样,傅立叶变 换使我们能通过频率成分来分析一个函数。

    傅立叶变换有很多优良的性质。

    如线性, 对称性(可以用在计算信号的傅里叶变换里面);

    时移性:函数在时域中的时移,对 应于其在频率域中附加产生的相移,而幅度频谱则保持不变;

    频移性:函数在时域中乘 以e^jwt,可以使整个频谱搬移w。这个也叫调制定理,通讯里面信号的频分复用需要用到这个特性(将不同的信号调制到不同的频段上同时传输);

   卷积定理:时域卷积等于频域乘积;时域乘积等于频域卷积(附加一个系数)。(图像处理里面 这个是个重点)。

   信号在频率域的表现。

    在频域中,频率越大说明原始信号变化速度越快;频率越小说明原始信号越平缓。当频率为0时,表示直 流信号,没有变化。因此,频率的大小反应了信号的变化快慢。高频分量解释信号的突变部分,而低频分量决定信号的整体形象。

    在图像处理中,频域反应了图像在空域灰度变化剧烈程度,也就是图像灰度的变化速度,也就是图像的梯 度大小。对图像而言,图像的边缘部分是突变部分,变化较快,因此反应在频域上是高频分量;图像的噪声大部分情况下是高频部分;图像平缓变化部分则为低频分 量。也就是说,傅立叶变换提供另外一个角度来观察图像,可以将图像从灰度分布转化到频率分布上来观察图像的特征。书面一点说就是,傅里叶变换提供了一条从 空域到频率自由转换的途径。对图像处理而言,以下概念非常的重要:

    图像高频分量: 图像突变部分;在某些情况下指图像边缘信息,某些情况下指噪声,更多是两者的混合;

    低 频分量:图像变化平缓的部分,也就是图像轮廓信息

    高通滤波器:让图像使低频分量抑 制,高频分量通过

    低通滤波器:与高通相反,让图像使高频分量抑制,低频分量通过

    带通滤波器:使图像在某一部分的频率信息通过,其他过低或过高都抑制

    带阻滤波器,是带通的反。

模板运算与卷积定理

    在时域内做模板运算,实际上就是对图像进行卷积。 模板运算是图像处理一个很重要的处理过程,很多图像处理过程,比如增强/去噪(这两个分不清楚),边缘检测中普遍用到。根据卷积定理,时域卷积等价与频域 乘积。因此,在时域内对图像做模板运算就等效于在频域内对图像做滤波处理。

比如说 一个均值模板,其频域响应为一个低通滤波器;在时域内对图像作均值滤波就等效于在频域内对图像用均值模板的频域响应对图像的频域响应作一个低通滤波。

    图像去噪

    图像去噪 就是压制图像的噪音部分。因此,如果噪音是高频额,从频域的角度来看,就是需要用一个低通滤波器对图像进行处理。通过低通滤波器可以抑制图像的高频分量。 但是这种情况下常常会造成边缘信息的抑制。常见的去噪模板有均值模板,高斯模板等。这两种滤波器都是在局部区域抑制图像的高频分量,模糊图像边缘的同时也 抑制了噪声。还有一种非线性滤波-中值滤波器。中值滤波器对脉冲型噪声有很好的去掉。因为脉冲点都是突变的点,排序以后输出中值,那么那些最大点和最小点 就可以去掉了。中值滤波对高斯噪音效果较差。

    椒盐噪声:对于椒盐采用中值滤波可以 很好的去除。用均值也可以取得一定的效果,但是会引起边缘的模糊。

高斯白噪声:白 噪音在整个频域的都有分布,好像比较困难。

冈萨雷斯版图像处理P185:算术均值 滤波器和几何均值滤波器(尤其是后者)更适合于处理高斯或者均匀的随机噪声。谐波均值滤波器更适合于处理脉冲噪声。

    图像增强

有时候感觉图像增 强与图像去噪是一对矛盾的过程,图像增强经常是需要增强图像的边缘,以获得更好的显示效果,这就需要增加图像的高频分量。而图像去噪是为了消除图像的噪 音,也就是需要抑制高频分量。有时候这两个又是指类似的事情。比如说,消除噪音的同时图像的显示效果显著的提升了,那么,这时候就是同样的意思了。

    常见的图像增强方法有对比度拉伸,直方图均衡化,图像锐化等。前面两个是在空域进行基于像 素点的变换,后面一个是在频域处理。我理解的锐化就是直接在图像上加上图像高通滤波后的分量,也就是图像的边缘效果。对比度拉伸和直方图均衡化都是为了提 高图像的对比度,也就是使图像看起来差异更明显一些,我想,经过这样的处理以后,图像也应该增强了图像的高频分量,使得图像的细节上差异更大。同时也引入 了一些噪音。

    对图像二维傅立叶变换的意义

众所周至,傅立叶变换可以将连续或离散的函数序列从空域映射到频域上,因此,傅立叶变换是信息与信号学中不可获缺的强大工具。但是,由于傅立 叶变换在学习时是以一大堆公式的形式给出的,因此很多人(包括我在内)往往在做了一大堆习题掌握了变换的数学表示却对其变换后的物理意义一无所知,尤其是 自学的时候更是晕头转向。

     这里假设大家对傅立叶变换的数学表示已经很熟悉了,撇开傅立叶变换本身和其在其他领域的应用不谈,只谈图像傅立叶变换前后的对应关系。我们知道傅立叶变换 以前,图像(未压缩的位图)是由对在连续空间(现实空间)上的采样得到一系列点的集合,我们习惯用一个二维矩阵表示空间上各点,则图像可由 z=f(x,y)来表示。由于空间是三维的,图像是二维的,因此空间中物体在另一个维度上的关系就由梯度来表示,这样我们可以通过观察图像得知物体在三维 空间中的对应关系。为什么要提梯度?因为实际上对图像进行二维傅立叶变换得到频谱图,就是图像梯度的分布图,当然频谱图上的各点与图像上各点并不存在一一 对应的关系,即使在不移频的情况下也是没有。傅立叶频谱图上我们看到的明暗不一的亮点,实际上图像上某一点与邻域点差异的强弱,即梯度的大小,也即该点的 频率的大小(可以这么理解,图像中的低频部分指低梯度的点,高频部分相反)。一般来讲,梯度大则该点的亮度强,否则该点亮度弱。这样通过观察傅立叶变换后 的频谱图,也叫功率图(看看频谱图的各点的计算公式就知道为什么叫功率图了:)),我们首先就可以看出,图像的能量分布,如果频谱图中暗的点数更多,那么 实际图像是比较柔和的(因为各点与邻域差异都不大,梯度相对较小),反之,如果频谱图中亮的点数多,那么实际图像一定是尖锐的,边界分明且边界两边像素差 异较大的。对频谱移频到原点以后,可以看出图像的频率分布是以原点为圆心,对称分布的。将频谱移频到圆心除了可以清晰地看出图像频率分布以外,还有一个好 处,它可以分离出有周期性规律的干扰信号,比如正玄(sin的正玄,找不到这个字,郁闷)干扰,一副带有正玄干扰,移频到原点的频谱图上可以看出除了中心 以外还存在以某一点为中心,对称分布的亮点集合,这个集合就是干扰噪音产生的,这时可以很直观的通过在该位置放置带阻滤波器消除干扰。



数学公式:

1维的离散序列的DFT变换公式为:

 

2维的离散矩阵的DFT变换公式为:

1.使用模板处理图像相关概念:     

      模板:矩阵方块,其数学含义是一种卷积运算。
      卷积运算:可看作是加权求和的过程,使用到的图像区域中的每个像素分别于卷积核(权矩阵)的每个元素对应相
                乘,所有乘积之和作为区域中心像素的新值。
      卷积核:卷积时使用到的权用一个矩阵表示,该矩阵与使用的图像区域大小相同,其行、列都是奇数,
              是一个权矩阵。
      卷积示例:
              3 * 3 的像素区域R与卷积核G的卷积运算:
              R5(中心像素)=R1G1 + R2G2 + R3G3 + R4G4 + R5G5 + R6G6 + R7G7 + R8G8 + R9G9
            

2.使用模板处理图像的问题:
       边界问题:当处理图像边界像素时,卷积核与图像使用区域不能匹配,卷积核的中心与边界像素点对应,
                 卷积运算将出现问题。
       处理办法:
              A. 忽略边界像素,即处理后的图像将丢掉这些像素。
              B. 保留原边界像素,即copy边界像素到处理后的图像。

3.常用模板:



例子1.:

//【1】以灰度模式读取原始图像并显示
	Mat srcImage = imread("1.jpg", 0);
	if(!srcImage.data ) { printf("读取图片错误,请确定目录下是否有imread函数指定图片存在~! \n"); return false; } 
	imshow("原始图像" , srcImage);   

	//【2】将输入图像延扩到最佳的尺寸,边界用0补充
	int m = getOptimalDFTSize( srcImage.rows );
	int n = getOptimalDFTSize( srcImage.cols ); 
	//将添加的像素初始化为0.
	Mat padded;  
	copyMakeBorder(srcImage, padded, 0, m - srcImage.rows, 0, n - srcImage.cols, BORDER_CONSTANT, Scalar::all(0));

	//【3】为傅立叶变换的结果(实部和虚部)分配存储空间。
	//将planes数组组合合并成一个多通道的数组complexI
	Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)};
	Mat complexI;
	merge(planes, 2, complexI);         

	//【4】进行就地离散傅里叶变换
	dft(complexI, complexI);           

	//【5】将复数转换为幅值,即=> log(1 + sqrt(Re(DFT(I))^2 + Im(DFT(I))^2))
	split(complexI, planes); // 将多通道数组complexI分离成几个单通道数组,planes[0] = Re(DFT(I), planes[1] = Im(DFT(I))
	magnitude(planes[0], planes[1], planes[0]);// planes[0] = magnitude  
	Mat magnitudeImage = planes[0];

	//【6】进行对数尺度(logarithmic scale)缩放
	magnitudeImage += Scalar::all(1);
	log(magnitudeImage, magnitudeImage);//求自然对数

	//【7】剪切和重分布幅度图象限
	//若有奇数行或奇数列,进行频谱裁剪      
	magnitudeImage = magnitudeImage(Rect(0, 0, magnitudeImage.cols & -2, magnitudeImage.rows & -2));
	//重新排列傅立叶图像中的象限,使得原点位于图像中心  
	int cx = magnitudeImage.cols/2;
	int cy = magnitudeImage.rows/2;
	Mat q0(magnitudeImage, Rect(0, 0, cx, cy));   // ROI区域的左上
	Mat q1(magnitudeImage, Rect(cx, 0, cx, cy));  // ROI区域的右上
	Mat q2(magnitudeImage, Rect(0, cy, cx, cy));  // ROI区域的左下
	Mat q3(magnitudeImage, Rect(cx, cy, cx, cy)); // ROI区域的右下
	//交换象限(左上与右下进行交换)
	Mat tmp;                           
	q0.copyTo(tmp);
	q3.copyTo(q0);
	tmp.copyTo(q3);
	//交换象限(右上与左下进行交换)
	q1.copyTo(tmp);                 
	q2.copyTo(q1);
	tmp.copyTo(q2);

	//【8】归一化,用0到1之间的浮点值将矩阵变换为可视的图像格式
	//此句代码的OpenCV2版为:
	//normalize(magnitudeImage, magnitudeImage, 0, 1, CV_MINMAX); 
	//此句代码的OpenCV3版为:
	normalize(magnitudeImage, magnitudeImage, 0, 1, NORM_MINMAX); 

	//【9】显示效果图
	imshow("频谱幅值", magnitudeImage); 

函数解读:

C++: intgetOptimalDFTSize(int vecsize)

源码解读;

copyMakeBorder

C++: void copyMakeBorder(InputArraysrc, OutputArray dst, int top, int bottom,                                                        int left,int right, intborderType, const Scalar& value=Scalar())

src: 源图像

dst: 目标图像,和源图像有相同的类型,dst.cols=src.cols+left+right; dst.rows=src.rows+dst.top+dst.bottom

top:

bottom:

left:

right: 以上四个参数指定了在src图像周围附加的像素个数。

borderType: 边框类型

value: 当borderType==BORDER_CONSTANT时需要指定该值。


例子2.

  1. int cv::getOptimalDFTSizeint size0 )  
  2. {  
  3.    int a = 0, b = sizeof(optimalDFTSizeTab)/sizeof(optimalDFTSizeTab[0]) -1;  
  4.    if( (unsigned)size0 >= (unsigned)optimalDFTSizeTab[b] )  
  5.        return -1;  
  6.    
  7.    while( a < b )//二分查找合适的size  
  8.     {  
  9.        int c = (a + b) >> 1;  
  10.        if( size0 <= optimalDFTSizeTab[c] )  
  11.            b = c;  
  12.        else  
  13.            a = c+1;  
  14.     }  
  15.    
  16.     returnoptimalDFTSizeTab[b];  
  17. }</span>  

optimalDFTSizeTab定义在namespace cv中,里边的数值为2^x*3^y*5^z

static const int optimalDFTSizeTab[] = {1,2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16,…,                                                                                       2123366400, 2125764000};

 

 


示例代码:

  1. <span style="font-size:18px;">#include <opencv2/core/core.hpp>  
  2. #include<opencv2/highgui/highgui.hpp>  
  3. #include<opencv2/imgproc/imgproc.hpp>  
  4. #include <iostream>  
  5.    
  6. using namespace cv;  
  7. using namespace std;  
  8.    
  9. int main(){  
  10.        Matsrc = imread("fruits.jpg");  
  11.        if(src.empty())  
  12.        {  
  13.               return-1;  
  14.        }  
  15.    
  16.        Matsrc_gray;  
  17.        cvtColor(src,src_gray,CV_RGB2GRAY);//灰度图像做傅里叶变换  
  18.    
  19.        intm = getOptimalDFTSize(src_gray.rows);//2,3,5的倍数有更高效率的傅里叶转换  
  20.        intn = getOptimalDFTSize(src_gray.cols);  
  21.    
  22.        Matdst;  
  23.        ///把灰度图像放在左上角,在右边和下边扩展图像,扩展部分填充为0;  
  24.        copyMakeBorder(src_gray,dst,0,m-src_gray.rows,0,n-src_gray.cols,BORDER_CONSTANT,Scalar::all(0));  
  25.        cout<<dst.size()<<endl;  
  26.    
  27.        //新建一个两页的array,其中第一页用扩展后的图像初始化,第二页初始化为0  
  28.        Matplanes[] = {Mat_<float>(dst), Mat::zeros(dst.size(), CV_32F)};  
  29.        Mat  completeI;  
  30.        merge(planes,2,completeI);//把两页合成一个2通道的mat  
  31.    
  32.        //对上边合成的mat进行傅里叶变换,支持原地操作,傅里叶变换结果为复数。通道1存的是实部,通道2存的是虚部。  
  33.        dft(completeI,completeI);  
  34.    
  35.        split(completeI,planes);//把变换后的结果分割到各个数组的两页中,方便后续操作  
  36.        magnitude(planes[0],planes[1],planes[0]);//求傅里叶变换各频率的幅值,幅值放在第一页中。  
  37.    
  38.        MatmagI = planes[0];  
  39.        //傅立叶变换的幅度值范围大到不适合在屏幕上显示。高值在屏幕上显示为白点,  
  40.        //而低值为黑点,高低值的变化无法有效分辨。为了在屏幕上凸显出高低变化的连续性,我们可以用对数尺度来替换线性尺度:  
  41.        magI+= 1;  
  42.        log(magI,magI);//取对数  
  43.        magI= magI(Rect(0,0,src_gray.cols,src_gray.rows));//前边对原始图像进行了扩展,这里把对原始图像傅里叶变换取出,剔除扩展部分。  
  44.    
  45.    
  46.        //这一步的目的仍然是为了显示。 现在我们有了重分布后的幅度图,  
  47.        //但是幅度值仍然超过可显示范围[0,1] 。我们使用 normalize() 函数将幅度归一化到可显示范围。  
  48.        normalize(magI,magI,0,1,CV_MINMAX);//傅里叶图像进行归一化。  
  49.    
  50.    
  51.        //重新分配象限,使(0,0)移动到图像中心,  
  52.        //在《数字图像处理》中,傅里叶变换之前要对源图像乘以(-1)^(x+y)进行中心化。  
  53.        //这是是对傅里叶变换结果进行中心化  
  54.        intcx = magI.cols/2;  
  55.        intcy = magI.rows/2;  
  56.    
  57.        Mattmp;  
  58.        Matq0(magI,Rect(0,0,cx,cy));  
  59.        Matq1(magI,Rect(cx,0,cx,cy));  
  60.        Matq2(magI,Rect(0,cy,cx,cy));  
  61.        Matq3(magI,Rect(cx,cy,cx,cy));  
  62.    
  63.         
  64.        q0.copyTo(tmp);  
  65.        q3.copyTo(q0);  
  66.        tmp.copyTo(q3);  
  67.    
  68.        q1.copyTo(tmp);  
  69.        q2.copyTo(q1);  
  70.        tmp.copyTo(q2);  
  71.    
  72.         
  73.    
  74.        namedWindow("InputImage");  
  75.        imshow("InputImage",src);  
  76.    
  77.        namedWindow("SpectrumImage");  
  78.        imshow("SpectrumImage",magI);  
  79.    
  80.        waitKey();  
  81.        return0;  
  82. }</span>  


图像卷积原理:

图像处理-线性滤波-1 基础(相关算子、卷积算子、边缘效应)

这里讨论利用输入图像中像素的小邻域来产生输出图像的方法,在信号处理中这种方法称为滤波(filtering)。其中,最常用的是线性滤波:输出像素是输入邻域像素的加权和。

 

1.相关算子(Correlation Operator)

       定义:image image ,其中h称为相关核(Kernel).

        

  步骤:

        1)滑动核,使其中心位于输入图像g的(i,j)像素上

        2)利用上式求和,得到输出图像的(i,j)像素值

        3)充分上面操纵,直到求出输出图像的所有像素值

 

  例:

A = [17  24      15            h = [8     6
     23      14  16                 3     7
         13  20  22                 4     2]
     10  12  19  21             
     11  18  25     9]

计算输出图像的(2,4)元素=image

image

Matlab 函数:imfilter(A,h)

 

2.卷积算子(Convolution)

定义:image image ,其中

   步骤:

        1)将围绕中心旋转180度

        2)滑动核,使其中心位于输入图像g的(i,j)像素上

        3)利用上式求和,得到输出图像的(i,j)像素值

        4)充分上面操纵,直到求出输出图像的所有像素值

       例:计算输出图像的(2,4)元素=image

       image

Matlab 函数:Matlab 函数:imfilter(A,h,'conv')% imfilter默认是相关算子,因此当进行卷积计算时需要传入参数'conv'

3.边缘效应

当对图像边缘的进行滤波时,核的一部分会位于图像边缘外面。

image

常用的策略包括:

1)使用常数填充:imfilter默认用0填充,这会造成处理后的图像边缘是黑色的。

2)复制边缘像素:I3 = imfilter(I,h,'replicate');

image

   

4.常用滤波

fspecial函数可以生成几种定义好的滤波器的相关算子的核。

例:unsharp masking 滤波

1
2
3
4
5
I = imread('moon.tif');
h = fspecial('unsharp');
I2 = imfilter(I,h);
imshow(I), title('Original Image')
figure, imshow(I2), title('Filtered Image')
 
 

图像处理-线性滤波-2 图像微分(1、2阶导数和拉普拉斯算子)

更复杂些的滤波算子一般是先利用高斯滤波来平滑,然后计算其1阶和2阶微分。由于它们滤除高频和低频,因此称为带通滤波器(band-pass filters)。

在介绍具体的带通滤波器前,先介绍必备的图像微分知识。

1 一阶导数

连续函数,其微分可表达为image ,或image                         (1.1)

对于离散情况(图像),其导数必须用差分方差来近似,有

                                   image,前向差分 forward differencing                  (1.2)

                                   image ,中心差分 central differencing                     (1.3)

1)前向差分的Matlab实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
function dimg = mipforwarddiff(img,direction)
% MIPFORWARDDIFF     Finite difference calculations 
%
  DIMG = MIPFORWARDDIFF(IMG,DIRECTION)
%
 Calculates the forward-difference for a given direction
 IMG       : input image
 DIRECTION : 'dx' or 'dy'
 DIMG      : resultant image
%
  See also MIPCENTRALDIFF MIPBACKWARDDIFF MIPSECONDDERIV
  MIPSECONDPARTIALDERIV
  
  Omer Demirkaya, Musa Asyali, Prasana Shaoo, ... 9/1/06
  Medical Image Processing Toolbox
  
imgPad = padarray(img,[1 1],'symmetric','both');%将原图像的边界扩展
[row,col] = size(imgPad);
dimg = zeros(row,col);
switch (direction)   
case 'dx',
   dimg(:,1:col-1) = imgPad(:,2:col)-imgPad(:,1:col-1);%x方向差分计算,
case 'dy',
   dimg(1:row-1,:) = imgPad(2:row,:)-imgPad(1:row-1,:); 
otherwise, disp('Direction is unknown');
end;
dimg = dimg(2:end-1,2:end-1);

2)中心差分的Matlab实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
function dimg = mipcentraldiff(img,direction)
% MIPCENTRALDIFF     Finite difference calculations 
%
  DIMG = MIPCENTRALDIFF(IMG,DIRECTION)
%
 Calculates the central-difference for a given direction
 IMG       : input image
 DIRECTION : 'dx' or 'dy'
 DIMG      : resultant image
%
  See also MIPFORWARDDIFF MIPBACKWARDDIFF MIPSECONDDERIV
  MIPSECONDPARTIALDERIV
  
  Omer Demirkaya, Musa Asyali, Prasana Shaoo, ... 9/1/06
  Medical Image Processing Toolbox
  
img = padarray(img,[1 1],'symmetric','both');
[row,col] = size(img);
dimg = zeros(row,col);
switch (direction)
    case 'dx',
        dimg(:,2:col-1) = (img(:,3:col)-img(:,1:col-2))/2;
    case 'dy',
        dimg(2:row-1,:) = (img(3:row,:)-img(1:row-2,:))/2;
    otherwise,
        disp('Direction is unknown');
end
dimg = dimg(2:end-1,2:end-1);
1   

实例:技术图像x方向导数

1
2
I = imread('coins.png'); figure; imshow(I);
Id = mipforwarddiff(I,'dx'); figure, imshow(Id);

      image image

    原图像                           x方向1阶导数

 

2 图像梯度(Image Gradient)

图像I的梯度定义为image  ,其幅值为image 。出于计算性能考虑,幅值也可用image 来近似。

Matlab函数

1)gradient:梯度计算

2)quiver:以箭头形状绘制梯度。注意放大下面最右侧图可看到箭头,由于这里计算横竖两个方向的梯度,因此箭头方向都是水平或垂直的。

实例:仍采用上面的原始图像

1
2
3
4
5
I = double(imread('coins.png'));
[dx,dy]=gradient(I);
magnitudeI=sqrt(dx.^2+dy.^2);
figure;imagesc(magnitudeI);colormap(gray);%梯度幅值
hold on;quiver(dx,dy);%叠加梯度方向

        image image

                         梯度幅值          梯度幅值+梯度方向

 

3 二阶导数

对于一维函数,其二阶导数image ,即image 。它的差分函数为

                                 image                  (3.1)

 

3.1 普拉斯算子(laplacian operator)

3.1.2 概念

拉普拉斯算子是n维欧式空间的一个二阶微分算子。它定义为两个梯度向量算子的内积

                          image       (3.2)

其在二维空间上的公式为:    image                (3.3)

 

对于1维离散情况,其二阶导数变为二阶差分

1)首先,其一阶差分为image

2)因此,二阶差分为

          image

3)因此,1维拉普拉斯运算可以通过1维卷积核image 实现

 

对于2维离散情况(图像),拉普拉斯算子是2个维上二阶差分的和(见式3.3),其公式为:

image   (3.4)

上式对应的卷积核为

                       image

常用的拉普拉斯核有:

                      image

3.1.2 应用

拉普拉斯算子会突出像素值快速变化的区域,因此常用于边缘检测。

 

 

Matlab里有两个函数

1)del2

计算公式:image image  

2)fspecial:图像处理中一般利用Matlab函数fspecial

h = fspecial('laplacian', alpha) returns a 3-by-3 filter approximating the shape of the two-dimensional Laplacian operator.
The parameter alpha controls the shape of the Laplacian and must be in the range 0.0 to 1.0. The default value for alpha is 0.2.

 

3.1.3 资源

http://fourier.eng.hmc.edu/e161/lectures/gradient/node8.html (非常清晰的Laplacian Operator介绍,本文的主要参考)

http://homepages.inf.ed.ac.uk/rbf/HIPR2/log.htm

 

 
 
 
 

sift算法

 

尺度不变特征转换(Scale-invariant feature transform 或 SIFT)是一种电脑视觉的算法用来侦测与描述影像中的局部性特征,它在空间尺度中寻找极值点,并提取出其位置、尺度、旋转不变量,此算法由 David Lowe 在1999年所发表,2004年完善总结。

Sift算法就是用不同尺度(标准差)的高斯函数对图像进行平滑,然后比较平滑后图像的差别,
差别大的像素就是特征明显的点。

sift可以同时处理亮度,平移,旋转,尺度的变化,利用特征点来提取特征描述符,最后在特征描述符之间寻找匹配


五个步骤

1构建尺度空间,检测极值点,获得尺度不变性

2特征点过滤并进行经确定位,剔除不稳定的特征点

3 在特征点处提取特征描述符,为特征点分配方向直

4声称特征描述子,利用特征描述符寻找匹配点

5计算变换参数

当2幅图像的sift特征向量生成以后,下一步就可以采用关键点特征向量的欧式距离来作为2幅图像中关键点的相似性判定量度


尺度空间:

尺度就是受delta这个参数控制的表示

而不同的L(x,y,delta)就构成了尺度空间,实际上具体计算的时候即使连续的高斯函数,都要被离散为矩阵来和数字图像进行卷积操作

L(x,y,delta)=G(x,y,e)*i(x,y)

尺度空间=原始图像(卷积)一个可变尺度的2维高斯函数G(x,y,e)


G(x,y,e) = [1/2*pi*e^2] * exp[ -(x^2 + y^2)/2e^2] 


为了更有效的在尺度空间检测到稳定的关键点,提出了高斯差分尺度空间,利用不同尺度的高斯差分核与原始图像i(x,y)卷积生成

D(x,y,e)=(G(x,y,ke)-G(x,y,e))*i(x,y)

=L(x,y,ke)-L(x,y,e)

(为避免遍历每个像素点)


高斯卷积:

在组建一组尺度空间后,再组建下一组尺度空间,对上一组尺度空间的最后一幅图像进行二分之一采样,得到下一组尺度空间的第一幅图像,然后进行像建立第一组尺度空间那样的操作,得到第二组尺度空间,公式定义为
         L(x,y,e) = G(x,y,e)*I(x,y)

    图像金字塔的构建:图像金字塔共O组,每组有S层,下一组的图像由上一组图像降采样得到、

高斯差分

    在尺度空间建立完毕后,为了能够找到稳定的关键点,采用高斯差分的方法来检测那些在局部位置的极值点,即采用俩个相邻的尺度中的图像相减,即公式定义为:
        D(x,y,e) = ((G(x,y,ke) - G(x,y,e)) * I(x,y) 
                 = L(x,y,ke) - L(x,y,e)
 咱们再来具体阐述下构造D(x,y,e)的详细步骤:
    1、首先采用不同尺度因子的高斯核对图像进行卷积以得到图像的不同尺度空间,将这一组图像作为金子塔图像的第一层。
    2、接着对第一层图像中的2倍尺度图像(相对于该层第一幅图像的2倍尺度)以2倍像素距离进行下采样来得到金子塔图像的第二层中的第一幅图像,对该图像采用不同尺度因子的高斯核进行卷积,以获得金字塔图像中第二层的一组图像。
    3、再以金字塔图像中第二层中的2倍尺度图像(相对于该层第一幅图像的2倍尺度)以2倍像素距离进行下采样来得到金字塔图像的第三层中的第一幅图像,对该图像采用不同尺度因子的高斯核进行卷积,以获得金字塔图像中第三层的一组图像。这样依次类推,从而获得了金字塔图像的每一层中的一组图像,
 4、对上图得到的每一层相邻的高斯图像相减,就得到了高斯差分图像,如下述第一幅图所示。下述第二幅图中的右列显示了将每组中相邻图像相减所生成的高斯差分图像的结果,限于篇幅,图中只给出了第一层和第二层高斯差分图像的计算
sift算法
 

 

图像处理之卷积概念

 

我们来看一下一维卷积的概念.
连续空间的卷积定义是 f(x)与g(x)的卷积是 f(t-x)g(x) 在t从负无穷到正无穷的积分值.t-x要在f(x)定义域内,所以看上去很大的积分实际上还是在一定范围的.
实际的过程就是f(x) 先做一个Y轴的反转,然后再沿X轴平移t就是f(t-x),然后再把g(x)拿来,两者乘积的值再积分.想象一下如果g(x)或者f(x)是个单位的阶越函数. 那么就是f(t-x)与g(x)相交部分的面积.这就是卷积了.
把积分符号换成求和就是离散空间的卷积定义了.

 

么在图像中卷积卷积地是什么意思呢,就是图像f(x),模板g(x),然后将模版g(x)在模版中移动,每到一个位置,就把f(x)与g(x)的定义域相交的元素进行乘积并且求和,得出新的图像一点,就是被卷积后的图像. 模版又称为卷积核.卷积核做一个矩阵的形状.


卷积定义上是线性系统分析经常用到的.线性系统就是一个系统的输入和输出的关系是线性关系.就是说整个系统可以分解成N多的无关独立变化,整个系统就是这些变化的累加.
如 x1->y1, x2->y2; 那么A*x1 + B*x2 -> A*y1 + B*y2 这就是线性系统. 表示一个线性系统可以用积分的形式 如 Y = Sf(t,x)g(x)dt S表示积分符号,就是f(t,x)表示的是A B之类的线性系数.
看上去很像卷积呀,,对如果f(t,x) = F(t-x) 不就是了吗.从f(t,x)变成F(t-x)实际上是说明f(t,x)是个线性移不变,就是说 变量的差不变化的时候,那么函数的值不变化. 实际上说明一个事情就是说线性移不变系统的输出可以通过输入和表示系统线性特征的函数卷积得到.


http://dept.wyu.edu.cn/dip/DIPPPT2005/����������ϵͳ.ppt


谈起卷积分当然要先说说冲击函数—-这个倒立的小蝌蚪,卷积其实就是为它诞生的。”冲击函数”是狄拉克为了解决一些瞬间作用的物理现象而提出的符号。
古人曰:”说一堆大道理不如举一个好例子”,冲量这一物理现象很能说明”冲击函数”。在t时间内对一物体作用F的力,我们可以让作用时间t很小,作用力F很大,但让Ft的乘积不变,即冲量不变。于是在用t做横坐标、F做纵坐标的坐标系中,就如同一个面积不变的长方形,底边被挤的窄窄的,高度被挤的高高的,在数学中它可以被挤到无限高,但即使它无限瘦、无限高、但它仍然保持面积不变(它没有被挤没!),为了证实它的存在,可以对它进行积分,积分就是求面积嘛!于是”卷积” 这个数学怪物就这样诞生了。说它是数学怪物是因为追求完美的数学家始终在头脑中转不过来弯,一个能瘦到无限小的家伙,竟能在积分中占有一席之地,必须将这个细高挑清除数学界。但物理学家、工程师们确非常喜欢它,因为它解决了很多当时数学家解决不了的实际问题。最终追求完美的数学家终于想通了,数学是来源于实际的,并最终服务于实际才是真。于是,他们为它量身定做了一套运作规律。于是,妈呀!你我都感觉眩晕的卷积分产生了。
例子:
有一个七品县令,喜欢用打板子来惩戒那些市井无赖,而且有个惯例:如果没犯大罪,只打一板,释放回家,以示爱民如子。
有一个无赖,想出人头地却没啥指望,心想:既然扬不了善名,出恶名也成啊。怎么出恶名?炒作呗!怎么炒作?找名人呀!他自然想到了他的行政长官——县令。
无赖于是光天化日之下,站在县衙门前撒了一泡尿,后果是可想而知地,自然被请进大堂挨了一板子,然后昂首挺胸回家,躺了一天,嘿!身上啥事也没有!第二天如法炮制,全然不顾行政长管的仁慈和衙门的体面,第三天、第四天……每天去县衙门领一个板子回来,还喜气洋洋地,坚持一个月之久!这无赖的名气已经和衙门口的臭气一样,传遍八方了!
县令大人噤着鼻子,呆呆地盯着案子上的惊堂木,拧着眉头思考一个问题:这三十个大板子怎么不好使捏?……想当初,本老爷金榜题名时,数学可是得了满分,今天好歹要解决这个问题:
——人(系统!)挨板子(脉冲!)以后,会有什么表现(输出!)?
——费话,疼呗!
——我问的是:会有什么表现?
——看疼到啥程度。像这无赖的体格,每天挨一个板子啥事都不会有,连哼一下都不可能,你也看到他那得意洋洋的嘴脸了(输出0);如果一次连揍他十个板子,他可能会皱皱眉头,咬咬牙,硬挺着不哼
(输出1);揍到二十个板子,他会疼得脸部扭曲,象猪似地哼哼(输出3);揍到三十个板子,他可能会象驴似地嚎叫,一把鼻涕一把泪地求你饶他一命(输出5);揍到四十个板子,他会大小便失禁,勉
强哼出声来(输出1);揍到五十个板子,他连哼一下都不可能(输出0)——死啦!
县令铺开坐标纸,以打板子的个数作为X轴,以哼哼的程度(输出)为Y轴,绘制了一条曲线:
——呜呼呀!这曲线象一座高山,弄不懂弄不懂。为啥那个无赖连挨了三十天大板却不喊绕命呀?
—— 呵呵,你打一次的时间间隔(Δτ=24小时)太长了,所以那个无赖承受的痛苦程度一天一利索,没有叠加,始终是一个常数;如果缩短打板子的时间间隔(建议 Δτ=0.5秒),那他的痛苦程度可就迅速叠加了;等到这无赖挨三十个大板(t=30)时,痛苦程度达到了他能喊叫的极限,会收到最好的惩戒效果,再多打就显示不出您的仁慈了。
——还是不太明白,时间间隔小,为什么痛苦程度会叠加呢?
——这与人(线性时不变系统)对板子(脉冲、输入、激励)的响应有关。什么是响应?人挨一个板子后,疼痛的感觉会在一天(假设的,因人而异)内慢慢消失(衰减),而不可能突然消失。这样一来,只要打板子的时间间隔很小,每一个板子引起的疼痛都来不及完全衰减,都会对最终的痛苦程度有不同的贡献:
t个大板子造成的痛苦程度=Σ(第τ个大板子引起的痛苦*衰减系数)
[衰减系数是(t-τ)的函数,仔细品味]
数学表达为:y(t)=∫T(τ)H(t-τ)
——拿人的痛苦来说卷积的事,太残忍了。除了人以外,其他事物也符合这条规律吗?
——呵呵,县令大人毕竟仁慈。其实除人之外,很多事情也遵循此道。好好想一想,铁丝为什么弯曲一次不折,快速弯曲多次却会轻易折掉呢?
——恩,一时还弄不清,容本官慢慢想来——但有一点是明确地——来人啊,将撒尿的那个无赖抓来,狠打40大板!
卷积及拉普拉斯变换的通俗解释–对于我这类没学过信号系统的人来说太需要了
卷积(convolution, 另一个通用名称是德文的Faltung)的名称由来,是在于当初定义它时,定义成 integ(f1(v)*f2(t-v))dv,积分区间在0到t之间。举个简单的例子,大家可以看到,为什么叫”卷积”了。比方说在(0,100)间积分,用简单的辛普生积分公式,积分区间分成100等分,那么看到的是f1(0)和f2(100)相乘,f1(1)和f2(99)相乘,f1(2)和f2 (98)相乘,……… 等等等等,就象是在坐标轴上回卷一样。所以人们就叫它”回卷积分”,或者”卷积”了。
为了理解”卷积”的物理意义,不妨将那个问题”相当于它的时域的信号与系统的单位脉冲响应的卷积”略作变化。这个变化纯粹是为了方便表达和理解,不影响任何其它方面。将这个问题表述成这样一个问题:一个信号通过一个系统,系统的响应是频率响应或波谱响应,且看如何理解卷积的物理意义。
假设信号函数为f, 响应函数为g。f不仅是时间的函数(信号时有时无),还是频率的函数(就算在某一固定时刻,还有的地方大有的地方小);g也是时间的函数(有时候有反应,有时候没反应),同时也是频率的函数(不同的波长其响应程度不一样)。那我们要看某一时刻 t 的响应信号,该怎么办呢?
这就需要卷积了。
要看某一时刻 t 的响应信号,自然是看下面两点:
1。你信号来的时候正赶上人家”系统”的响应时间段吗?
2。就算赶上系统响应时间段,响应有多少?
响 应不响应主要是看 f 和 g 两个函数有没有交叠;响应强度的大小不仅取决于所给的信号的强弱,还取决于在某频率处对单位强度响应率。响应强度是信号强弱和对单位强度信号响应率的乘积。”交叠”体现在f(t1)和g(t-t1)上,g之所以是”(t-t1)”就是看两个函数错开多少。
由于 f 和 g 两个函数都有一定的带宽分布(假若不用开头提到的”表述变化”就是都有一定的时间带宽分布),这个信号响应是在一定”范围”内广泛响应的。算总的响应信号,当然要把所有可能的响应加起来,实际上就是对所有可能t1积分了。积分范围虽然一般在负无穷到正无穷之间;但在没有信号或者没有响应的地方,积也是白积,结果是0,所以往往积分范围可以缩减。
这就是卷积及其物理意义啊。并成一句话来说,就是看一个时有时无(当然作为特例也可以永恒存在)的信号,跟一个响应函数在某一时刻有多大交叠。
*********拉普拉斯*********
拉普拉斯(1729-1827) 是法国数学家,天文学家,物理学家。他提出拉普拉斯变换(Laplace Transform) 的目的是想要解决他当时研究的牛顿引力场和太阳系的问题中涉及的积分微分方程。
拉普拉斯变换其实是一个数学上的简便算法;想要了解其”物理”意义 — 如果有的话 — 请看我举这样一个例子:
问题:请计算十万乘以一千万。
对于没学过指数的人,就只会直接相乘;对于学过指数的人,知道不过是把乘数和被乘数表达成指数形式后,两个指数相加就行了;如果要问究竟是多少,把指数转回来就是。
“拉 普拉斯变换” 就相当于上述例子中把数转换成”指数” 的过程;进行了拉普拉斯变换之后,复杂的微分方程(对应于上例中”复杂”的乘法) 就变成了简单的代数方程,就象上例中”复杂”的乘法变成了简单的加减法。再把简单的代数方程的解反变换回去(就象把指数重新转换会一般的数一样),就解决了原来那个复杂的微分方程。
所以要说拉普拉斯变换真有” 物理意义”的话,其物理意义就相当于人们把一般的有理数用指数形式表达一样。
另外说两句题外话:
1 。拉普拉斯变换之所以现在在电路中广泛应有,根本原因是电路中也广泛涉及了微分方程。
2。拉普拉斯变换与Z变换当然有紧密联系;其本质区别在于拉氏变换处理的是时间上连续的问题,Z变换处理的是时间上分立的问题。
Signals, Linear Systems, and Convolution
Download from here
 
我们都知道卷积公式,但是它有什么物理意义呢?平时我们用卷积做过很多事情,信号处理时,输出函数是输入函数和系统函数的卷积;在图像处理时,两组幅分辨率不同的图卷积之后得到的互相平滑的图像可以方便处理。卷积甚至可以用在考试作弊中,为了让照片同时像两个人,只要把两人的图像卷积处理即可,这就是一种平滑的过程,可是我们怎么才能真正把公式和实际建立起一种联系呢?生活中就有实例:
     比如说你的老板命令你干活,你却到楼下打台球去了,后来被老板发现,他非常气愤,扇了你一巴掌(注意,这就是输入信号,脉冲),于是你的脸上会渐渐地(贱贱地)鼓起来一个包,你的脸就是一个系统,而鼓起来的包就是你的脸对巴掌的响应。
      好,这样就和信号系统建立起来意义对应的联系。下面还需要一些假设来保证论证的严谨:假定你的脸是线性时不变系统,也就是说,无论什么时候老板打你一巴掌,打在你脸的同一位置(这似乎要求你的脸足够光滑,如果你说你长了很多青春痘,甚至整个脸皮处处连续处处不可导,那难度太大了,我就无话可说了),你的脸上总是会在相同的时间间隔内鼓起来一个相同高度的包来,并且假定以鼓起来的包的大小作为系统输出。好了,那么,下面可以进入核心内容——卷积了!
      如果你每天都到楼下去打台球,那么老板每天都要扇你一巴掌,不过当老板打你一巴掌后,你5分钟就消肿了,所以时间长了,你甚至就适应这种生活了……如果有一天,老板忍无可忍,以0.5秒的间隔开始不间断的扇你的过程,这样问题就来了:第一次扇你鼓起来的包还没消肿,第二个巴掌就来了,你脸上的包就可能鼓起来两倍高,老板不断扇你,脉冲不断作用在你脸上,效果不断叠加了,这样这些效果就可以求和了,结果就是你脸上的包的高度岁时间变化的一个函数了(注意理解)!
      如果老板再狠一点,频率越来越高,以至于你都辨别不清时间间隔了,那么,求和就变成积分了。可以这样理解,在这个过程中的某一固定的时刻,你的脸上的包的鼓起程度和什么有关呢?和之前每次打你都有关!但是各次的贡献是不一样的,越早打的巴掌,贡献越小,这就是说,某一时刻的输出是之前很多次输入乘以各自的衰减系数之后的叠加而形成某一点的输出,然后再把不同时刻的输出点放在一起,形成一个函数,这就是卷积。卷积之后的函数就是你脸上的包的大小随时间变化的函数。本来你的包几分钟就可以消肿,可是如果连续打,几个小时也消不了肿了,这难道不是一种平滑过程么?反映到公式上,f(a)就是第a个巴掌,g(x-a)就是第a个巴掌在x时刻的作用程度,乘起来再叠加就ok了,这就是卷积!
     最后提醒各位,请勿亲身尝试……

卷积的物理意义?
在信号与系统中,两个函数所要表达的物理含义是什么?例如,一个系统,其单位冲激响应为h(t),当输入信号为f(t)时,该系统的输出为y(t)。为什么y(t)是f(t)和h(t)的卷积?(从数学推导我明白,但其物理意义不明白。)y(t)是f(t)和h(t)的卷积表达了一个什么意思?

卷积(convolution, 另一个通用名称是德文的Faltung)的名称由来,是在于当初定义它时,定义成 integ(f1(v)*f2(t-v))dv,积分区间在0到t之间。举个简单的例子,大家可以看到,为什么叫“卷积”了。比方说在(0,100)间积分,用简单的辛普生积分公式,积分区间分成100等分,那么看到的是f1(0)和f2(100)相乘,f1(1)和f2(99)相乘,f1(2)和f2(98)相乘,......... 等等等等,就象是在坐标轴上回卷一样。所以人们就叫它“回卷积分”,或者“卷积”了。
为了理解“卷积”的物理意义,不妨将那个问题“相当于它的时域的信号与系统的单位脉冲响应的卷积”略作变化。这个变化纯粹是为了方便表达和理解,不影响任何其它方面。将这个问题表述成这样一个问题:一个信号通过一个系统,系统的响应是频率响应或波谱响应,且看如何理解卷积的物理意义。
假设信号函数为f, 响应函数为g。f不仅是时间的函数(信号时有时无),还是频率的函数(就算在某一固定时刻,还有的地方大有的地方小);g也是时间的函数(有时候有反应,有时候没反应),同时也是频率的函数(不同的波长其响应程度不一样)。那我们要看某一时刻 t 的响应信号,该怎么办呢?
这就需要卷积了。
其实卷积积分应用广泛用在信号里面,一个是频域一个是时域
 

卷积是个啥?我忽然很想从本质上理解它。于是我从抽屉里翻出自己珍藏了许多年,每每下决心阅读却永远都读不完的《应用傅立叶变换》。
 
3.1 一维卷积的定义
 
函数f(x)与函数h(x)的卷积,由函参量的无穷积分

  定义。这里参量x和积分变量α皆为实数;函数f和h可实可复。
 
定义虽然找到了,但我还是一头雾水。卷积是个无穷积分吗?那它是干啥用的?再往后翻:几何说明、运算举例、基本性质,一堆的公式,就是没有说它是干啥用的。我于是坐在那呆想,忽然第二个困扰我的问题冒了出来:傅立叶变换是个啥?接着就是第三个、第四个、……、第N个问题。
 
傅立叶变换是个啥?听说能将时域上的东东变到频域上分析?哎?是变到频域上还是空间域上来着?到底啥是时域,频域,空间域?
 
上网查傅立叶变换的物理意义,没发现明确答案,倒发现了许多和我一样晕着问问题的人。结果又多出了许多名词,能量?功率谱?图像灰度域?……没办法又去翻那本教材。
 
1.1 一维傅立叶变换的定义与傅立叶积分定理
 
设f(x)是实变量x的函数,该函数可实可复,称积分

为函数f(x)的傅立叶变换。
 
吐血,啥是无穷积分来着?积分是啥来着?还能记起三角函数和差化积、积化和差公式吗?我忽然有种想把高中课本寻来重温的冲动。
 
卷积主要是为了将信号运算从时域转换为频域。
信号的时域的卷积等于频域的乘积。
利用这个性质以及特殊的δ函数可以通过抽样构造简单的调制电路
 
 
我比较赞同卷积的相关性的作用  在通信系统中的接收机部分MF匹配滤波器等就是本质上的相关
匹配滤波器最简单的形式就是原信号反转移位相乘积分得到的近似=相关
相关性越好得到的信号越强   这个我们有一次大作业做的  做地做到呕吐  呵呵
还有解调中一些东西本质就是相关
 

卷积公式  解释  卷积公式是用来求随机变量和的密度函数(pdf)的计算公式。  定义式:  z(t)=x(t)*y(t)= ∫x(m)y(t-m)dm.   已知x,y的pdf,x(t),y(t).现在要求z=x+y的pdf. 我们作变量替显,令  z=x+y,m=x. 雅可比行列式=1.那么,z,m联合密度就是f(z,m)=x(m)y(z-m)*1. 这样,就可以很容易求Z的在(z,m)中边缘分布  即fZ(z)=∫x(m)y(z-m)dm..... 由于这个公式和x(t),y(t)存在一一对应的关系。为了方便,所以记 ∫x(m)y(z-m)dm=x(t)*y(t)   长度为m的向量序列u和长度为n的向量序列v,卷积w的向量序列长度为(m+n-1),   u(n)与v(n)的卷积w(n)定义为: w(n)=u(n)@v(n)=sum(v(m)*u(n-m)),m from 负无穷到正无穷;   当m=n时w(1) = u(1)*v(1)   w(2) = u(1)*v(2)+u(2)*v(1)   w(3) = u(1)*v(3)+u(2)*v(2)+u(3)*v(1)   …   w(n) = u(1)*v(n)+u(2)*v(n-1)+ … +u(n)*v(1)   …   w(2*n-1) = u(n)*v(n)   当m≠n时,应以0补齐阶次低的向量的高位后进行计算  这是数学中常用的一个公式,在概率论中,是个重点也是一个难点。

  卷积公式是用来求随机变量和的密度函数(pdf)的计算公式。
  定义式:
  z(t)=x(t)*y(t)= ∫x(m)y(t-m)dm.
  已知x,y的pdf,x(t),y(t).现在要求z=x+y的pdf. 我们作变量替显,令
  z=x+y,m=x. 雅可比行列式=1.那么,t,m联合密度就是f(z,m)=x(m)y(z-m)*1. 这样,就可以很容易求Z的在(z,m)中边缘分布
  即fZ(z)=∫x(m)y(z-m)dm..... 由于这个公式和x(t),y(t)存在一一对应的关系。为了方便,所以记 ∫x(m)y(z-m)dm=x(t)*y(t)
 
卷积是一种线性运算,图像处理中常见的mask运算都是卷积,广泛应用于图像滤波。castlman的书对卷积讲得很详细。
高斯变换就是用高斯函数对图像进行卷积。高斯算子可以直接从离散高斯函数得到:
for(i=0; i<N; i++)
{
for(j=0; j<N; j++)
{
g[i*N+j]=exp(-((i-(N-1)/2)^2+(j-(N-1)/2)^2))/(2*delta^2));
sum += g[i*N+j];
}
}
再除以 sum 得到归一化算子
N是滤波器的大小,delta自选
首先,再提到卷积之前,必须提到卷积出现的背景。卷积是在信号与线性系统的基础上或背景中出现的,脱离这个背景单独谈卷积是没有任何意义的,除了那个所谓褶反公式上的数学意义和积分(或求和,离散情况下)。
信号与线性系统,讨论的就是信号经过一个线性系统以后发生的变化(就是输入输出和所经过的所谓系统,这三者之间的数学关系)。所谓线性系统的含义,就是,这个所谓的系统,带来的输出信号与输入信号的数学关系式之间是线性的运算关系。
因此,实际上,都是要根据我们需要待处理的信号形式,来设计所谓的系统传递函数,那么这个系统的传递函数和输入信号,在数学上的形式就是所谓的卷积关系。
卷积关系最重要的一种情况,就是在信号与线性系统或数字信号处理中的卷积定理。利用该定理,可以将时间域或空间域中的卷积运算等价为频率域的相乘运算,从而利用FFT等快速算法,实现有效的计算,节省运算代价。

参考:

http://www.cnblogs.com/a-toad/archive/2008/10/24/1318921.html

http://blog.sina.com.cn/s/blog_6d0e97bb01013op2.html

2019-04-23 16:24:29 Eastmount 阅读数 19610

该系列文章是讲解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图像处理] 四.图像平滑之均值滤波、方框滤波、高斯滤波及中值滤波
[Python图像处理] 五.图像融合、加法运算及图像类型转换
[Python图像处理] 六.图像缩放、图像旋转、图像翻转与图像平移
[Python图像处理] 七.图像阈值化处理及算法对比
[Python图像处理] 八.图像腐蚀与图像膨胀
[Python图像处理] 九.形态学之图像开运算、闭运算、梯度运算
[Python图像处理] 十.形态学之图像顶帽运算和黑帽运算
[Python图像处理] 十一.灰度直方图概念及OpenCV绘制直方图
[Python图像处理] 十二.图像几何变换之图像仿射变换、图像透视变换和图像校正
[Python图像处理] 十三.基于灰度三维图的图像顶帽运算和黑帽运算
[Python图像处理] 十四.基于OpenCV和像素处理的图像灰度化处理
[Python图像处理] 十五.图像的灰度线性变换
[Python图像处理] 十六.图像的灰度非线性变换之对数变换、伽马变换
[Python图像处理] 十七.图像锐化与边缘检测之Roberts算子、Prewitt算子、Sobel算子和Laplacian算子
[Python图像处理] 十八.图像锐化与边缘检测之Scharr算子、Canny算子和LOG算子
[Python图像处理] 十九.图像分割之基于K-Means聚类的区域分割
[Python图像处理] 二十.图像量化处理和采样处理及局部马赛克特效
[Python图像处理] 二十一.图像金字塔之图像向下取样和向上取样

前面一篇文章我讲解了Python图像量化、采样处理及图像金字塔。本文主要讲解图像傅里叶变换的相关内容,在数字图像处理中,有两个经典的变换被广泛应用——傅里叶变换和霍夫变换。其中,傅里叶变换主要是将时间域上的信号转变为频率域上的信号,用来进行图像除噪、图像增强等处理。基础性文章,希望对你有所帮助。同时,该部分知识均为杨秀璋查阅资料撰写,转载请署名CSDN+杨秀璋及原地址出处,谢谢!!

1.图像傅里叶变换
2.Numpy实现傅里叶变换
3.Numpy实现傅里叶逆变换
4.OpenCV实现傅里叶变换
5.OpenCV实现傅里叶逆变换


PS:文章参考自己以前系列图像处理文章及OpenCV库函数,同时参考如下文献:
《数字图像处理》(第3版),冈萨雷斯著,阮秋琦译,电子工业出版社,2013年.
《数字图像处理学》(第3版),阮秋琦,电子工业出版社,2008年,北京.
《OpenCV3编程入门》,毛星云,冷雪飞,电子工业出版社,2015,北京.
百度百科-傅里叶变换
网易云课堂-高登教育 Python+OpenCV图像处理
安安zoe-图像的傅里叶变换
daduzimama-图像的傅里叶变换的迷思----频谱居中
tenderwx-数字图像处理-傅里叶变换在图像处理中的应用
小小猫钓小小鱼-深入浅出的讲解傅里叶变换(真正的通俗易懂)


一.图像傅里叶变换原理

傅里叶变换(Fourier Transform,简称FT)常用于数字信号处理,它的目的是将时间域上的信号转变为频率域上的信号。随着域的不同,对同一个事物的了解角度也随之改变,因此在时域中某些不好处理的地方,在频域就可以较为简单的处理。同时,可以从频域里发现一些原先不易察觉的特征。傅里叶定理指出“任何连续周期信号都可以表示成(或者无限逼近)一系列正弦信号的叠加。”

下面引用李老师 “Python+OpenCV图像处理” 中的一个案例,非常推荐同学们去购买学习。如下图所示,他将某饮料的制作过程的时域角度转换为频域角度。

绘制对应的时间图和频率图如下所示:

傅里叶公式如下,其中w表示频率,t表示时间,为复变函数。它将时间域的函数表示为频率域的函数f(t)的积分。

傅里叶变换认为一个周期函数(信号)包含多个频率分量,任意函数(信号)f(t)可通过多个周期函数(或基函数)相加合成。从物理角度理解,傅里叶变换是以一组特殊的函数(三角函数)为正交基,对原函数进行线性变换,物理意义便是原函数在各组基函数的投影。如下图所示,它是由三条正弦曲线组合成。

傅里叶变换可以应用于图像处理中,经过对图像进行变换得到其频谱图。从谱频图里频率高低来表征图像中灰度变化剧烈程度。图像中的边缘信号和噪声信号往往是高频信号,而图像变化频繁的图像轮廓及背景等信号往往是低频信号。这时可以有针对性的对图像进行相关操作,例如图像除噪、图像增强和锐化等。

二维图像的傅里叶变换可以用以下数学公式(15-3)表达,其中f是空间域(Spatial Domain))值,F是频域(Frequency Domain)值

对上面的傅里叶变换有了大致的了解之后,下面通过Numpy和OpenCV分别讲解图像傅里叶变换的算法及操作代码。


二.Numpy实现傅里叶变换

Numpy中的 FFT包提供了函数 np.fft.fft2()可以对信号进行快速傅里叶变换,其函数原型如下所示,该输出结果是一个复数数组(Complex Ndarry)。

fft2(a, s=None, axes=(-2, -1), norm=None)

  • a表示输入图像,阵列状的复杂数组
  • s表示整数序列,可以决定输出数组的大小。输出可选形状(每个转换轴的长度),其中s[0]表示轴0,s[1]表示轴1。对应fit(x,n)函数中的n,沿着每个轴,如果给定的形状小于输入形状,则将剪切输入。如果大于则输入将用零填充。如果未给定’s’,则使用沿’axles’指定的轴的输入形状
  • axes表示整数序列,用于计算FFT的可选轴。如果未给出,则使用最后两个轴。“axes”中的重复索引表示对该轴执行多次转换,一个元素序列意味着执行一维FFT
  • norm包括None和ortho两个选项,规范化模式(请参见numpy.fft)。默认值为无

Numpy中的fft模块有很多函数,相关函数如下:

#计算一维傅里叶变换
numpy.fft.fft(a, n=None, axis=-1, norm=None)
#计算二维的傅里叶变换
numpy.fft.fft2(a, n=None, axis=-1, norm=None)
#计算n维的傅里叶变换
numpy.fft.fftn()
#计算n维实数的傅里叶变换
numpy.fft.rfftn()
#返回傅里叶变换的采样频率
numpy.fft.fftfreq()
#将FFT输出中的直流分量移动到频谱中央
numpy.fft.shift()

下面的代码是通过Numpy库实现傅里叶变换,调用np.fft.fft2()快速傅里叶变换得到频率分布,接着调用np.fft.fftshift()函数将中心位置转移至中间,最终通过Matplotlib显示效果图。

# -*- coding: utf-8 -*-
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

#读取图像
img = cv.imread('test.png', 0)

#快速傅里叶变换算法得到频率分布
f = np.fft.fft2(img)

#默认结果中心点位置是在左上角,
#调用fftshift()函数转移到中间位置
fshift = np.fft.fftshift(f)       

#fft结果是复数, 其绝对值结果是振幅
fimg = np.log(np.abs(fshift))

#展示结果
plt.subplot(121), plt.imshow(img, 'gray'), plt.title('Original Fourier')
plt.axis('off')
plt.subplot(122), plt.imshow(fimg, 'gray'), plt.title('Fourier Fourier')
plt.axis('off')
plt.show()

输出结果如图15-2所示,左边为原始图像,右边为频率分布图谱,其中越靠近中心位置频率越低,越亮(灰度值越高)的位置代表该频率的信号振幅越大。


三.Numpy实现傅里叶逆变换

下面介绍Numpy实现傅里叶逆变换,它是傅里叶变换的逆操作,将频谱图像转换为原始图像的过程。通过傅里叶变换将转换为频谱图,并对高频(边界)和低频(细节)部分进行处理,接着需要通过傅里叶逆变换恢复为原始效果图。频域上对图像的处理会反映在逆变换图像上,从而更好地进行图像处理。

图像傅里叶变化主要使用的函数如下所示:

#实现图像逆傅里叶变换,返回一个复数数组
numpy.fft.ifft2(a, n=None, axis=-1, norm=None)
#fftshit()函数的逆函数,它将频谱图像的中心低频部分移动至左上角
numpy.fft.fftshift()
#将复数转换为0至255范围
iimg = numpy.abs(逆傅里叶变换结果)

下面的代码分别实现了傅里叶变换和傅里叶逆变换。

# -*- coding: utf-8 -*-
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

#读取图像
img = cv.imread('Lena.png', 0)

#傅里叶变换
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
res = np.log(np.abs(fshift))

#傅里叶逆变换
ishift = np.fft.ifftshift(fshift)
iimg = np.fft.ifft2(ishift)
iimg = np.abs(iimg)

#展示结果
plt.subplot(131), plt.imshow(img, 'gray'), plt.title('Original Image')
plt.axis('off')
plt.subplot(132), plt.imshow(res, 'gray'), plt.title('Fourier Image')
plt.axis('off')
plt.subplot(133), plt.imshow(iimg, 'gray'), plt.title('Inverse Fourier Image')
plt.axis('off')
plt.show()

输出结果如图15-4所示,从左至右分别为原始图像、频谱图像、逆傅里叶变换转换图像。


四.OpenCV实现傅里叶变换

OpenCV 中相应的函数是cv2.dft()和用Numpy输出的结果一样,但是是双通道的。第一个通道是结果的实数部分,第二个通道是结果的虚数部分,并且输入图像要首先转换成 np.float32 格式。其函数原型如下所示:

dst = cv2.dft(src, dst=None, flags=None, nonzeroRows=None)

  • src表示输入图像,需要通过np.float32转换格式
  • dst表示输出图像,包括输出大小和尺寸
  • flags表示转换标记,其中DFT _INVERSE执行反向一维或二维转换,而不是默认的正向转换;DFT _SCALE表示缩放结果,由阵列元素的数量除以它;DFT _ROWS执行正向或反向变换输入矩阵的每个单独的行,该标志可以同时转换多个矢量,并可用于减少开销以执行3D和更高维度的转换等;DFT _COMPLEX_OUTPUT执行1D或2D实数组的正向转换,这是最快的选择,默认功能;DFT _REAL_OUTPUT执行一维或二维复数阵列的逆变换,结果通常是相同大小的复数数组,但如果输入数组具有共轭复数对称性,则输出为真实数组
  • nonzeroRows表示当参数不为零时,函数假定只有nonzeroRows输入数组的第一行(未设置)或者只有输出数组的第一个(设置)包含非零,因此函数可以处理其余的行更有效率,并节省一些时间;这种技术对计算阵列互相关或使用DFT卷积非常有用

注意,由于输出的频谱结果是一个复数,需要调用cv2.magnitude()函数将傅里叶变换的双通道结果转换为0到255的范围。其函数原型如下:

cv2.magnitude(x, y)

  • x表示浮点型X坐标值,即实部
  • y表示浮点型Y坐标值,即虚部
    最终输出结果为幅值,即:

完整代码如下所示:

# -*- coding: utf-8 -*-
import numpy as np
import cv2
from matplotlib import pyplot as plt

#读取图像
img = cv2.imread('Lena.png', 0)

#傅里叶变换
dft = cv2.dft(np.float32(img), flags = cv2.DFT_COMPLEX_OUTPUT)

#将频谱低频从左上角移动至中心位置
dft_shift = np.fft.fftshift(dft)

#频谱图像双通道复数转换为0-255区间
result = 20*np.log(cv2.magnitude(dft_shift[:,:,0], dft_shift[:,:,1]))

#显示图像
plt.subplot(121), plt.imshow(img, cmap = 'gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(result, cmap = 'gray')
plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
plt.show()

输出结果如图15-5所示,左边为原始“Lena”图,右边为转换后的频谱图像,并且保证低频位于中心位置。


五.OpenCV实现傅里叶逆变换

在OpenCV 中,通过函数cv2.idft()实现傅里叶逆变换,其返回结果取决于原始图像的类型和大小,原始图像可以为实数或复数。其函数原型如下所示:

dst = cv2.idft(src[, dst[, flags[, nonzeroRows]]])

  • src表示输入图像,包括实数或复数
  • dst表示输出图像
  • flags表示转换标记
  • nonzeroRows表示要处理的dst行数,其余行的内容未定义(请参阅dft描述中的卷积示例)

完整代码如下所示:

# -*- coding: utf-8 -*-
import numpy as np
import cv2
from matplotlib import pyplot as plt

#读取图像
img = cv2.imread('Lena.png', 0)

#傅里叶变换
dft = cv2.dft(np.float32(img), flags = cv2.DFT_COMPLEX_OUTPUT)
dftshift = np.fft.fftshift(dft)
res1= 20*np.log(cv2.magnitude(dftshift[:,:,0], dftshift[:,:,1]))

#傅里叶逆变换
ishift = np.fft.ifftshift(dftshift)
iimg = cv2.idft(ishift)
res2 = cv2.magnitude(iimg[:,:,0], iimg[:,:,1])

#显示图像
plt.subplot(131), plt.imshow(img, 'gray'), plt.title('Original Image')
plt.axis('off')
plt.subplot(132), plt.imshow(res1, 'gray'), plt.title('Fourier Image')
plt.axis('off')
plt.subplot(133), plt.imshow(res2, 'gray'), plt.title('Inverse Fourier Image')
plt.axis('off')
plt.show()

输出结果如图15-6所示,第一幅图为原始“Lena”图,第二幅图为傅里叶变换后的频谱图像,第三幅图为傅里叶逆变换,频谱图像转换为原始图像的过程。


六.总结

傅里叶变换的目的并不是为了观察图像的频率分布(至少不是最终目的),更多情况下是为了对频率进行过滤,通过修改频率以达到图像增强、图像去噪、边缘检测、特征提取、压缩加密等目的。下一篇文章,作者将结合傅里叶变换和傅里叶逆变换讲解它的应用。

时也,命也。
英语低分数线一分,些许遗憾,但不气馁,更加努力。雄关漫道真如铁,而今迈过从头越,从头越。苍山如海,残阳如血。感谢一路陪伴的人和自己。

无论成败,那段拼搏的日子都很美。结果只会让我更加努力,学好英语。下半年沉下心来好好做科研写文章,西藏之行,课程分享。同时,明天的博士考试加油,虽然裸泳,但也加油!还有春季招考开始准备。

最后补充马刺小石匠精神,当一切都看起来无济于事的时候,我去看一个石匠敲石头.他一连敲了100次,石头仍然纹丝不动。但他敲第101次的时候,石头裂为两半。可我知道,让石头裂开的不是那最后一击,而是前面的一百次敲击的结果。人生路漫漫,不可能一路一帆风顺,暂时的不顺只是磨练自己的必经之路,夜最深的时候也是距黎明最近的时刻,经历过漫漫长夜的打磨,你自身会更加强大。

最后希望这篇基础性文章对您有所帮助,如果有错误或不足之处,请海涵!

(By:Eastmount 2019-04-23 周二下午6点写于花溪 https://blog.csdn.net/Eastmount )

2015-06-09 11:37:07 u012590688 阅读数 1974

          依据对称性特征对障碍物进行检测,依照一般定性的分析方法,我们只能知道障碍物是否是对称的,但是在这里仅仅利用对称性的定性分析是不够的,必须能够用数学的形式对其进行定量的描述,下面将对称性的定量分析进行了介绍。本文利用连续对称的概念,建立了定量的方法来度量对称性。图像中的一行灰度数据可视为水平像素坐标的一维函数g(x),(我们不需要知道函数是什么,因为我们最终计算只是用这个函数值,这个类似于核函数的感觉)任何函数都可以写成一个偶函数










2019-05-11 08:31:12 Dujing2019 阅读数 3570

数字图像处理—形态学图像处理

同样的,暂时对书上已经写得很清楚的知识点不再重复赘述,主要做一些总结,思考以及知识点的梳理和扩展。

(一)预备知识

介绍一下形态学中的一些基本概念。

  1. 用数学形态学(也称图像代数)表示以形态为基础对图像进行分析的数学工具
  2. 基本思想是用具有一定形态的结构元素去度量和提取图像中的对应形状以达到对图像分析识别的目的
  3. 形态学图像处理的数学基础和所用语言是集合论
  4. 形态学图像处理的应用可以简化图像数据, 保持它们基本的形状特性,并除去不相干的结 构
  5. 形态学图像处理的基本运算有4个:膨胀、 腐蚀、开操作和闭操作

1.1 集合理论中的基本概念

介绍一下比较陌生的几个概念,其他的看书就好:

  1. 所有像素坐标的集合均不属于集合A,记为AcA^c,由下式给出:
    在这里插入图片描述
    这个集合称为集合A的补集

  2. 集合B的反射,定义为:

    即关于原集合原点对称 .

  3. 集合A平移到点z=(z1,z2),表示为(A)z,定义为:

1.2 二值图像、集合及逻辑算子

二值图像

二值图像(Binary Image),按名字来理解只有两个值,0和1,0代表黑,1代表白,或者说0表示背景,而1表示前景。其保存也相对简单,每个像素只需要1Bit就可以完整存储信息。如果把每个像素看成随机变量,一共有N个像素,那么二值图有2的N次方种变化,而8位灰度图有255的N次方种变化,8为三通道RGB图像有255255255的N次方种变化。也就是说同样尺寸的图像,二值图像保存的信息更少。二值图像(binary image),即图像上的每一个像素只有两种可能的取值或灰度等级状态,人们经常用黑白、B&W、单色图像表示二值图像。

二值图像集合

如果A和B是二值图像,那么C=A∪B仍是二值图像。这里,如 果 A 和B中相应的像素不是前景像素就是背景像素,那么 C中的这个像素就是前景像素。以第一种观点,函数 C由下式给出:
在这里插入图片描述
另一方面,运用集合的观点,C由下式给出:
在这里插入图片描述
集合运算

  1. A为图像集合,B为结构元素(集合)。
  2. 数学形态学运算时B对A进行操作。
  3. 结构元素要有1个原点(即结构元素参与形态学运算的参考点),可以是中心像素,原则上可选任何像素。
    注意:原点可以包含在结构元素中,也可以不包含在结构元素中,但运算的结果常不相同。

编码

f = imread('D:\数字图像处理\第九章学习\Fig0903(a).tif');
g = imread('D:\数字图像处理\第九章学习\Fig0903(b).tif');
subplot(2,3,1), imshow(f);title('(a)二值图像 A:');
subplot(2,3,2), imshow(g);title('(b)二值图像 B:');
subplot(2,3,3), imshow(~f);title('(c)A的补集~A:');
subplot(2,3,4), imshow(f|g);title('(d) A和B的并集 A|B:');
subplot(2,3,5), imshow(f&g);title('(e)A和B的交集 A & B:');
subplot(2,3,6), imshow(f&~g);title('(f)A和B的差集 A&~B');

代码运行效果如下
在这里插入图片描述
分析

图像(d)是 “ UTK”和 “ GT” 图像的并集,包括来自两幅图像的所有前景像素。相反,两幅图像的交集(图(e))显示了字母 “ UTK”和 “ GT”中重叠的像素。最后,集合的差集图像(图(f))显示了 “ UTK”中除去 “ GT” 像素后的字母。

(二)膨胀和腐蚀

2.1 膨胀

膨胀:膨胀是在二值图像中“加长”或“变粗”的操作。这种特殊的方式和变粗的程度由一个称为结构元素的集合控制。(实际就是将结构元素的原点与二值图像中的1重叠,将二值图像中重叠部分不是1的值变为1,完成膨胀)。

公式

A和B是两个集合,A被B膨胀定义为:

公式解释:

  1. B的反射进行平移与A的交集不为空。
  2. B的反射:相对于自身原点的映象。
  3. B的平移:对B的反射进行位移

图解

      

(a)集合A    (b)结构元素B (黑色为原点所在)

      

(c)结构元素B的映像    (d)图中两种阴影部分(深色为扩大的部分)合起来为A+B

注意

  1. 膨胀运算只要求结构元素的原点在目标图像的内部平移,换句话说,当结构元素在目标图像上平移时,允许结构元素中的非原点像素超出目标图像的范围
  2. 膨胀运算具有扩大图像和填充图像中比结果元素小的成分的作用,因此在实际应用中可以利用膨胀运算连接相邻物体和填充图像中的小孔和狭窄的缝隙

膨胀举例

膨胀函数

D = imdilate(A,B)

图像膨胀的应用:桥接文字裂缝

编码:

A = imread('D:\数字图像处理\第九章学习\Fig0906(a).tif');
B = [0 1 0; 1 1 1; 0 1 0];   %指定结构元素由0和1组成的矩阵
A2 = imdilate(A, B);    %二值图像
subplot(1,2,1), imshow(A);title('(a)包括断开文本的输入图像:');
subplot(1,2,2), imshow(A2);title('(b)膨胀后图像:');

在这里插入图片描述
图片中字体的加粗,且填充了字母中的小孔和狭窄的缝隙。

2.2 结构元的分解

公式
在这里插入图片描述
公式理解

B膨胀A等同于B1先膨胀A,再用B2膨胀之前的结果。

举例

下面是由1组成的5x5数组的膨胀:
在这里插入图片描述
这个结构元能够分解为值为 1 的 5 元素行矩阵和值为 1 的 5 元素列矩阵:

在这里插入图片描述
分析

在原结构元中,元素个数为 25; 但在行列分解后,总元素数目仅为 10。这意味着首先用 行结构元膨胀,再用列结构元膨胀,能够比 5x5 的数组膨胀快 2.5 倍。在实践中,速度的增长稍微慢一些,因为在每个膨胀运算中总有些其他开销。然而,由分解执行获得的速度方面的增 长仍然有很大意义。

2.3 strel函数

工具箱函数 strel 用于构造各种形状和大小的结构元。

基本语法

se = strel(shape, parameters)

shape用于指定希望形状的字符串,parameters是描述形状信息的参数列表。

具体例子参考课本,是基础语法。

2.4 腐蚀

腐蚀:与膨胀相反,对二值图像中的对象进行“收缩”或“细化”。(实际上将结构元素的原点覆盖在每一个二值图像的1上,只要二值图像上有0和结构元素的1重叠,那么与原点重叠的值为0)同样由集合与结构元素完成。

公式

A和B是两个集合,A被B腐蚀定义为:

公式解释:

  1. A被 B 腐蚀是包含在A中的B由z平移的所有点z的集合。
  2. B包含在A中的声明相当于B不共享A背景的任何元素。

图解
     

(a)集合A(阴影部分)   (b)结构元素B(阴影部分,深色部分为原点)(c)阴影部分合起来为A-B

注意

  1. 当结构元素中原点位置不为1(也即原点不属于结构元素时),也要把它看作是1,也就是说,当在目标图像中找与结构元素B相同的子图像时,也要求子图像中与结构元素B的原点对应的那个位置的像素的值是1。
  2. 腐蚀运算要求结构元素必须完全包括在被腐蚀图像内部:换句话说,当结构元素在目标图像上平移时,结构元素中的任何元素不能超过目标图像范围。
  3. 腐蚀运算的结果不仅与结构元素的形状选取有关,而且还与原点位置的选取有关
  4. 腐蚀运算具有缩小图像和消除图像中比结构元素小的成分的作用,因此在实际应用中,可以利用腐蚀运算去除物体之间的粘连,消除图像中的小颗粒噪声

腐蚀举例

腐蚀函数

A2 = imerode(A, se)

图像腐蚀应用:消除图像细节部分

编码:

f = imread('D:\数字图像处理\第九章学习\Fig0908(a).tif');
se = strel('disk', 10);
g = imerode(f, se);
se = strel('disk', 5);
g1 = imerode(f, se);
g2 = imerode(f, strel('disk', 20));
subplot(2,2,1), imshow(f);title('(a)原始图像的尺寸为480x480像素:');
subplot(2,2,2), imshow(g);title('(b)用半径为10的圆形腐蚀:');
subplot(2,2,3), imshow(g1);title('(c)用半径为5的圆形腐蚀:');
subplot(2,2,4), imshow(g2);title('(d)用半径为20的圆形腐蚀');

分析

假设要除去图a中的细线,但想保留其他结构,可以选取足够小的结构元来匹配中心方块,但较粗的边缘线因太大而无法匹配全部线。图b几乎成功去掉了模板中的细线,图c中一些引线还没有去掉,图d中引线都被去掉了,但是边缘引线也丢失了,所以选取合适的结构元很重要。

(三) 膨胀与腐蚀的结合

3.1 开操作和闭操作

开操作

  1. 使图像的轮廓变得光滑,断开狭窄的间断和消除细的突出物。
  2. 使用结构元素B对集合A进行开操作,定义为:

    先用B对A腐蚀,然后用B对结果膨胀。
  3. 与开操作等价的数学表达式为:
  4. A o B 的边界通过B中的点完成。
  5. B在A的边界内转动时,B中的点所能到达的A的边界的最远点。
  6. A o B 是 A的子集合。
  7. 如果C是D的子集,则 C o B是 D o B的子集。
  8. (A o B) o B = A o B

闭操作

  1. 同样使图像的轮廓变得光滑,但与开操作相反,它能消除狭窄的间断和长细的鸿沟,消除小的孔洞,并填补轮廓线中的裂痕。
  2. 使用结构元素B对集合A进行闭操作,定 义为:

    先用B对A膨胀,然后用B对结果腐蚀。
  3. A . B的边界通过B中的点完成 。
  4. B在A的边界外部转动 :
  5. A 是 A . B的子集合。
  6. 如果C 是 D 的子集 , 则C . B 是 D . B的子集。
  7. (A . B) . B = A . B

工具箱函数

开操作:

C = imopen(A, B)

闭操作:

C = imclose(A, B)

A为二值图像,B为0,1矩阵组成,并且是指定结构元素。

函数imopen 和 imclose 的应用

编码:

f = imread('D:\数字图像处理\第九章学习\Fig0910(a).tif');
se = strel('square', 40);
fo = imopen(f, se);
fc = imclose(f, se);
foc = imclose(fo, se);
subplot(2,2,1), imshow(f), title('(a)原图');
subplot(2,2,2), imshow(fo), title('(b)开操作');
subplot(2,2,3), imshow(fc), title('(c)闭操作');
subplot(2,2,4), imshow(foc), title('(d) (b)的闭操作结果');

分析

  1. 图(a)中的图像设计了一些用于演示开操作和闭操作的特征,比如细小突起、细的桥接点、几个弯口、孤立的小洞、 小的孤立物和齿状边缘。
  2. 图 (b)显示了结果。注意,从图中可以看出,细的突出和外部点的边缘的不规则部分被去除掉了,细的桥接和小的孤立物也被去除了。
  3. 图 ©中的结果: 这里,细的弯口、内部的不规则边缘和小洞都被去除了。先做开操作的闭操作的结果有平滑效果.
  4. 图 (d)显示了平滑过的物体。

噪声滤波器

先开操作再闭操作,构成噪声滤波器。

编码:

f = imread('D:\数字图像处理\第九章学习\Fig0911(a).tif');
se = strel('square', 6);
fo = imopen(f, se);
foc = imclose(fo, se);
subplot(1,3,1), imshow(f), title('(a)带噪声的指纹图像');
subplot(1,3,2), imshow(fo), title('(b)图像的开操作');
subplot(1,3,3), imshow(foc), title('(c)先用开操作,再用闭操作');

在这里插入图片描述
分析

  1. 图(a)是受噪声污染的指纹二值图像,噪声为黑色背景上的亮元素和亮指纹部分的暗元素。
  2. 图(b)所示的图像。发现,对图像进行开操作可以去除噪声点,但是这种处理在指纹的纹脊上又引入一些缺口
  3. 图( c )显示了最终结果。在这个结果中,大多数噪声被消除了,开运算的闭运算可以给指纹填充缺口,但是指纹纹路并没有完全恢复 。

3.2 击中或击不中变换

击中击不中变换(HMT),HMT变换可以同时探测图像的内部和外部。研究解决目标图像识别模式识别等领域,在处理目标图像和背景的关系上能够取得更好的效果。

作用:形状检测的基本工具。

公式

A中对B进行的匹配(击中)表示为:

B1是由与一个对象相联系的B元素构成的集合,B1是由与一个对象相联系的B元素构成的集合。

图解

工具箱函数

C = bwhitmiss(A, B1, B2)

其中的 C为结果,A为输入图像,B1、B2表示结构元素。

定位图像中物体左上角的像素

编码:

f = imread('D:\数字图像处理\第九章学习\Fig0913(a).tif');
B1 = strel([0 0 0;0 1 1; 0 1 0]);
B2 = strel([1 1 1;1 0 0;1 0 0]);
g = bwhitmiss(f,B1,B2);
subplot(1,2,1), imshow(f), title('(a)原始图像');
subplot(1,2,2), imshow(g), title('(b)击中、击不中变换的结果');

分析

  1. 图(a)显示了包括各种尺寸的正方形图像。我们要定位有东、南相邻像素(这些 “击中”)和没有东北、北、西北、西和西南相邻像素(这些 “击不中”)的前景像素。这些要求导致以下B1,B2两个结构元。这两个结构元都不包括东南邻域像素,这称为不关心像素。用函数 bwhitmiss 来计算变换。
  2. 图 (b)中的每个单像素点都是图 (a)中物体左上角的像素。图 (b)中是放大后的像素,以便更清晰。bwhitmiss的替代语法可以把Bl 和 B2 组合成间隔矩阵。只要 B1等于 1 或-1,B2 等于 1, 间隔矩阵就等于 1。对于不关心像素,间隔矩阵等于 0。

3.3 bwmorph函数

工具箱函数 bwmorph 执行许多以膨胀、腐蚀和查找表运算相结合为基础的形态学操作, 调用语法为:

g = bwmorph(f, operation, n);

f 是输入的二值图像,operation 是指定所希望运算的字符串,n 是指定重复次数的正整数。

细化

f = imread('D:\数字图像处理\第九章学习\Fig0911(a).tif');
g1 = bwmorph(f, 'thin',1);
g2 = bwmorph(f, 'thin',2);
ginf = bwmorph(f,'thin', Inf);
subplot(1,4,1),imshow(f);title('(a)指纹图像:');
subplot(1,4,2),imshow(g1);title('(b)细化一次后的指纹图像:');
subplot(1,4,3),imshow(g2);title('(c)细化两次后的图像:');
subplot(1,4,4),imshow(ginf);title('(d)一直细化到稳定状态的图像:');

在这里插入图片描述
骨骼化

f = imread('D:\数字图像处理\第九章学习\Fig0916(a).tif');
fs = bwmorph(f,'skel',Inf);
for k = 1:5
    fa = fs & ~endpoints(fs);
end
subplot(1,3,1),imshow(f);title('(a)骨头图像:');
subplot(1,3,2),imshow(fs);title('(b)使用函数 bwmorph 得到的骨豁:');
subplot(1,3,3),imshow(fa);title('(c)使用函数 endpoint 裁剪后的骨豁:');

在这里插入图片描述
分析:骨骼化(Gonzalez和 Woods[2008])是另一种减少二值图像中的物体为一组细“笔画”的方法, 这些细骨豁仍保留原始物体形状的重要信息。当 operation 置为 'skel '时,函数 bwmorph 执行骨骼化。令 f 代表图(a)中类似骨头的图像,为了计算骨骼,调用 bwmorph, 令 n=Inf,图(b)显示了骨骼化的结果,与物体的基本形状相似。骨骼化和细化经常产生短的无关的“毛刺” ,有时这被叫做寄生成分。清除(或除去)这些“毛刺”的处理称为裁剪。方法是反复确认并去除端点。通过 5 次去除端点的迭代,得以后处理骨骼化图像 fs,图(c )显示了结果。

(四)标记连通分量

工具箱函数

[L, num] = bwlabel (f, conn)

f 是输入二值图像,coon指定希望的连接方式(不是4连接就是8连接),输出L叫做标记矩阵,函数num则给出找到的连通分量总数。

计算和显示连通分量的质心:

f = imread('D:\数字图像处理\第九章学习\Fig0917(a).tif');
imshow(f);title('(a)标注连通分量原始图像:');
[L,n]=bwlabel(f);        %L为标记矩阵,n为找到连接分量的总数
[r,c]=find(L==3);        %返回第3个对象所有像素的行索引和列索引 
rbar=mean(r);
cbar=mean(c);
figure,imshow(f);title('(b)标记所有对象质心后的图像:');
hold on            %保持当前图像使其不被刷新
for k=1:n
   [r,c]=find(L==k);
   rbar=mean(r);
   cbar=mean(c);
   plot(cbar,rbar,'Marker','o','MarkerEdgeColor','k',...
        'MarkerFaceColor','k','MarkerSize',10);
   plot(cbar,rbar,'Marker','*','MarkerFaceColor','w'); %其中的marker为标记
end

(五)形态学重建

概述:重构是一种涉及到两幅图像和一个结构元素的形态学变换。一幅图像,即标记,是变换的开始点。另一幅图像是掩膜,用来约束变换过程。结构元素用于定义连接性。

定义:若G是掩膜,f为标记,则从f重构g可以记为RgR_g(f),由下列的迭代过程定义:

  1. 将h1初始化为标记图像f。
  2. 创建结构元素 :B = ones(3)。
  3. 重复

    直到

    其中,标记f必须是g的一个子集。

函数

out = imreconstruct(marker,mask)

masker是标记,mask是掩膜。

5.1 通过重建进行开操作

在形态学开操作中,腐蚀典型地去除小的物体,且随后的膨胀趋向于恢复保留的物体形状。 然而,这种恢复的精确度取决于形状和结构元之间的相似性。本节讨论的方法,通过重建进行开操作能准确地恢复腐蚀之后的物体形状。用结构元B对图像 G通过重建进行开操作可定义为 :
在这里插入图片描述

f = imread('D:\数字图像处理\第九章学习\Fig0917(a).tif');
subplot(3,2,1),imshow(f);title('(a)重构原始图像');
fe=imerode(f,ones(51,1));%竖线腐蚀
subplot(3,2,2),imshow(fe);title('(b)使用竖线腐蚀后的结果');
fo=imopen(f,ones(51,1));%竖线做开运算
subplot(3,2,3),imshow(fo);title('(c)使用竖线做开运算结果');
fobr=imreconstruct(fe,f);%fe做标记
subplot(3,2,4),imshow(fobr);title('(d)使用竖线做重构开运算');
ff=imfill(f,'holes');%对f进行孔洞填充
subplot(3,2,5),imshow(ff);title('(e)对f填充孔洞后的图像');
fc=imclearborder(f,8);%清除边界,2维8邻接
subplot(3,2,6),imshow(fc);title('(f)对f清除边界后的图像');

在这里插入图片描述
分析

  1. 传统开运算中,腐蚀去除掉小对象,随后的膨胀恢复原始对象形状,但受元素结构影响,恢复的往往不是很精确。
  2. 重构则能精确恢复原始图像。

5.2 填充孔洞

令I表示二值图像,假设我们选择标记图像F,除了图像边缘外,其余部分都为 0, 边缘部分设值为 1-I:
在这里插入图片描述
函数

g = imfill(f,‘holes’);

5.3 清除边界物体

定义标记图像F为:
在这里插入图片描述
其中,/是原始图像,然后以/作为模板图像,重建
在这里插入图片描述
得到一幅图像H, 其中仅包含与边界接触的物体。

函数

g = imclearborder(f,conn)

f 是输入图像,g 是结果。conn 的值不是 4 就是 8(默认)。 物体更亮且与图像边界相连接的结构。

(六)灰度级形态学

6.1 膨胀和腐蚀

灰度图像的形态学梯度定义为膨胀运算与腐蚀运算的结果之间的差值。

膨胀定义

  1. 使用结构元素b对f的灰度膨胀定义为:

    其中,DfD_fDbD_b分别是f和b的定义域,f和b是函数而不是二值形态学情况中的集合。

  2. 当结构元素b是平坦的,即b(x,y)在其定义域内都为0时:
    在这里插入图片描述

腐蚀定义

  1. 使用结构元素b对f的灰度腐蚀定义为:
    在这里插入图片描述
    其中,DfD_fDbD_b分别是f和b的定义域。

  2. 当结构元素b是平坦的,即b(x,y)在其定义域内都为0时:
    在这里插入图片描述

膨胀和腐蚀操作

编写代码:

f = imread('D:\数字图像处理\第九章学习\Fig0923(a).tif');
se=strel('square',3);  %构造了一个平坦的3x3的结构元素
gd=imdilate(f,se);    %对原图像进行膨胀操作
ge=imerode(f,se);     %对原图像进行腐蚀操作
morph_grad=imsubtract(gd,ge); %从膨胀的图像中减去腐蚀过得图像产生一个形态学梯度。
subplot(3,2,1);imshow(f,[]);title('(a)原始图像');
subplot(3,2,2),imshow(gd,[]);title('(b)膨胀的图像');
subplot(3,2,3),imshow(ge,[]);title('(c)腐蚀的图像');
subplot(3,2,4),imshow(morph_grad,[]);title('(d)形态学梯度');

在这里插入图片描述
分析

  1. 膨胀得到的图像比原图像更明亮,并且减弱或消除小的,暗的细节部分。即比原图像模糊。
  2. 腐蚀得到的图像更暗,并且尺寸小,明亮的部分被削弱 。

6.2 开操作和闭操作

图像开运算

  1. 在灰度图像中,开操作的表达式与二值图像拥有相同的形式。
  2. 把一幅图像看做是一个三维表明,其亮度值代表xy平面上的高度值,则当结构元素b在f下面活动时,结构元素的任何部分的最高值构成了开运算的结果。
  3. 先进行腐蚀操作可以除去小的亮的图像细节,但这样会使图像变暗,接下来进行膨胀操作增强图像的整体亮度。

图像闭运算

  1. 在灰度图像中,闭操作的表达式与二值图像拥有相同的形式。
  2. 当结构元素b在f的上面活动时,结构元素的任何部分的最低值构成了闭运算的结果 。
  3. 先通过膨胀操作除去图像中的暗细节,同时增加图像的亮度,接下来对图像进行腐蚀,而不会将膨胀操作除去的部分重新引入图像中。

用开操作和闭操作做形态学平滑

f = imread('D:\数字图像处理\第九章学习\Fig0925(a).tif');
subplot(3,2,1),imshow(f);  
title('(a)木钉图像原图');   
se=strel('disk',5);     %disk其实就是一个八边形  
fo=imopen(f,se);        %经过开运算  
subplot(3,2,2),imshow(f);  
title('(b)使用半径5的disk开运算后的图像');   
foc=imclose(fo,se);  
subplot(3,2,3),imshow(foc);  
title('(c)先开后闭的图像'); 
focd=imclose(f,se);  
subplot(3,2,4),imshow(focd);  
title('(d)原始图像的闭操作'); 
foce=imopen(focd,se);  
subplot(3,2,5),imshow(foce);  
title('(e)先闭后开的图像'); 
fasf=f;  
for i=2:5  
    se=strel('disk',i);  
    fasf=imclose(imopen(fasf,se),se);  
end  
subplot(3,2,6),imshow(fasf);  
title('(f)使用开闭交替滤波后图像'); 


在这里插入图片描述
分析

  1. 图 (b)显示了开操作的图像 fo, 在这里,我们看到,亮区域己经被调低了(平滑),木钉上的暗条文几乎没有受影响。
  2. 图 (c )显示了开操作的闭操作 foe。现在我们注意到,暗区域已经被平滑得很好了,结果是整个图像得到全部平滑。这种过程通常叫做开-闭滤波。先开运算后闭运算构成噪声滤波器,用来平滑图像并去除噪声。
  3. 图 (d)显示了原始图像的闭操作结果。木钉上的暗条文已经被平滑掉了,主要留下了亮的细节(注意背景中的亮条文)。
  4. 图 (e)显示了这些条文的平滑和木钉表面的进一步平滑效果。最终结果是原始图像得到全部平滑。
  5. 图(f)是交替顺序滤波,交替顺序滤波的一种形式是用不断增大的一系列结构元执行开-闭滤波,刚开始用小的结构元,增加大小,直到与图 (b)和©中结构元的大小相同为止。交替顺序滤波与单个开-闭滤波相比,处理图像更平滑一些。

非均匀背景的补偿

f = imread('D:\数字图像处理\第九章学习\Fig0926(a).tif');
g = f>=(255*graythresh(f));
se=strel('disk',100);
fo=imopen(f,se);
f2=imsubtract(f,fo); 
g1 = f2>=(255*graythresh(f2));
subplot(2,3,1),imshow(f);  
title('(a)原始图像');  
subplot(2,3,2),imshow(g);  
title('(b)经过阈值处理后的图像');   
subplot(2,3,3),imshow(f);  
title('(c)原图开运算后的图像');  
subplot(2,3,4),imshow(f2);  
title('(d)原图减去开运算');  
subplot(2,3,5),imshow(g1);  
title('(e)最终结果');  

在这里插入图片描述
分析

  1. 图 (a) :显示了一幅米粒的图像f,图像下部的背景比上部的黑。这样的话,对不平坦的亮度进行阈值处理会很困难。
  2. 图 (b) "是阈值处理方案,图像顶端的米粒被很好地从背景中分离开来,但是图像底部的米粒没有从背景中正确地提取出来。
  3. 图(c ):对图像进行开操作,可以产生对整个图像背景的合理估计。
  4. 图(d) :把图(c )从原始图像中减去,生成一幅拥有合适的均勾背景的米粒图像.
  5. 图(e):显示了新的经阈值处理后的图像。注意,改进效果超过了图 (b)。

粒度测定 :

颗粒分析:形态学技术可以用与间接地度量颗粒的大小分布,但不能准确地识别每一个颗粒。对于形状规则且亮于背景大的颗粒,基本方法是应用不断增大尺寸的形态学开运算。

f = imread('D:\数字图像处理\第九章学习\Fig0926(a).tif');
sumpixels=zeros(1,36);  
for k=0:35  
    se=strel('disk',k);  
    fo=imopen(f,se);  
    sumpixels(k+1)=sum(fo(:));  
end    
%可以看到,连续开运算之间的表面积会减少  
plot(0:35,sumpixels),xlabel('k'),ylabel('surface area');  
title('(a)表面积和结构元素半径之间的关系');  
figure,plot(-diff(sumpixels));%diff()函数为差分或者近似倒数,即相邻2个之间的差值  
xlabel('k'),ylabel('surface area reduction');  
title('(b)减少的表面积和结构元素半径之间的关系'); 

分析

  1. (a)连续开运算之间的表面积会减小。
  2. (b)图峰值表明出现了大量的有着这种半径的对象。

6.3 重建

重建

  1. h极小值变换:标记图像是由掩膜挑选ing减去常量所得。
  2. 开运算重建:先腐蚀后重建。
  3. 闭运算重建:对图像求补、计算其开操作重建并对结果求补。

重建移去复杂的背景

f = imread('D:\数字图像处理\第九章学习\Fig0930(a).tif');
subplot(3,3,1),imshow(f);  
title('(a)原图像');    
f_obr=imreconstruct(imerode(f,ones(1,71)),f);  
subplot(3,3,2),imshow(f_obr);  
title('(b)重建的开操作');   
f_o=imopen(f,ones(1,71));    
subplot(3,3,3),imshow(f_o);  
title('(c)开操作');    
f_thr=imsubtract(f,f_obr);    %顶帽重构
subplot(3,3,4),imshow(f_thr);  
title('(d)重建的顶帽操作');  
f_th=imsubtract(f,f_o)    %标准顶帽运算,方便比较
subplot(3,3,5),imshow(f_th);  
title('(e)顶帽操作');  
g_obr=imreconstruct(imerode(f_thr,ones(1,11)),f_thr);  
subplot(3,3,6),imshow(g_obr);  
title('(f)用水平线对(b)经开运算后重建图');   
g_obrd=imdilate(g_obr,ones(1,2));  
subplot(3,3,7),imshow(g_obrd);  
title('(g)使用水平线对(f)进行膨胀');  
f2=imreconstruct(min(g_obrd,f_thr),f_thr);  
subplot(3,3,8),imshow(f2);  
title('(h)最后的重建结果');  

在这里插入图片描述
分析

为了消除每个键盘上方的水平反射光,利用这些反射比图像中任何文本字符都要宽的这个事实。用长水平线的结构元执行重建的开操作,重建的开操作(f_obr) 显示于图(b)中。为了进行对比,图(c )显示了标准的开操作 (f_o) 。重建的开操作在提取水平的相邻键之间的背景方面的确较好。从原始图像中减去重建的开操作被称为顶帽重建 , 结果示于图 (d)中。消除图 (d)中键右边的垂直反射光。这可以通过用短的水平线执行重建的开操作来完成,在这个结果中(见图 (f)),垂直的反射光不见了。但是,包括字母的垂直的细笔画也不见了。我们利用了那些已被错误消除的字母非常接近第一次膨胀(见图 (g))后还存在的其他字符这一事实,以 f_thr 作为模板,以 min(g_obrd,f_thr) 作为标记,图 (h)显示了最后的结果。注意,背景上键盘的阴影和反射光都成功去除了。