2018-03-20 16:56:17 HXG2006 阅读数 14889
  • 深度学习之卷积神经网络CNN以及python案例图片中文本...

    卷积神经网络是深度学习技术中极具代表的网络结构之一,在图像处理领域取得了很大的成功。本课程将会讲解:CNN、卷基层、卷积计算、池化层、池化、全连接等概念。重点讲解如何进行卷积计算?如何进行池化计算?CNN如何训练以及优缺点?什么全连接和激励层?后python图片文本识别的案例。

    1634 人正在学习 去看看 王而川

转载:http://blog.csdn.net/chaipp0607/article/details/72236892

        https://www.zhihu.com/question/22298352

     在图像处理领域,我们经常能听到滤波,卷积之类的词,其实他们都可以看做一种图像的卷积操作,相对应的卷积核,卷积模板,滤波器,滤波模板,扫描窗其实也都是同一个东西。下面我们进一步讨论图像中的卷积操作核卷积的意义。

1、数字信号处理中卷积理解

    卷积一词最开始出现在信号与线性系统中,信号与线性系统中讨论的就是信号经过一个线性系统以后发生的变化。由于现实情况中常常是一个信号前一时刻的输出影响着这一时刻的输出,所在一般利用系统的单位响应与系统的输入求卷积,以求得系统的输出信号(当然要求这个系统是线性时不变的)。 
卷积的定义: 卷积是两个变量在某范围内相乘后求和的结果。如果卷积的变量是序列x(n)和h(n),则卷积的结果: 

                     这里写图片描述

作者:果程C
链接:https://www.zhihu.com/question/22298352/answer/50940942
来源:知乎

对于初学者,我推荐用复利的例子来理解卷积可能更好理解一些:

小明存入100元钱,年利率是5%,按复利计算(即将每一年所获利息加入本金,以计算下一年的利息),那么在五年之后他能拿到的钱数是100(1+5\%)^5,如下表所示:


将这笔钱存入银行的一年之后,小明又往银行中存入了100元钱,年利率仍为5%,那么这笔钱按复利计算,到了第五年,将收回的钱数是100(1+5\%)^4,我们将这一结果作为新的一行加入上面的表格中:

以此类推,如果小明每年都往银行中存入新的100元钱,那么这个收益表格将是这样的:
<img src="https://pic1.zhimg.com/50/cfe98b9d33640fae02a21bf369f0459d_hd.jpg" data-rawwidth="1296" data-rawheight="284" class="origin_image zh-lightbox-thumb" width="1296" data-original="https://pic1.zhimg.com/cfe98b9d33640fae02a21bf369f0459d_r.jpg">可见,最终小明拿到的钱将等于他各年存入的钱分别计算复利之后得到的钱数的总和,即:

用求和符号来简化这个公式,可以得到:
\sum_{i=0}^{5}{f(i)g(5-i)}, \mathrm{where} \ f(i)=100, g(5-i) = (1.05)^{5-i}
在上式中,f(i)为小明的存钱函数,而g(i)为存入银行的每一笔钱的复利计算函数在这里,小明最终得到的钱就是他的存钱函数和复利计算函数的卷积。
为了更清晰地看到这一点,我们将这个公式推广到连续的情况,也就是说,小明在从0t的这一段时间内,每时每刻都往银行里存钱,他的存钱函数为f(\tau)\ (0\leq \tau\leq t),而银行也对他存入的每一笔钱按复利公式计算收益:g(t-\tau)=(1+5\%)^{t-\tau},则小明到时间t将得到的总钱数为:
\int_{0}^{t} f(\tau)g(t-\tau)d\tau=\int_{0}^{t} f(\tau)(1+5\%)^{t-\tau}d\tau
这也就是卷积的表达式了,上式可以记为(f\ast g)(t)

相信通过上面这个例子,大家应该能够很清晰地记住卷积公式了。下面我们再展开说两句:
如果我们将小明的存款函数视为一个信号发生(也就是激励)的过程,而将复利函数g(t-\tau)视为一个系统对信号的响应函数(也就是响应),那么二者的卷积(f\ast g)(t)就可以看做是在t时刻对系统进行观察,得到的观察结果(也就是输出)将是过去产生的所有信号经过系统的「处理/响应」后得到的结果的叠加,这也就是卷积的物理意义了。


作者:鱼腻
链接:https://www.zhihu.com/question/22298352/answer/91131073
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

看了好多关于卷积的答案,看到这个例子才彻底地理解了这个过程~
关于卷积的一个血腥的讲解
比如说你的老板命令你干活,你却到楼下打台球去了,后来被老板发现,他非常气愤,扇了你一巴掌(注意,这就是输入信号,脉冲),于是你的脸上会渐渐地(贱贱地)鼓起来一个包,你的脸就是一个系统,而鼓起来的包就是你的脸对巴掌的响应,好,这样就和信号系统建立起来意义对应的联系。下面还需要一些假设来保证论证的严谨:假定你的脸是线性时不变系统,也就是说,无论什么时候老板打你一巴掌,打在你脸的同一位置(这似乎要求你的脸足够光滑,如果你说你长了很多青春痘,甚至整个脸皮处处连续处处不可导,那难度太大了,我就无话可说了哈哈),你的脸上总是会在相同的时间间隔内鼓起来一个相同高度的包来,并且假定以鼓起来的包的大小作为系统输出。好了,那么,下面可以进入核心内容——卷积了!

如果你每天都到地下去打台球,那么老板每天都要扇你一巴掌,不过当老板打你一巴掌后,你5分钟就消肿了,所以时间长了,你甚至就适应这种生活了……如果有一天,老板忍无可忍,以0.5秒的间隔开始不间断的扇你的过程,这样问题就来了,第一次扇你鼓起来的包还没消肿,第二个巴掌就来了,你脸上的包就可能鼓起来两倍高,老板不断扇你,脉冲不断作用在你脸上,效果不断叠加了,这样这些效果就可以求和了,结果就是你脸上的包的高度随时间变化的一个函数了(注意理解);如果老板再狠一点,频率越来越高,以至于你都辨别不清时间间隔了,那么,求和就变成积分了。可以这样理解,在这个过程中的某一固定的时刻,你的脸上的包的鼓起程度和什么有关呢?和之前每次打你都有关!但是各次的贡献是不一样的,越早打的巴掌,贡献越小,所以这就是说,某一时刻的输出是之前很多次输入乘以各自的衰减系数之后的叠加而形成某一点的输出,然后再把不同时刻的输出点放在一起,形成一个函数,这就是卷积,卷积之后的函数就是你脸上的包的大小随时间变化的函数。本来你的包几分钟就可以消肿,可是如果连续打,几个小时也消不了肿了,这难道不是一种平滑过程么?反映到剑桥大学的公式上,f(a)就是第a个巴掌,g(x-a)就是第a个巴掌在x时刻的作用程度,乘起来再叠加就ok了,大家说是不是这个道理呢?我想这个例子已经非常形象了,你对卷积有了更加具体深刻的了解了吗?

作者:Kaixiang Wang
链接:https://www.zhihu.com/question/22298352/answer/193852554
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

补充一下@镜面狐@笑劫戈的答案。

想要形象地理解卷积这个数学概念,那么思路当然是找它的“实际应用”,最容易想到的例子就是它对动态系统的输入输出关系的描述了。许多答主提到了“打脸”的例子,非常形象,就不复述了。

以下略纠结,嫌麻烦可以跳过直接看图。

之前我对@镜面狐答案的有部分理解是不准确的;现在看来他对 a 的定义确实有问题(感谢@高启峰@逐光指出)。顺便提一下,@镜面狐的答案引用了Franklin的那本经典教材,但是我越来越感觉它讲卷积的那部分并没有写得很清楚,比如它和配图和文字就对不上号,徒增了理解的难度。我尽量梳理一遍吧。

首先是单位脉冲\delta(t)和单位脉冲响应 h(t) 的定义,大家应该都懂我就不啰嗦了。(注意 \delta(t) 的“面积”为 1 。)再是定义 p_\Delta(t)h_\Delta(t) ,当 \Delta\rightarrow0 时趋近于 \delta(t)h(t) 。(同样注意 p_\Delta(t) 的高度为 \frac{1}{\Delta} ,面积为 1 。)

一个输入信号可以拆成很多 p_\Delta(t) 的和,即 u\left(t\right)\approx\cdots+u\left(0\right)p_{\Delta}\left(t\right)\Delta+u\left(\Delta\right)p_{\Delta}\left(t-\Delta\right)\Delta+u\left(2\Delta\right)p_{\Delta}\left(t-2\Delta\right)\Delta+\cdots (所以

@镜面狐的答案确实少了个 \Delta
输出即 y\left(t\right)\approx\cdots+u\left(0\right)h_{\Delta}\left(t\right)\Delta+u\left(\Delta\right)h_{\Delta}\left(t-\Delta\right)\Delta+u\left(2\Delta\right)h_{\Delta}\left(t-2\Delta\right)\Delta+\cdots

取极限写成积分形式即 y\left(t\right)=\int_{-\infty}^{\infty}u\left(\tau\right)h\left(t-\tau\right)d\tau

注意不要忘了 d\tau ,因为我们是要跟单位脉冲比较面积,即 u(\tau)d\tau1 的多少倍。


纠结部分完。

有了这个基础,再去理解卷积的公式就没那么intimidating了。放张图,心血来潮随手画的,但愿能顶个卵用。


另外,对于实际系统(因果系统),由于未来的打脸( \tau>t )不会造成现在的脸肿,所以积分上限设为 t 就行了;此外我们还一般假设 t=0 之前没人打脸并且脸也不肿,所以积分下限设为 0 就行了。因此y(t)=\int^t_0u(\tau)h(t-\tau)d\tau

2、数字图像处理中卷积

        数字图像是一个二维的离散信号,对数字图像做卷积操作其实就是利用卷积核(卷积模板)在图像上滑动,将图像点上的像素灰度值与对应的卷积核上的数值相乘,然后将所有相乘后的值相加作为卷积核中间像素对应的图像上像素的灰度值,并最终滑动完所有图像的过程。 




       这张图可以清晰的表征出整个卷积过程中一次相乘后相加的结果:该图片选用3*3的卷积核,卷积核内共有九个数值,所以图片右上角公式中一共有九行,而每一行都是图像像素值与卷积核上数值相乘,最终结果-8代替了原图像中对应位置处的1。这样沿着图片一步长为1滑动,每一个滑动后都一次相乘再相加的工作,我们就可以得到最终的输出结果。除此之外,卷积核的选择有一些规则: 
       1)卷积核的大小一般是奇数,这样的话它是按照中间的像素点中心对称的,所以卷积核一般都是3x3,5x5或者7x7。有中心了,也有了半径的称呼,例如5x5大小的核的半径就是2。 
       2)卷积核所有的元素之和一般要等于1,这是为了原始图像的能量(亮度)守恒。其实也有卷积核元素相加不为1的情况,下面就会说到。 
        3)如果滤波器矩阵所有元素之和大于1,那么滤波后的图像就会比原图像更亮,反之,如果小于1,那么得到的图像就会变暗。如果和为0,图像不会变黑,但也会非常暗。 
        4)对于滤波后的结构,可能会出现负数或者大于255的数值。对这种情况,我们将他们直接截断到0和255之间即可。对于负数,也可以取绝对值。

2.1边界补充问题

        上面的图片说明了图像的卷积操作,但是他也反映出一个问题,如上图,原始图片尺寸为7*7,卷积核的大小为3*3,当卷积核沿着图片滑动后只能滑动出一个5*5的图片出来,这就造成了卷积后的图片和卷积前的图片尺寸不一致,这显然不是我们想要的结果,所以为了避免这种情况,需要先对原始图片做边界填充处理。在上面的情况中,我们需要先把原始图像填充为9*9的尺寸。 
常用的区域填充方法包括: 
        图是我在word里面画的,所以有很多回车键哈,有些简陋,大家凑合看吧,意思还是对的,也是为了画图方便,这里就不用5*5的尺寸了,用3*3定义原始图像的尺寸,补充为9*9的尺寸,图片上的颜色只为方便观看,并没有任何其他含义。 

原始图像:


2.1.1补零 


2.2.2边界复制 


2.2.3镜像


2.2.4块复制


以上四种边界补充方法通过看名字和图片就能理解了,不在多做解释。

不同卷积核下卷积意义

我们经常能看到的,平滑,模糊,去燥,锐化,边缘提取等等工作,其实都可以通过卷积操作来完成,下面我们一一举例说明一下: 
(1)一个没有任何作用的卷积核: 
这里写图片描述 
将原像素中间像素值乘1,其余全部乘0,显然像素值不会发生任何变化。 
(2)平滑均值滤波: 
选择卷积核: 
这里写图片描述 
该卷积核的作用在于取九个值的平均值代替中间像素值,所以起到的平滑的效果: 

该卷积核的作用在于取九个值的平均值代替中间像素值,所以起到的平滑的效果: 
这里写图片描述 
这里写图片描述

(3)高斯平滑: 
卷积核: 
这里写图片描述 
高斯平滑水平和垂直方向呈现高斯分布,更突出了中心点在像素平滑后的权重,相比于均值滤波而言,有着更好的平滑效果。 
这里写图片描述 
(4)图像锐化: 
卷积核: 
这里写图片描述 
该卷积利用的其实是图像中的边缘信息有着比周围像素更高的对比度,而经过卷积之后进一步增强了这种对比度,从而使图像显得棱角分明、画面清晰,起到锐化图像的效果。 
这里写图片描述 
除了上述卷积核,边缘锐化还可以选择: 
这里写图片描述 
(5)梯度Prewitt: 
水平梯度: 
这里写图片描述 
这里写图片描述 
垂直梯度: 
这里写图片描述 
这里写图片描述

梯度Prewitt卷积核与Soble卷积核的选定是类似的,都是对水平边缘或垂直边缘有比较好的检测效果。

(6)Soble边缘检测: 
Soble与上述卷积核不同之处在于,Soble更强调了和边缘相邻的像素点对边缘的影响。 
水平梯度: 
这里写图片描述 
这里写图片描述 
垂直梯度: 
这里写图片描述 
这里写图片描述

以上的水平边缘与垂直边缘检测问题可以参考:Soble算子水平和垂直方向导数问题

(7)梯度Laplacian:

卷积核: 
这里写图片描述

这里写图片描述

Laplacian也是一种锐化方法,同时也可以做边缘检测,而且边缘检测的应用中并不局限于水平方向或垂直方向,这是Laplacian与soble的区别。下面这张图可以很好的表征出二者的区别:来源于OpenCV官方文档 

这里写图片描述

代码实现

可以利用OpenCV提供的filter2D函数完成对图像进行卷积操作,其函数接口为:

CV_EXPORTS_W void filter2D(
InputArray src, 
OutputArray dst, 
int ddepth,
InputArray kernel, 
Point anchor=Point(-1,-1),
double delta=0, 
int borderType=BORDER_DEFAULT );
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

第一个参数: 输入图像 
第二个参数: 输出图像,和输入图像具有相同的尺寸和通道数量 
第三个参数: 目标图像深度,输入值为-1时,目标图像和原图像深度保持一致。 
第四个参数: 卷积核,是一个矩阵 
第五个参数:内核的基准点(anchor),其默认值为(-1,-1)说明位于kernel的中心位置。基准点即kernel中与进行处理的像素点重合的点。 
第六个参数: 在储存目标图像前可选的添加到像素的值,默认值为0 
第七个参数: 像素向外逼近的方法,默认值是BORDER_DEFAULT。

#include <iostream>
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace  cv;

int main()
{
    Mat srcImage = imread("1.jpg");
    namedWindow("srcImage", WINDOW_AUTOSIZE);
    imshow("原图", srcImage);
    Mat kernel = (Mat_<double>(3,3) << 
        -1, 0 ,1,
        -2, 0, 2,
        -1, 0, 1);
    Mat dstImage;
    filter2D(srcImage,dstImage,srcImage.depth(),kernel);
    namedWindow("dstImage",WINDOW_AUTOSIZE);
    imshow("卷积图",dstImage);
    waitKey(0);
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

所以代码的实现就非常简单了,不同的卷积操作只需要改变卷积核kernel 即可。




2019-04-07 20:37:39 cqhblg 阅读数 471
  • 深度学习之卷积神经网络CNN以及python案例图片中文本...

    卷积神经网络是深度学习技术中极具代表的网络结构之一,在图像处理领域取得了很大的成功。本课程将会讲解:CNN、卷基层、卷积计算、池化层、池化、全连接等概念。重点讲解如何进行卷积计算?如何进行池化计算?CNN如何训练以及优缺点?什么全连接和激励层?后python图片文本识别的案例。

    1634 人正在学习 去看看 王而川

通俗点说:卷积在图像处理中的应用就是用一个模式矩阵和原图像矩阵相乘,得到一个新的矩阵作为卷积结果

(核:指一组权重的集合,它会应用在源图像的一个区域,并由此生成目标图像的一个像素。比如大小为7的核意味着49(7*7)个源图像的像素会产生目标图像的一个像素。可把核看作一块覆盖在源图像上可移动的毛玻璃片,玻璃片覆盖区域的光线会按某种方式进行扩散混合后透过去。

用一个模板和一幅图像进行卷积,对于图像上的一个点,让模板的原点和该点重合,然后模板上的点和图像上对应的点相乘,然后各点的积相加,就得到该点的卷积值。对图像上的每个点都这样处理。由于多数模板都对称,所以模板不旋转。
卷积是一种积分运算,用来求两个曲线重叠区域面积。可以看作加权求和,可以用来消除噪声、特征增强。 把一个点的像素值用它周围的点的像素值的加权平均代替。)

示例代码:

import cv2 as cv
import numpy as np
from scipy import ndimage

kernel_3x3=np.array([[-1,-1,-1],
                    [-1,8,-1],
                    [-1,-1,-1]])

kernel_5x5=np.array([[-1,-1,-1,-1,-1],
                    [-1,1,2,1,-1],
                    [-1,2,4,2,-1],
                     [-1,1,2,1,-1],
                     [-1,-1,-1,-1,-1]])

img=cv.imread("H:/1.jpg",0)
k3=ndimage.convolve(img,kernel_3x3)
k5=ndimage.convolve(img,kernel_5x5)

blurred=cv.GaussianBlur(img,(11,11),0)
g_phf=img-blurred

cv.imshow("img",img)
cv.imshow("3x3",k3)
cv.imshow("5x5",k5)
cv.imshow("g_phf",g_phf)
cv.waitKeyEx()
cv.destroyAllWindows()

效果:

原图: 

卷积后三张图片:

 

参考博客:https://blog.csdn.net/qq_39521554/article/details/79083864

参考书籍:OpenCV+3计算机视觉++Python语言实现+第二版

2019-08-09 09:32:50 jesseyule 阅读数 333
  • 深度学习之卷积神经网络CNN以及python案例图片中文本...

    卷积神经网络是深度学习技术中极具代表的网络结构之一,在图像处理领域取得了很大的成功。本课程将会讲解:CNN、卷基层、卷积计算、池化层、池化、全连接等概念。重点讲解如何进行卷积计算?如何进行池化计算?CNN如何训练以及优缺点?什么全连接和激励层?后python图片文本识别的案例。

    1634 人正在学习 去看看 王而川

在介绍卷积神经网络之前,我们需要先了解以下卷积运算和互相关运算。很多时候,我们都说卷积神经网络在图像处理方面具有很大的优势,主要原因就在于卷积运算,所以接下来就主要从图像处理和卷积的联系入手进行分析。

卷积运算在概率统计中关于随机变量的和的计算中也有出现,从数学上的定义来看,当我们有两个随机变量分别服从密度函数f和g,如果需要求它们的和t的概率密度,那么就有:

s(t)=fg=f(x)g(x+t)dxs(t) = f*g = \int _{-\infty} ^{\infty} f(x) g(-x+t)dx

这是一维的情况,对于二维,我们可以进一步推广:

s(u,v)=fg=f(x,y)g(x+u,y+v)dxdys(u,v) = f*g = \int _{-\infty} ^{\infty} \int _{-\infty} ^{\infty} f(x,y) g(-x+u, -y+v)dxdy

与卷积运算非常相似的还有互相关运算:

r(t)=fg=fu(x)fv(x+t)dxr (t) = f \bigodot g = \int _{-\infty} ^{\infty} f_u (x) f_v (x+t)dx

二维形式:

r(u,v)=fg=fu(x,y)fv(x+u,y+v)dxdyr (u,v) = f \bigodot g = \int _{-\infty} ^{\infty} \int _{-\infty} ^{\infty} f_u (x,y) f_v (x+u, y+v)dxdy

对比卷积运算和互相关运算公式,就可以发现它们形式上是多么相似,唯一的区别只是正负号,这个区别导致卷积运算涉及到函数翻转而互相关运算不涉及的原因,但这里不细说,而是把重点放在分析为什么这种形式的运算会和图像处理产生联系。在运用卷积神经网络进行图像处理时,原则上既可以使用卷积运算也可以使用互相关运算,两者的效果可以做到完全等同只是算法的细节处理上有所不同,而实际上出于简便性的考虑一般会采用互相关运算,所以接下来的分析主要从互相关运算入手,而后文提到的卷积实际上也是指互相关运算。

首先关于图像处理,我们来看这样一个例子,现在我们有一副黑白图像,用矩阵表示,黑色像素点为1,白色像素点为0:

00000100010001000000 \begin{matrix} 0 &amp; 0 &amp; 0 &amp; 0 \\ 0 &amp; 1 &amp; 0 &amp; 0 \\ 0 &amp; 1 &amp; 0 &amp; 0 \\ 0 &amp; 1 &amp; 0 &amp; 0 \\ 0 &amp; 0 &amp; 0 &amp; 0 \\ \end{matrix}
如果我们现在想要检测这幅图像有没有一条垂直的直线,应该怎么做,这里有一个方法,那就是构建一个反映特征的矩阵,或者说一个具有明显特征的图像矩阵:
010010010 \begin{matrix} 0 &amp; 1 &amp; 0 \\ 0 &amp; 1 &amp; 0 \\ 0 &amp; 1 &amp; 0 \\ \end{matrix}
然后,我们就可以把原图划分成一个个小块,对比是否具有类似我们分析的特征的区域,这个构成,也像我们人类观察的过程,比如我们找一幅图里面有没有眼镜,我们也需要一处处仔细观察,而不能一下子就看完整张图片。那么从数学的角度,这个过程就是原图的矩阵分成和特征矩阵同等大小的一个个小矩阵,比如从左上角开始划分,得到第一个小矩阵:

000010010 \begin{matrix} 0 &amp; 0 &amp; 0 \\ 0 &amp; 1 &amp; 0 \\ 0 &amp; 1 &amp; 0 \\ \end{matrix}
用它和特征矩阵按对应元素相乘得到:

000010010 \begin{matrix} 0 &amp; 0 &amp; 0 \\ 0 &amp; 1 &amp; 0 \\ 0 &amp; 1 &amp; 0 \\ \end{matrix}
r(1,1)=2r(1,1) = 2

按照这样遍历整副图像,最后把每次计算的结果写成矩阵形式,得到:

203020 \begin{matrix} 2 &amp; 0 \\ 3 &amp; 0 \\ 2 &amp; 0 \\ \end{matrix}
根据这个矩阵,我们可以确定阈值为3,达到阈值就认为原图像存在特征,然后就可以判断在原图像中间偏左的位置存在一条垂直直线。

以上的这个过程,其实就是卷积神经网络的核心思想,也是反映了卷积运算和图像处理的关系,其中,反映特征的矩阵称为卷积核,图像就是我们的输入,两者相乘得到的结果称为特征映射图。

还记得一开始说过,互相关运算反映了函数的平移,这种平移就体现在上面提到的卷积核对输入图像遍历过程中的移动,而互相关运算中的两个函数相乘就反映了输入图像和卷积核相乘,最后积分的步骤就反映了卷积核对输入图像的遍历,所以一次遍历得到一个输出结果,作为特征映射图的一个点的值。

想浏览更多关于数学、机器学习、深度学习的内容,可浏览本人博客

2018-11-14 16:07:10 u012005313 阅读数 835
  • 深度学习之卷积神经网络CNN以及python案例图片中文本...

    卷积神经网络是深度学习技术中极具代表的网络结构之一,在图像处理领域取得了很大的成功。本课程将会讲解:CNN、卷基层、卷积计算、池化层、池化、全连接等概念。重点讲解如何进行卷积计算?如何进行池化计算?CNN如何训练以及优缺点?什么全连接和激励层?后python图片文本识别的案例。

    1634 人正在学习 去看看 王而川

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


目录

  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&amp; 2&amp; 3\\ 4&amp; 5&amp; 6\\ 7&amp; 8&amp; 9 \end{bmatrix}\frac{180^{^{\circ}}}{\Rightarrow} \begin{bmatrix} 9&amp; 8&amp; 7\\ 6&amp; 5&amp; 4\\ 3&amp; 3&amp; 1 \end{bmatrix}

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

[123456789][321654987][987654321]\begin{bmatrix} 1&amp; 2&amp; 3\\ 4&amp; 5&amp; 6\\ 7&amp; 8&amp; 9 \end{bmatrix}\Rightarrow \begin{bmatrix} 3&amp; 2&amp; 1\\ 6&amp; 5&amp; 4\\ 9&amp; 8&amp; 7 \end{bmatrix}\Rightarrow \begin{bmatrix} 9&amp; 8&amp; 7\\ 6&amp; 5&amp; 4\\ 3&amp; 2&amp; 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()

在这里插入图片描述

2018-06-07 15:23:46 zuange2417 阅读数 759
  • 深度学习之卷积神经网络CNN以及python案例图片中文本...

    卷积神经网络是深度学习技术中极具代表的网络结构之一,在图像处理领域取得了很大的成功。本课程将会讲解:CNN、卷基层、卷积计算、池化层、池化、全连接等概念。重点讲解如何进行卷积计算?如何进行池化计算?CNN如何训练以及优缺点?什么全连接和激励层?后python图片文本识别的案例。

    1634 人正在学习 去看看 王而川

根据冈萨雷斯一书中的图像卷积概念。

卷积,是把核矩阵顺时针旋转180度,在和图像做变换。这个变换类似书中有,这里不过多解释。

我个人认为,虽然国外都是convolution,译为数学中的卷积是没错,并且人家就是这个数学上的卷积的概念

但其实根据卷积定义,用在图像——二维离散上,积分变为加法,其实更像是实现了矩阵的点积。

所以,当大部分情况,核矩阵旋转后不改变的情况下,当成点积更好理解。

1

博文 来自: Europe233

图像处理(卷积)

阅读数 1325

没有更多推荐了,返回首页