精华内容
下载资源
问答
  • 图像卷积

    千次阅读 2018-11-14 16:07:10
    图像卷积概念 图像卷积数学公式 图像卷积注意事项 图像卷积算法实现 图像卷积概念 参考: Convolution Kernel (image processing) 图像卷积操作(convolution),或称为核操作(kernel),是进行图像处理的一种...

    这几天在进行其它运算时突然发觉自己对于卷积的概念和运算有一些陌生,重新复习一下。


    目录

    1. 图像卷积概念
    2. 图像卷积数学公式
    3. 图像卷积注意事项
    4. 图像卷积算法实现

    图像卷积概念

    参考:

    Convolution

    Kernel (image processing)

    图像卷积操作(convolution),或称为核操作(kernel),是进行图像处理的一种常用手段,

    图像卷积操作的目的是利用像素点和其邻域像素之前的空间关系,通过加权求和的操作,实现模糊(blurring),锐化(sharpening),边缘检测(edge detection)等功能。

    图像卷积的计算过程就是卷积核按步长对图像局部像素块进行加权求和的过程。

    卷积核实质上是一个固定大小的权重数组,该数组中的锚点通常位于中心。

    卷积核大小

    通常情况下,选取卷积核大小为1x1,3x3,5x5,7x7

    取奇数大小的目的是为了设置卷积核中心为锚点,方便卷积核和图像的对齐处理

    设置卷积核大小对称的目的是为了在空间域中充分利用像素点和其领域像素间的关系。当然这不是必须的,如果需要针对某一轴进行处理,可以设置1x33x1大小。


    图像卷积数学公式

    二维离散卷积公式如下:

    h[x,y]=f[x,y]g[x,y]=n1=n2=f(n1,n2)g(xn1,yn2)h[x,y]=f[x,y]\ast g[x,y]=\sum_{n_{1}=-\infty}^{\infty}\sum_{n_{2}=-\infty}^{\infty}f(n_1, n_2)\cdot g(x-n_{1},y-n_{2})

    图像卷积通常使用这个公式,其中g[x,y]g[x,y]为卷积核,符号\ast表示卷积操作

    图形化表示

    以一维离散卷积公式为例:

    y(t)=(fg)(t)=τ=f(τ)g(tτ)dτy(t)=(f\ast g)(t)=\sum_{\tau =-\infty}^{\infty}f(\tau )g(t-\tau )d\tau

    其图形化公式如下:

    在这里插入图片描述

    • 首先将函数g(τ)g(\tau)反射为g(τ)g(-\tau),相当于g(τ)g(\tau)沿yy轴翻转
    • 再对函数g(τ)g(-\tau)添加一个时间偏移量tt,它允许函数g(tτ)g(t-\tau)沿着τ\tau轴移动
    • 变量tt每增加1,表示函数g(tτ)g(t-\tau)向左移动一步
    • 计算t遍历-\infty\infty的过程中,函数f(τ)f(\tau)g(tτ)g(t-\tau)的重叠面积

    举例

    函数f=[1,2,3,4]f=[1, 2, 3, 4],函数g=[1,3,2]g=[1, 3, 2]

    将函数gg逆转:g(τ)g(τ)g(\tau)\Rightarrow g(-\tau),值变为[2,3,1][2, 3, 1]

    计算过程如下:

    h(0)=[1][1]=11=1h(0)=[1]\cdot [1]=1\cdot 1=1
    h(1)=[1,2][3,1]=13+21=3+2=5h(1)=[1,2]\cdot [3,1]=1\cdot 3+2\cdot 1=3+2=5
    h(2)=[1,2,3][2,3,1]=12+23+31=2+6+3=11h(2)=[1,2,3]\cdot [2,3,1]=1\cdot 2 +2\cdot 3+3\cdot 1=2+6+3=11
    h(3)=[2,3,4][2,3,1]=22+33+41=4+9+4=17h(3)=[2,3,4]\cdot [2,3,1]=2\cdot 2+3\cdot 3+4\cdot 1=4+9+4=17
    h(4)=[3,4][2,3]=32+43=6+12=18h(4)=[3,4]\cdot [2,3]=3\cdot 2+4\cdot 3=6+12=18
    h(5)=[4][2]=42=8h(5)=[4]\cdot [2]=4\cdot 2=8
    h(x)=[1,5,11,17,18,8]h(x)=[1, 5, 11, 17, 18, 8]

    以此类推可知二维离散卷积的计算过程,先对角翻转卷积核,在逐步向两个正方向移动,计算重叠面积

    • flip the mask (horizontally and vertically) only once(水平和垂直翻转掩模一次)
    • slide the mask onto the image(在图像上滑动掩模)
    • multiply the corresponding elements and then add them(将相应的元素相乘,然后求和)
    • repeat this procedure until all values of the image has been calculated(重复这一过程,直到所有图像值均已被计算)

    多说一句,关于信号与系统中的LTIlinear time-invariant systems,线性时不变系统)和LSIlinear shift invariant system,线性位移不变系统)的不变性一直没太理解,图形化理解就是信号(函数)可以随着时间/空间移动而不改变它的原先的形状,就像卷积核一样。

    卷积核为啥要翻转?

    参考:

    在定义卷积时为什么要对其中一个函数进行翻转?

    如何通俗易懂地解释卷积?

    LTILSI中,信号在时间和空间中移动不改变其特性,不断有信号随时间移动和系统产生响应,某一时刻的输出(即卷积输出)不仅包括当前信号的响应,还有之前信号的残留,所以是累加的,转换卷积核是为了计算这一过程。

    如何翻转?

    参考:卷积核翻转方法

    在计算之前需要对卷积核进行180180^{^{\circ}}翻转

    [123456789]180[987654331]\begin{bmatrix} 1& 2& 3\\ 4& 5& 6\\ 7& 8& 9 \end{bmatrix}\frac{180^{^{\circ}}}{\Rightarrow} \begin{bmatrix} 9& 8& 7\\ 6& 5& 4\\ 3& 3& 1 \end{bmatrix}

    可以先通过水平翻转,再进行垂直翻转,就能实现180180^{^{\circ}}翻转

    [123456789][321654987][987654321]\begin{bmatrix} 1& 2& 3\\ 4& 5& 6\\ 7& 8& 9 \end{bmatrix}\Rightarrow \begin{bmatrix} 3& 2& 1\\ 6& 5& 4\\ 9& 8& 7 \end{bmatrix}\Rightarrow \begin{bmatrix} 9& 8& 7\\ 6& 5& 4\\ 3& 2& 1 \end{bmatrix}

    卷积结果大小

    由一维离散卷积公式可知,设函数ff大小为AA,函数gg大小为BB,那么卷积结果大小为A+B1A+B-1

    对于二维离散卷积公式,设函数ff大小为[A,B][A,B],函数gg大小为[C,D][C,D],那么结果卷积大小为[(A+C1),(B+D1)][(A+C-1), (B+D-1)]

    对于图像卷积而言,输出图像与输入图像大小一致,因此需要舍弃卷积核锚点(图像中心)不与图像像素点重叠时的计算

    边界填充方式

    对图像卷积而言,当卷积核在图像边界计算时,会发生超出图像边界的情况,有几种方式来填充:

    1. 扩展(extend):扩展最近邻的像素点,即扩展图像边界
    2. 环绕(wrap):假设图像是首尾相接的,即使用图像相反方向的像素值
    3. 镜像(mirror):超出边界多少个像素,就向图像内部读取对应位置的像素
    4. 固定值:超出图像边界的像素取固定值,默认为0

    卷积操作和傅里叶变换

    参考:Convolution Theorem

    • 在空间域执行卷积操作,相当于在频率域执行滤波操作(乘法操作)
    • 在频率域执行卷积操作,相当于在空间域执行滤波操作(乘法操作)

    公式如下:

    fg=DFT(f)DFT(g)f\ast g=DFT(f)\cdot DFT(g)
    DFT(f)DFT(g)=fgDFT(f)\ast DFT(g)=f\cdot g


    图像卷积注意事项

    在进行卷积操作时,需要注意两点

    卷积核归一化

    卷积核的大小和值可以根据要求定义,但通常会将整个卷积核进行归一化操作,其目的是为了保证修改后结果图像的平均元素值和原始图像平均元素值一样。

    因为卷积操作满足齐次性,所以可以卷积计算完成后再除以整个卷积核的值。

    数值精度

    图像数值类型通常为uint8,在进行卷积操作时很容易造成数值溢出,所以在进行操作之前可以先转换成更高精度的数值类型


    图像卷积算法实现

    参考:

    Signal processing (scipy.signal) Convolution

    Multi-dimensional image processing (scipy.ndimage)

    Python有多个包(Numpy/Scipy/OpenCV)提供了卷积操作

    Numpy

    numpy.convolve

    Numpy包提供了方法convolve,用于计算一维线性卷积

    它提供了3种模式:

    • full:默认方式,计算所有重叠的面积
    • same:返回和最大数组一样长度的数组。从卷积核锚点位置开始计算
    • valid:仅计算完全重叠的面积

    实现结果如下:

    import numpy as np
    
    a = np.array([1, 2, 3, 4])
    v = np.array([1, 3, 2])
    full = np.convolve(a, v)
    same = np.convolve(a, v, 'same')
    valid = np.convolve(a, v, 'valid')
    
    [ 1  5 11 17 18  8]
    [ 5 11 17 18]
    [11 17]
    

    Scipy.signal

    scipy.signal包提供了好几种方法来计算卷积:

    convolve(in1, in2[, mode, method]) 
    correlate(in1, in2[, mode, method]) 	
    fftconvolve(in1, in2[, mode]) 
    convolve2d(in1, in2[, mode, boundary, fillvalue]) 	
    correlate2d(in1, in2[, mode, boundary, …]) 	
    sepfir2d(input, hrow, hcol) 
    choose_conv_method(in1, in2[, mode, measure])
    

    signal.convolve2d()

    参考:

    scipy.signal.convolve2d

    convolve2d(in1, in2, mode='full', boundary='fill', fillvalue=0)
    

    in1in2的维数大小相同

    参数mode决定了返回卷积结果的大小:

    • full:输出全离散线性卷积(默认)
    • valid:输出不依赖于零填充的卷积结果
    • same:输出大小和in1一样,卷积核锚点对齐图像处理的结果

    它额外提供了边界填充模式boundary和填充值fillvalue

    3种填充模式:

    1. fill:默认方式,使用fillvalue的值进行填充
    2. wrap:环形填充
    3. symm:镜像模式

    signal.convolve()

    参考:scipy.signal.convolve

    convolve(in1, in2, mode='full', method='auto')
    

    convolve用于计算N维数组的卷积,除了可以设定模式外,还可以选择计算方法:

    1. direct:直接按照卷积的定义进行加权求和计算
    2. fft:使用快速傅里叶变换(fft)进行卷积操作
    3. auto:默认方式,估计计算时间,选择直接计算还是快速傅里叶方法

    Signal.ndimage

    signal.ndiamge包提供了多个卷积函数:

    convolve(input, weights[, output, mode, …]) 
    convolve1d(input, weights[, axis, output, …])
    correlate(input, weights[, output, mode, …]) 
    correlate1d(input, weights[, axis, output, …])
    

    OpenCV

    参考:

    Making your own linear filters!

    filter2D()

    BorderTypes

    Depth combinations

    OpenCV提供了一个2维滤波器filter2D

    def filter2D(src, ddepth, kernel, dst=None, anchor=None, delta=None, borderType=None)
    
    src:输入图像
    dst:相同大小和通道的结果图像
    ddepth:结果图像深度,看Depth combinations
    kernel:卷积核,一个单通道浮点矩阵
    anchor:卷积核锚点位置,默认值(-1,-1),表示在核中心
    delta:额外值
    borderType:边界填充像素方式,参考BorderTypes
    

    比如实现一个Sobel算子,计算x轴梯度

    import cv2 as cv
    import numpy as np
    import matplotlib.pyplot as plt
    
    def realize_sobel():
        gray = cv.imread("lena.jpg", 0)
        ddepth = cv.CV_16S
    
        kernel = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]], dtype=np.float)
        res_x = cv.filter2D(gray, ddepth, kernel)
        abs_res_x = cv.convertScaleAbs(res_x)
    
        sobel_x = cv.Sobel(gray, ddepth, 1, 0, ksize=3)
        abs_sobel_x = cv.convertScaleAbs(sobel_x)
    
        plt.figure(figsize=(10, 5))  # 设置窗口大小
        plt.suptitle('sobel')  # 图片名称
        plt.subplot(1, 2, 1)
        plt.title('filter2D_x')
        plt.imshow(abs_res_x, cmap='gray'), plt.axis('off')
        plt.subplot(1, 2, 2)
        plt.title('sobel_x')
        plt.imshow(abs_sobel_x, cmap='gray'), plt.axis('off')
        plt.savefig('./sobel_x.png')  # 保存图像
        plt.show()
    

    在这里插入图片描述

    展开全文
  • c++图像卷积操作

    2018-11-15 12:14:53
    c++实现图像卷积操作,参数为(输入图像,输出图像),卷积核内部自己更改
  • 图像卷积与滤波的一些知识点

    万次阅读 多人点赞 2015-10-12 21:24:06
    图像卷积与滤波的一些知识点zouxy09@qq.comhttp://blog.csdn.net/zouxy09 之前在学习CNN的时候,有对卷积经常一些学习和整理,后来就烂尾了,现在稍微整理下,先放上来,以提醒和交流。一、线性滤波与卷积的基本...

    图像卷积与滤波的一些知识点

    zouxy09@qq.com

    http://blog.csdn.net/zouxy09

     

          之前在学习CNN的时候,有对卷积进行一些学习和整理,后来就烂尾了,现在稍微整理下,先放上来,以提醒和交流。

    一、线性滤波与卷积的基本概念

          线性滤波可以说是图像处理最基本的方法,它可以允许我们对图像进行处理,产生很多不同的效果。做法很简单。首先,我们有一个二维的滤波器矩阵(有个高大上的名字叫卷积核)和一个要处理的二维图像。然后,对于图像的每一个像素点,计算它的邻域像素和滤波器矩阵的对应元素的乘积,然后加起来,作为该像素位置的值。这样就完成了滤波过程。

          对图像和滤波矩阵进行逐个元素相乘再求和的操作就相当于将一个二维的函数移动到另一个二维函数的所有位置,这个操作就叫卷积或者协相关。卷积和协相关的差别是,卷积需要先对滤波矩阵进行180的翻转,但如果矩阵是对称的,那么两者就没有什么差别了。

          Correlation 和 Convolution可以说是图像处理最基本的操作,但却非常有用。这两个操作有两个非常关键的特点:它们是线性的,而且具有平移不变性shift-invariant。平移不变性指我们在图像的每个位置都执行相同的操作。线性指这个操作是线性的,也就是我们用每个像素的邻域的线性组合来代替这个像素。这两个属性使得这个操作非常简单,因为线性操作是最简单的,然后在所有地方都做同样的操作就更简单了。

          实际上,在信号处理领域,卷积有广泛的意义,而且有其严格的数学定义,但在这里不关注这个。

          2D卷积需要4个嵌套循环4-double loop,所以它并不快,除非我们使用很小的卷积核。这里一般使用3x3或者5x5。而且,对于滤波器,也有一定的规则要求:

          1)滤波器的大小应该是奇数,这样它才有一个中心,例如3x3,5x5或者7x7。有中心了,也有了半径的称呼,例如5x5大小的核的半径就是2。

          2)滤波器矩阵所有的元素之和应该要等于1,这是为了保证滤波前后图像的亮度保持不变。当然了,这不是硬性要求了。

          3)如果滤波器矩阵所有元素之和大于1,那么滤波后的图像就会比原图像更亮,反之,如果小于1,那么得到的图像就会变暗。如果和为0,图像不会变黑,但也会非常暗。

          4)对于滤波后的结构,可能会出现负数或者大于255的数值。对这种情况,我们将他们直接截断到0和255之间即可。对于负数,也可以取绝对值。

    二、神奇的卷积核

          上面说到,对图像的滤波处理就是对图像应用一个小小的卷积核,那这个小小的卷积核到底有哪些魔法,能让一个图像从惨不忍睹变得秀色可餐。下面我们一起来领略下一些简单但不简单的卷积核的魔法。

    2.1、啥也不做

          哈哈,大家可以看到啥了吗?这个滤波器啥也没有做,得到的图像和原图是一样的。因为只有中心点的值是1。邻域点的权值都是0,对滤波后的取值没有任何影响。

          下面我们动点真格的。

    2.2、图像锐化滤波器Sharpness Filter

          图像的锐化和边缘检测很像,首先找到边缘,然后把边缘加到原来的图像上面,这样就强化了图像的边缘,使图像看起来更加锐利了。这两者操作统一起来就是锐化滤波器了,也就是在边缘检测滤波器的基础上,再在中心的位置加1,这样滤波后的图像就会和原始的图像具有同样的亮度了,但是会更加锐利。

          我们把核加大,就可以得到更加精细的锐化效果

          另外,下面的滤波器会更强调边缘:

          主要是强调图像的细节。最简单的3x3的锐化滤波器如下:

          实际上是计算当前点和周围点的差别,然后将这个差别加到原来的位置上。另外,中间点的权值要比所有的权值和大于1,意味着这个像素要保持原来的值。

    2.3、边缘检测Edge Detection

          我们要找水平的边缘:需要注意的是,这里矩阵的元素和是0,所以滤波后的图像会很暗,只有边缘的地方是有亮度的。

          为什么这个滤波器可以寻找到水平边缘呢?因为用这个滤波器卷积相当于求导的离散版本:你将当前的像素值减去前一个像素值,这样你就可以得到这个函数在这两个位置的差别或者斜率。下面的滤波器可以找到垂直方向的边缘,这里像素上和下的像素值都使用:

          再下面这个滤波器可以找到45度的边缘:取-2不为了什么,只是为了让矩阵的元素和为0而已。

          那下面这个滤波器就可以检测所有方向的边缘:

          为了检测边缘,我们需要在图像对应的方向计算梯度。用下面的卷积核来卷积图像,就可以了。但在实际中,这种简单的方法会把噪声也放大了。另外,需要注意的是,矩阵所有的值加起来要是0.

    2.4、浮雕Embossing Filter

          浮雕滤波器可以给图像一种3D阴影的效果。只要将中心一边的像素减去另一边的像素就可以了。这时候,像素值有可能是负数,我们将负数当成阴影,将正数当成光,然后我们对结果图像加上128的偏移。这时候,图像大部分就变成灰色了。

          下面是45度的浮雕滤波器

          我们只要加大滤波器,就可以得到更加夸张的效果了

          这种效果非常的漂亮,就像是将一副图像雕刻在一块石头上面一样,然后从一个方向照亮它。它和前面的滤波器不同,它是非对称的。另外,它会产生负数值,所以我们需要将结果偏移,以得到图像灰度的范围。

          A:原图像。B:锐化。C:边缘检测。D:浮雕

    2.5、均值模糊Box Filter (Averaging)

          我们可以将当前像素和它的四邻域的像素一起取平均,然后再除以5,或者直接在滤波器的5个地方取0.2的值即可,如下图:

          可以看到,这个模糊还是比较温柔的,我们可以把滤波器变大,这样就会变得粗暴了:注意要将和再除以13.

          所以,如果你想要更模糊的效果,加大滤波器的大小即可。或者对图像应用多次模糊也可以。


    2.6、高斯模糊

          均值模糊很简单,但不是很平滑。高斯模糊就有这个优点,所以被广泛用在图像降噪上。特别是在边缘检测之前,都会用来移除细节。高斯滤波器是一个低通滤波器。


    2.7、运动模糊Motion Blur

          运动模糊可以通过只在一个方向模糊达到,例如下面9x9的运动模糊滤波器。注意,求和结果要除以9。

          这个效果就好像,摄像机是从左上角移动的右下角。

    三、卷积的计算

          对图像处理而言,存在两大类的方法:空域处理和频域处理!空域处理是指直接对原始的像素空间进行计算,频率处理是指先对图像变换到频域,再做滤波等处理。

    3.1、空域计算-直接2D卷积

    3.1.1、2D卷积

          直接2D卷积就是一开始说的那样,对于图像的每一个像素点,计算它的邻域像素和滤波器矩阵的对应元素的乘积,然后加起来,作为该像素位置的值。

          直接的实现也称为暴力实现brute force,因为它严格按照定义来实现,没有任何优化。当然了,在并行实现里面,它也是比较灵活的。另外,也存在一个优化版本,如果我们的kernel是separable可分的,那么就可以得到一个快5倍左右的卷积方法。

    2.1.2、边界处理

          那卷积核遇到图像边缘怎么办?例如图像顶部的像素,它的上面已经没有像素了,那么它的值如何计算?目前有四种主流的处理方法,我们用一维卷积和均值滤波来说明下。

          我们在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要小。

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

    2.2、频域计算-快速傅里叶变换FFT卷积

          这个快速实现得益于卷积定理:时域上的卷积等于频域上的乘积。所以将我们的图像和滤波器通过算法变换到频域后,直接将他们相乘,然后再变换回时域(也就是图像的空域)就可以了。

          o表示矩阵逐元素相乘。那用什么方法将空域的图像和滤波器变换到频域了。那就是鼎鼎大名的Fast Fourier Transformation 快速傅里叶变换FFT(其实,在CUDA里面,已经实现了FFT了)。

          要在频域中对一副图像进行滤波,滤波器的大小和图像的大小必须要匹配,这样两者的相乘才容易。因为一般滤波器的大小比图像要小,所以我们需要拓展我们的kernel,让它和图像的大小一致。

          因为CUDA中的FFT实现是周期的,所以kernel的值也要安排成这样,以支持这种周期性。

          为了保证图像边界的像素也可以得到响应输出,我们也需要拓展我们的输入图像。同时,拓展的方式也要支持周期表达。

          如果只是使用卷积定理,没有对输入进行任何修改的话,那么我们得到的是周期卷积的结果。但这可能不是我们要的,因为周期卷积会对输入数据进行周期填补,引入一些artifacts。

          给定N长度的I和K,为了得到线性卷积,我们需要对I和K进行zero padding。为什么要补0,因为DFT假定了输入是无限和周期的,周期是N。 

          如上图,对于I和K,如果没有padding的话,隐含着会假定I和K是周期的,以他们的长度N为周期。图中本来N长度的I和K都是黑色虚线的部分,然后如果没有padding,隐含着就会在N之外,加上同样的无数个I,如红色虚线部分,加上了一个周期。对K也是这样。如果是zero padding的话,在黑色虚线的其他地方都全是0了,如图中蓝色部分。将I和K卷积,如果没有padding,如黑色虚线,会有红色那部分的artifact。如果有padding,就是蓝色实线。

     四、实验代码

          这是第二部分的Matlab实验代码:

    clear,close all, clc
     
    %% readimage
    image =imread('test.jpg');
     
    %% definefilter
    % -----Identity filter -----
    kernel =[0, 0, 0
                         0, 1, 0
                         0, 0, 0];
     
    % -----Average Blur -----
    kernel =[0, 1, 0
                         1, 1, 1
                         0, 1, 0] / 5;
     
    % -----Gaussian Blur -----
    kernel =fspecial('gaussian', 5 , 0.8);
     
    % -----Motion Blur -----
    kernel =[1, 0, 0, 0, 0
                         0, 1, 0, 0, 0
                         0, 0, 1, 0, 0
                         0, 0, 0, 1, 0
                         0, 0, 0, 0, 1] / 5;
                        
    % -----Edges Detection -----
    kernel =[-1, -1, -1
                         -1, 8, -1
                         -1, -1, -1];
     
    % -----Sharpen filter -----
    kernel =[-1, -1, -1
                         -1, 9, -1
                         -1, -1, -1];
                        
    % -----Emboss filter -----
    kernel =[-1, -1, 0
                         -1,  0,1
                         0,   1,1];
                        
    %% convolethe image with defined kernel or filter
    result =zeros(size(image));
    result(:,:, 1) = conv2(double(image(:, :, 1)), double(kernel), 'same');
    result(:,:, 2) = conv2(double(image(:, :, 2)), double(kernel), 'same');
    result(:,:, 3) = conv2(double(image(:, :, 3)), double(kernel), 'same');
     
    %% showthe result
    imshow(image);
    figure
    imshow(uint8(result))

    五、参考文献

    [1] Correlation and Convolution.pdf

    [2] Lode's Computer GraphicsTutorial Image Filtering


    展开全文
  • python scipy卷积 图像卷积

    千次阅读 2017-10-06 00:03:00
    python scipy卷积 图像卷积

    python学习笔记 26:scipy卷积运算

    原文:http://blog.csdn.net/shu15121856/article/details/76285479

    scipy的signal模块经常用于信号处理,卷积、傅里叶变换、各种滤波、差值算法等。 
    *两个一维信号卷积

    数组卷积的例子:

    import scipy.signal
    import numpy as np
    x=np.array([1,2,3,4])
    h=np.array([1,1,1])
    
    bb= scipy.signal.convolve(x,h) #卷积运算
    print(bb)

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    卷积运算大致可以分成3步,首先先翻转,让两个信号列反过来,如上面就是1,2,3和6,5,4。然后作平移,6,5,4最开始在1,2,3的左边,没有重叠,现在向右移动,4和1就重叠了。对于重叠的部分,作乘积求和。也就是1x4得到第一个结果1,然后再移动后5x1+4x2得到第二个结果13以此类推。 
    卷积运算可以用来做大整数的乘法(数组表示数的乘法),比如在上面的例子中,要求123乘以456,可以先得到它的卷积序列,然后从后往前,18将8保留,进位1给27;然后27变成28,把8保留进位2给28;然后28变成30,把0保留进位3给13;然后13变成16,把6保留进位1给4;4变成5即是最高位。也就是乘法的结果是56088。

    *对白噪声卷积

    import numpy as np
    from scipy import signal
    import matplotlib.pyplot as plt
    sig=np.random.randn(1000) #生成随机数
    autocorr=signal.fftconvolve(sig,sig[::-1],mode='full') #fft算法实现卷积
    fig,(ax_orig,ax_mag)=plt.subplots(2,1) #建立两行一列图形
    ax_orig.plot(sig) #在第一行把原始的随机数序列sig画出来
    # [<matplotlib.lines.Line2D object at 0x0000000006E1DC88>]
    ax_orig.set_title('White noise') #设置标题'白噪声'
    # <matplotlib.text.Text object at 0x0000000006931860>
    ax_mag.plot(np.arange(-len(sig)+1,len(sig)),autocorr) #卷积后的图像
    # [<matplotlib.lines.Line2D object at 0x0000000006E1DB00>]
    ax_mag.set_title('Autocorrelation') #设置标题
    # <matplotlib.text.Text object at 0x0000000006DFE8D0>
    fig.tight_layout() #此句可以防止图像重叠
    # fig.show() #显示图
    plt.show()

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    fftconvolve只是用fft算法(快速傅立叶变换)实现的卷积,其结果应当和普通的convolve一样。 
    这里写图片描述

    *二维图像卷积运算

    >>> import numpy as np
    >>> from scipy import signal
    >>> from scipy import misc
    >>> import matplotlib.pyplot as plt
    >>> face=misc.face(gray=True) #创建一个灰度图像
    >>> scharr=np.array([[-3-3j,0-10j,+3-3j],
            [-10+0j,0+0j,+10+0j],
             [-3+3j,0+10j,+3+3j]]) #设置一个特殊的卷积和
    >>> grad=signal.convolve2d(face,scharr,boundary='symm',mode='same') #把图像的face数组和设计好的卷积和作二维卷积运算,设计边界处理方式为symm
    >>> fig,(ax1,ax2)=plt.subplots(1,2,figsize=(10,6)) #建立1行2列的图fig
    >>> ax1.imshow(face,cmap='gray') #显示原始的图
    <matplotlib.image.AxesImage object at 0x00000000078FC198>
    >>> ax1.set_axis_off() #不显示坐标轴
    >>> ax2.imshow(np.absolute(grad),cmap='gray') #显示卷积后的图
    <matplotlib.image.AxesImage object at 0x00000000078FCE48>
    >>> ax2.set_axis_off() #不显示坐标轴
    >>> fig.show() #显示绘制好的画布
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    二维的卷积需要用上面的signal.convolve2d()。 
    之所以要对卷积后的图像数组grad作np.absolute()求绝对值运算是因为灰度图像的值都是正值,没有负的,为了防止出现负值所以才这样做。 
    这里写图片描述
    二维的卷积运算还有一种函数,是signal.sepfir2d(),它可以传入三个参数,后两个参数指定行和列的卷积和(两个方向上的卷积是可以不同的,分别指定卷积和序列)。


    展开全文
  • 图像卷积与反卷积

    2020-02-25 14:18:53
    一、图像卷积类型  在2维图像卷积计算中,大致分为full、same和valid这三类。  1、valid卷积操作    图1 valid卷积操作  valid卷积的图像大小计算公式为:滑动步长为S,图片大小为N1x...

    声明:本文章为转载文章,原文网址:https://www.cnblogs.com/raorao1994/p/9485814.html

    一、图像卷积类型

      在2维图像卷积计算中,大致分为full、same和valid这三类。

      1、valid卷积操作

      

                图1 valid卷积操作

      valid卷积的图像大小计算公式为:滑动步长为S,图片大小为N1xN1,卷积核大小为N2xN2,卷积后图像大小:((N1-N2)/S+1)x( (N1-N2)/S+1)

      如图1,滑动步长为1,图片大小为5x5,卷积核大小为3x3,卷积后图像大小:3x3

      2、same卷积操作

      

     

            图2 same卷积操作

      .same卷积的图像大小计算公式为: 滑动步长为1,图片大小为N1xN1,卷积核大小为N2xN2,卷积后图像大小:N1xN1

      same卷积会自动补全图像,使得输入输出图像保证相同大小的输出。

      3、full卷积操作

      

            图3 same卷积操作

      

      valid卷积的图像大小计算公式为:滑动步长为S,图片大小为N1xN1,卷积核大小为N2xN2,卷积后图像大小:(N1-N2)/S+1 x (N1-N2)/S+1
      如图3,滑动步长为1,图片大小为5x5,卷积核大小为3x3,卷积后图像大小:3x3
     
    二、反卷积
      
          图4 反卷积
        假设原图是3X3,首先使用上采样让图像变成7X7,可以看到图像多了很多空白的像素点。使用一个3X3的卷积核对图像进行滑动步长为1的valid卷积,得到一个5X5的图像,我们知道的是使用上采样扩大图片,使用反卷积填充图像内容,使得图像内容变得丰富,这也是CNN输出end to end结果的一种方法。
      目前使用得最多的deconvolution有2种,上文都已经介绍。 
      方法1:full卷积, 完整的卷积可以使得原来的定义域变大
      方法2:记录pooling index,然后扩大空间,再用卷积填充
      图像的deconvolution过程如下,

      输入:2x2, 卷积核:4x4, 滑动步长:3, 输出:7x7
      即输入为2x2的图片经过4x4的卷积核进行步长为3的反卷积的过程
      1.输入图片每个像素进行一次full卷积,根据full卷积大小计算可以知道每个像素的卷积后大小为 1+4-1=4, 即4x4大小的特征图,输入有4个像素所以4个4x4的特征图
      2.将4个特征图进行步长为3的fusion(即相加); 例如红色的特征图仍然是在原来输入位置(左上角),绿色还是在原来的位置(右上角),步长为3是指每隔3个像素进行fusion,重叠部分进行相加,即输出的第1行第4列是由红色特阵图的第一行第四列与绿色特征图的第一行第一列相加得到,其他如此类推。

      可以看出翻卷积的大小是由卷积核大小与滑动步长决定, in是输入大小, k是卷积核大小, s是滑动步长, out是输出大小
      得到 out = (in - 1) * s + k
      上图过程就是, (2 - 1) * 3 + 4 = 7
     
    展开全文
  • 1.前言 传统的CNN网络只能给出图像的LABLE,但是在很多情况下需要对识别的物体进行分割实现end to end,然后FCN出现了,给物体分割提供了一个非常重要的...2.图像卷积 图二 同样地,卷积的时候需要对卷积核进行180的.
  • 图像卷积与图像相关

    千次阅读 2017-02-22 19:31:07
    图像卷积与图像相关
  • 什么是图像卷积

    千次阅读 2020-03-08 12:26:44
    3 图像卷积是什么 4 图像卷积的一些应用 文章由我们熟悉的一维连续时间信号的卷积逐渐过渡到图像卷积。文章是循序渐进的,希望想要了解的朋友们可以耐心读一读。本人理解有限,如有错误还请指出 (1)先看连续时间...
  • LeNet3D + tfrecords 3D卷积样例 tf.nn.conv3d (立体图像卷积 3D 医疗图像卷积 (CT, fMRI)) #!/usr/bin/env python # coding: utf-8 # In[1]: import numpy as np import os os.environ["CUDA_VISIBLE_DEVICES"] ...
  • 理解图像卷积操作的意义

    万次阅读 多人点赞 2017-05-16 22:40:04
    数字信号处理中卷积 卷积一词最开始出现在信号与线性系统中,信号与线性系统中讨论的就是信号经过一个线性系统以后发生的变化。由于现实情况中常常是一个信号前一时刻的输出影响着这一时刻的输出,所在一般利用系统...
  • 深度学习---图像卷积与反卷积(最完美的解释)

    万次阅读 多人点赞 2018-05-31 10:57:28
    转自:卷积神经网络CNN(1)——图像卷积与反卷积(后卷积,转置卷积)1.前言 传统的CNN网络只能给出图像的LABLE,但是在很多情况下需要对识别的物体进行分割实现end to end,然后FCN出现了,给物体分割提供了一个...
  • RGB图像卷积

    千次阅读 2018-07-14 10:23:35
    如图所示,RGB图像卷积,三个通道依次卷积,然后将三个通道的结果相加,
  • 图像卷积的秘密

    2019-04-18 22:15:00
    首先,图像卷积核卷积操作时有区别的,图像卷积不改变图像的尺寸,但是类似深度学习里的卷积层是会改变图像的大小的。 高斯函数与图像卷积 假设高斯模糊稀疏为σ,根据3σ原则,使用NxN的模板在图像每一个像素点处...
  • 图像卷积的理解

    千次阅读 2017-11-01 13:37:39
    本博客谈谈对以下两个问题的理解: ... 先借助别人的博客,说明下图像卷积的操作:  1.1 图像卷积的操作方法:  数字图像是一个二维的离散信号,对数字图像做卷积操作其实就是利用卷积核(卷
  • 卷积神经网络CNN(1)——图像卷积与反卷积(后卷积,转置卷积)
  • 神经网络中的卷积层,它的原理就来源于图像卷积 概述 卷积在信号处理领域有极其广泛的应用, 也有严格的物理和数学定义. 本文只讨论卷积在数字图像处理中的应用. 在数字图像处理中, 有一种基本的处理方法:线性滤波...
  • 图像卷积与滤波

    2018-07-12 11:01:50
    转载:图像卷积与滤波的一些知识点
  • 图像卷积运算,主要是通过设定各种特征提取滤波器矩阵(卷积核,通常设定大小为3x3,或者5x5的矩阵),然后使用该卷积核在原图像矩阵(图像实际是像素值构成的矩阵)‘滑动’,实现卷积运算。如果对卷积运算还...
  • 数字图像卷积原理,matlab的conv2函数,不使用con2函数实现卷积 图像卷积原理 卷积,Convolution。卷积是两个变量在某范围内相乘后求和的结果。如果卷积的变量是序列x(n)和h(n),则卷积的结果为: 本文只讨论卷积...
  • 【深度学习】多通道图像卷积过程及计算方式

    万次阅读 多人点赞 2018-10-15 21:42:50
    之前,有写了一篇博文,【深度学习入门】——亲手实现图像卷积操作介绍卷积的相应知识,但那篇文章更多的是以滤波器的角度去讲解卷积。但实际上是神经网络中该博文内容并不适应。 之前的文章为了便于演示,针对的是...
  • 常用图像卷积核小结

    千次阅读 2020-05-09 10:25:07
    文章目录0. 前言1. 均值滤波和高斯滤波1.1 简介1.2 示例2. 锐化卷积核2.1 简介2.2 ...下面这张图片就很能说明图像卷积的基本原理了: CSDN上这篇博客对图像卷积的解释也很到位。在此先总结几个点: 卷积操作的主要
  • 图像卷积及Caffe中的卷积实现

    千次阅读 2016-02-03 20:07:30
    图像卷积及Caffe中的卷积实现  本文简单介绍了卷积、图像卷积以及Caffe中的卷积实现等相关知识,写作过程中参考了很多很赞的资料,有兴趣的读者可以从【参考资料】查看。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 20,111
精华内容 8,044
关键字:

图像卷积