[转] 卷积

0 定义

       简单定义:卷积是分析数学中一种重要的运算


       设:f(x),g(x)是R1上的两个可积函数,作积分:

       可以证明,关于几乎所有的实数x,上述积分是存在的。这样,随着x的不同取值,这个积分就定义了一个新函数h(x),称为函数fg的卷积,记为h(x)=(f*g)(x)

       由卷积得到的函数f*g一般要比fg都光滑。特别当g为具有紧致集的光滑函数f为局部可积时,它们的卷积f * g也是光滑函数。利用这一性质,对于任意的可积函数f,都可以简单地构造出一列逼近于f光滑函数fs,这种方法称为函数的光滑化或正则化

1 理解

       比较推荐知乎上的一个解释,https://www.zhihu.com/question/22298352。即在输入信号的每个位置,叠加一个单位响应,就得到了输出信号(这句也很好地解释了它的物理意义)。这个解释中并没有提到反褶,只有平移,因为它是从单位响应的角度考虑。如果从输入信号角度考虑,那么就会首先将激励信号反褶,再在每个位置上做乘加运算,得到输出。[对于卷积、傅里叶变换等等,只是将原始信号(数据)做一定的处理,得到另外一组信号(数据),而这组信号(数据)更利于处理,而不同的处理需求需要有针对性选择数据处理方式]。

2 计算

2.1 离散卷积

2.1.1 一维

       计算公式如下图所示


N-----为信号f(n)的长度

s(n)----为卷积结果序列,长度为len(f(n))+len(g(n))-1

以3个元素的信号为例:

f(n) = [1 2 3];g(n) = [2 3 1];

s(0) =f(0)g(0-0) + f(1)g(0-1)+f(2)g(0-2) = 1*2 + 2*0 + 3*0 =2

s(1) =f(0)g(1-0) + f(1)g(1-1) + f(2)g(1-2) = 1*3 + 2*2 + 3*0 = 7

s(2) =f(0)g(2-0) + f(1)g(2-1) + f(2)g(2-2) =1*1 + 2*3 + 3*2=13

s(3) =f(0)g(3-0) + f(1)g(3-1) + f(2)g(3-2) =1*0 + 2*1 + 3*3=11

s(4) =f(0)g(4-0) + f(1)g(4-1) + f(2)g(4-2) =1*0 + 2*0 + 3*1=3

最终结果为:s(n) = [2 7 13 11 3];

上述计算图示如下:


在数学里我们知道f(-x)的图像是f(x)对y轴的反转

     g(-m)就是把g(m)的序列反转,g(n-m)的意义是把g(-m)平移的n点:

如上图g(m)在信号处理中通常叫做滤波器或掩码,卷积相当于掩码g(m)反转后在信号f(n)上平移求和。

代码实现如下。

#include <iostream>

#include <vector>

 

using namespace std;

//一维向量的卷积运算

double convfft(vector<double> &a,vector<double> &b,vector<double> &cx) {

  unsigned int sz = a.size() +b.size() - 1;

  cx.resize(sz);

  int b_len = b.size();

  int a_len = a.size();

  for (intn = 0; n < sz; n++) {

    int kmin = (n >= b_len - 1) ?n - (b_len - 1) : 0;

    int kmax = (n < a_len - 1) ?n : a_len - 1;

    for (intk = kmin; k <= kmax; k++) {

      cx[n] +=a[k] *b[n -k];

    }

  }

  return 0;

}

上述方式其实是为了较好的运用计算机通过编程实现,如果是手动运算,则可以参考https://wenku.baidu.com/view/f68098b8360cba1aa911da5a.html中所述的方法计算。

       在matlab中可以通过convn方法(也有的matlab中方法名是conv)实现两个一维向量的卷积运算,注意convn中还可以跟除了第2个参数flag,表示返回卷积的一部分,这部分有参数shape决定:

full  返回完整的卷积(默认);

same  返回卷积的中心部分,与u有相同的大小;

valid 仅返回卷积中的那些被计算而没有填充零的部分,w的尺寸大小为max(size(u)-size(v)+1,0)。

2.1.2 二维

       同一维数据卷积一样。首先,将卷积模板图像翻转(等同于一维信号翻转),然后将卷积模板依次从上到下、从左到右滑动,计算乘积和,作为卷积以后的数值。

假设矩阵A(4*3)、B(2*3)如下:


首先,B需要旋转180,命令旋转2次90即可:


       其次,卷积操作图示:


      依次计算直至结束,结果数据为:


   同样地,matalabconvn2做卷积运算,也有fullsamevalid参数。具体区别可以参看如下链接http://blog.csdn.net/tina_ttl/article/details/51034809

2.2 连续

       http://blog.csdn.net/sbaini/article/details/50547896

3 应用

       卷积运算的一个重要应用即为图像,因为图像总是空间相关的,即每个像素点总是和周围部分像素有关,而不会与相距非常远的像素有关。所以利用卷积可以构建像素与周围像素的关系。

在图像处理中,图像的卷积是指一个卷积核作用在图像上得到的响应。显然,卷积核不同,得到响应也不同。卷积核,本质上是一个存在中心对称点的固定大小的矩阵。

但传统的卷积操作通常输出应该是与输入等宽的,而2中所述方法是得到一个长度为size(a)+size(b)-1的宽度的。所以图像处理中的卷积运算会做一定的修正。简单概述:

对于图像的每一个像素点,计算它的邻域像素和滤波器矩阵的对应元素的乘积,然后加起来,作为该像素位置的值。而其中的边缘像素(不一定是第一行和最后一行,而是依赖于卷积核的大小)。

       

可以参考http://blog.csdn.net/zouxy09/article/details/49080029。

边缘处理

1D图像中,用每个像素和它的二邻域的平均值来取代它的值。假设我们有个1D的图像I是这样的:


       对非图像边界的像素的操作比较简单。假设我们对I的第四个像素3做局部平均。也就是我们用2,3和7做平均,来取代这个位置的像素值。也就是,平均会产生一副新的图像J,这个图像在相同位置J (4) = (I(3)+I(4)+I(5))/3 = (2+3+7)/3 = 4。同样,我们可以得到J(3) = (I(2)+I(3)+I(4))/3 =(4+2+3)/3 = 3。需要注意的是,新图像的每个像素都取决于旧的图像,在计算J (4)的时候用J (3)是不对的,而是用I(3),I(4)和I(5)。所以每个像素都是它和它邻域两个像素的平均。平均是线性的操作,因为每个新的像素都是旧像素的线性组合。


      对卷积,也有必须要考虑的情况是,在图像边界的时候,怎么办?J(1)的值应该是什么?它取决于I(0),I(1)和I(2)。但是我们没有I(0)呀!图像左边没有值了。有四种方式来处理这个问题:

      1)第一种就是想象I是无限长的图像的一部分,除了我们给定值的部分,其他部分的像素值都是0。在这种情况下,I(0)=0。所以J(1) = (I(0) + I(1) + I(2))/3 =(0 + 5 + 4)/3= 3. 同样,J(10) =(I(9)+I(10)+I(11))/3 = (3+ 6 + 0)/3 = 3.


      2)第二种方法也是想象I是无限图像的一部分。但没有指定的部分是用图像边界的值进行拓展。在我们的例子中,因为图像I最左边的值I(1)=5,所以它左边的所有值,我们都认为是5 。而图像右边的所有的值,我们都认为和右边界的值I(10)一样,都是6。这时候J(1) = (I(0) + I(1) + I(2))/3 =(5 + 5 + 4)/3= 14/3. 而J(10) =(I(9)+I(10)+I(11))/3 = (3 + 6 + 6)/3 = 5。


      3)第三种情况就是认为图像是周期性的。也就是I不断的重复。周期就是I的长度。在我们这里,I(0)和I(10)的值就是一样的,I(11)的值和I(1)的值也是一样的。所以J(1) = (I(0) + I(1) + I(2))/3= (I(10) + I(1)+ I(2))/3 = (6 + 5 +4)/3 = 5 。


      4)最后一种情况就是不管其他地方了。我们觉得I之外的情况是没有定义的,所以没办法使用这些没有定义的值,所以要使用图像I没有定义的值的像素都没办法计算。在这里,J(1)和J(10)都没办法计算,所以输出J会比原图像I要小。

      这四种方法有各自的优缺点。如果我们想象我们使用的图像只是世界的一个小窗口,然后我们需要使用窗口边界外的值,那么一般来说,外面的值和边界上的值是几乎相似的,所以第二种方法可能更说得过去。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值