详解边缘检测示例

卷积运算是卷积神经网络最基本的组成部分,使用边缘检测作为入门样例。在这个博客中,会看到卷积是如何进行运算的。

在之前的博客中,说过神经网络的前几层是如何检测边缘的,然后,后面的层有可能检测到物体的部分区域,更靠后的一些层可能检测到完整的物体,这个例子中就是人脸。在这个博客中,会看到如何在一张图片中进行边缘检测。

让举个例子,给了这样一张图片,让电脑去搞清楚这张照片里有什么物体,可能做的第一件事是检测图片中的垂直边缘。比如说,在这张图片中的栏杆就对应垂直线,与此同时,这些行人的轮廓线某种程度上也是垂线,这些线是垂直边缘检测器的输出。同样,可能也想检测水平边缘,比如说这些栏杆就是很明显的水平线,它们也能被检测到,结果在这。所以如何在图像中检测这些边缘?

看一个例子,这是一个6×6的灰度图像。因为是灰度图像,所以它是6×6×1的矩阵,而不是6×6×3的,因为没有RGB三通道。为了检测图像中的垂直边缘,可以构造一个3×3矩阵。在共用习惯中,在卷积神经网络的术语中,它被称为过滤器。要构造一个3×3的过滤器,像这样\(\begin{bmatrix}1 & 0 & -1\\ 1 & 0 & -1\\ 1 & 0 & -1\end{bmatrix}\)。在论文它有时候会被称为核,而不是过滤器,但在这个博客中,将使用过滤器这个术语。对这个6×6的图像进行卷积运算,卷积运算用“\(*\)”来表示,用3×3的过滤器对其进行卷积。

关于符号表示,有一些问题,在数学中“\(*\)”就是卷积的标准标志,但是在Python中,这个标识常常被用来表示乘法或者元素乘法。所以这个“\(*\)”有多层含义,它是一个重载符号,在这个博客中,当“\(*\)”表示卷积的时候会特别说明。

这个卷积运算的输出将会是一个4×4的矩阵,可以将它看成一个4×4的图像。下面来说明是如何计算得到这个4×4矩阵的。为了计算第一个元素,在4×4左上角的那个元素,使用3×3的过滤器,将其覆盖在输入图像,如下图所示。然后进行元素乘法(element-wise products)运算,所以\(\begin{bmatrix} 3 \times 1 & 0 \times 0 & 1 \times \left(1 \right) \\ 1 \times 1 & 5 \times 0 & 8 \times \left( - 1 \right) \\ 2 \times1 & 7 \times 0 & 2 \times \left( - 1 \right) \\ \end{bmatrix} = \begin{bmatrix}3 & 0 & - 1 \\ 1 & 0 & - 8 \\ 2 & 0 & - 2 \\\end{bmatrix}\),然后将该矩阵每个元素相加得到最左上角的元素,即\(3+1+2+0+0 +0+(-1)+(-8) +(-2)=-5\)。

把这9个数加起来得到-5,当然,可以把这9个数按任何顺序相加,只是先写了第一列,然后第二列,第三列。

接下来,为了弄明白第二个元素是什么,要把蓝色的方块,向右移动一步,像这样,把这些绿色的标记去掉:

继续做同样的元素乘法,然后加起来,所以是 $0×1+5×1+7×1+1×0+8×0+2×0+2×(-1)+ 9×(-1)+5×(-1)=-4 $。

接下来也是一样,继续右移一步,把9个数的点积加起来得到0。

继续移得到8,验证一下:\(2×1+9×1+5×1+7×0+3×0+1×0+4×(-1)+ 1×(-1)+ 3×(-1)=8\)。

接下来为了得到下一行的元素,现在把蓝色块下移,现在蓝色块在这个位置:

重复进行元素乘法,然后加起来。通过这样做得到-10。再将其右移得到-2,接着是2,3。以此类推,这样计算完矩阵中的其他元素。

为了说得更清楚一点,这个-16是通过底部右下角的3×3区域得到的。

因此6×6矩阵和3×3矩阵进行卷积运算得到4×4矩阵。这些图片和过滤器是不同维度的矩阵,但左边矩阵容易被理解为一张图片,中间的这个被理解为过滤器,右边的图片可以理解为另一张图片。这个就是垂直边缘检测器。

在往下讲之前,多说一句,如果要使用编程语言实现这个运算,不同的编程语言有不同的函数,而不是用“\(*\)”来表示卷积。所以在编程练习中,会使用一个叫conv_forward的函数。如果在tensorflow下,这个函数叫tf.conv2d。在其他深度学习框架中,在后面的博客中,将会看到Keras这个框架,在这个框架下用Conv2D实现卷积运算。所有的编程框架都有一些函数来实现卷积运算。

为什么这个可以做垂直边缘检测呢?让来看另外一个例子。为了讲清楚,会用一个简单的例子。这是一个简单的6×6图像,左边的一半是10,右边一般是0。如果把它当成一个图片,左边那部分看起来是白色的,像素值10是比较亮的像素值,右边像素值比较暗,使用灰色来表示0,尽管它也可以被画成黑的。图片里,有一个特别明显的垂直边缘在图像中间,这条垂直线是从黑到白的过渡线,或者从白色到深色。

所以,当用一个3×3过滤器进行卷积运算的时候,这个3×3的过滤器可视化为下面这个样子,在左边有明亮的像素,然后有一个过渡,0在中间,然后右边是深色的。卷积运算后,得到的是右边的矩阵。如果愿意,可以通过数学运算去验证。举例来说,最左上角的元素0,就是由这个3×3块(绿色方框标记)经过元素乘积运算再求和得到的,\(10×1+10×1+10×1+10×0+10×0+10×0+10×(-1)+10×(-1)+10×(-1)=0\)

。相反这个30是由这个(红色方框标记)得到的,

\(10×1+10×1+10×1+10×0+10×0+10×0+0×(-1)+0×(-1)+ 0×(-1)=30\)。

如果把最右边的矩阵当成图像,它是这个样子。在中间有段亮一点的区域,对应检查到这个6×6图像中间的垂直边缘。这里的维数似乎有点不正确,检测到的边缘太粗了。因为在这个例子中,图片太小了。如果用一个1000×1000的图像,而不是6×6的图片,会发现其会很好地检测出图像中的垂直边缘。在这个例子中,在输出图像中间的亮处,表示在图像中间有一个特别明显的垂直边缘。从垂直边缘检测中可以得到的启发是,因为使用3×3的矩阵(过滤器),所以垂直边缘是一个3×3的区域,左边是明亮的像素,中间的并不需要考虑,右边是深色像素。在这个6×6图像的中间部分,明亮的像素在左边,深色的像素在右边,就被视为一个垂直边缘,卷积运算提供了一个方便的方法来发现图像中的垂直边缘。

神经网络之卷积篇:详解边缘检测示例(Edge detection example)的更多相关文章

  1. PHP函数篇详解十进制、二进制、八进制和十六进制转换函数说明

    PHP函数篇详解十进制.二进制.八进制和十六进制转换函数说明 作者: 字体:[增加 减小] 类型:转载   中文字符编码研究系列第一期,PHP函数篇详解十进制.二进制.八进制和十六进制互相转换函数说明 ...

  2. 走向DBA[MSSQL篇] 详解游标

    原文:走向DBA[MSSQL篇] 详解游标 前篇回顾:上一篇虫子介绍了一些不常用的数据过滤方式,本篇详细介绍下游标. 概念 简单点说游标的作用就是存储一个结果集,并根据语法将这个结果集的数据逐条处理. ...

  3. 基于双向BiLstm神经网络的中文分词详解及源码

    基于双向BiLstm神经网络的中文分词详解及源码 基于双向BiLstm神经网络的中文分词详解及源码 1 标注序列 2 训练网络 3 Viterbi算法求解最优路径 4 keras代码讲解 最后 源代码 ...

  4. Scala进阶之路-Scala函数篇详解

    Scala进阶之路-Scala函数篇详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.传值调用和传名调用 /* @author :yinzhengjie Blog:http: ...

  5. Wordpress菜单函数wp_nav_menu各参数详解及示例

    Wordpress菜单函数wp_nav_menu各参数详解及示例   注册菜单 首先要注册菜单,将以下函数添加至function.php函数里   register_nav_menus(array( ...

  6. Oracle创建表语句(Create table)语法详解及示例、、 C# 调用Oracle 存储过程返回数据集 实例

    Oracle创建表语句(Create table)语法详解及示例 2010-06-28 13:59:13|  分类: Oracle PL/SQL|字号 订阅 创建表(Create table)语法详解 ...

  7. Kubernetes K8S之affinity亲和性与反亲和性详解与示例

    Kubernetes K8S之Node节点亲和性与反亲和性以及Pod亲和性与反亲和性详解与示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-mas ...

  8. 第十五节,卷积神经网络之AlexNet网络详解(五)

    原文 ImageNet Classification with Deep ConvolutionalNeural Networks 下载地址:http://papers.nips.cc/paper/4 ...

  9. Android总结篇——Intent机制详解及示例总结

         最近在进行android开发过程中,在将 Intent传递给调用的组件并完成组件的调用时遇到点困难,并且之前对Intent的学习也是一知半解,最近特意为此拿出一些时间,对Intent部分进行 ...

  10. FFmpeg(2)-avformat_open_input()函数详解并示例打开mp4文件

    一. 解封装 pts 是显示的时间 dts是解码的时间, 这个时间是用来做同步. av_register_all(), 注册所有的格式.包括解封装格式和加封装格式. avformat_network_ ...

随机推荐

  1. 技术解密Java Chassis 3超实用的可观测性

    本文分享自华为云社区<Java Chassis 3技术解密:实用的可观测性>,作者:liubao68. 狭义的可观测性,指日志.调用链和指标,广义的可观测性则包含更多的内容,一般的,应用程 ...

  2. Elasticsearch如何聚合查询多个统计值,如何嵌套聚合?并相互引用,统计索引中某一个字段的空值率?语法是怎么样的?

    目录 Elasticsearch聚合查询说明 空值率查询DSL Elasticsearch聚合基础知识扩展 Elasticsearch聚合概念 Script 用法 Elasticsearch聚合查询语 ...

  3. poj1338 ugly number 题解 打表

    类似的题目有HDU1058 humble number(翻译下来都是丑陋的数字). Description Ugly numbers are numbers whose only prime fact ...

  4. mysql8的collate问题和修改

    环境 os:centos 7.6 数据库:8.0.22 64bit 问题: 字段a,b它们的collate不一样,结果关联的时候,发现错误. 查询了以下,发现挺多的,逐个修改挺麻烦的,于是整理了如下s ...

  5. Linux安全审计之audit安装与使用

    场景 安全最重要的一步是内部安全,如何监控用户的行为是一个永恒不变的话题. audit可以详细监控用户的行为,详细到查看或修改了某个文件.这些都可以在日志中查看到. 安装 小贴士: CentOS默认已 ...

  6. Mysql生成实体类

    -- 查询数据表结构 SELECT CONCAT('"e.',SUBSTRING(COLUMN_NAME,1),',"+'),COLUMN_NAME,',',COLUMN_TYPE ...

  7. SpringCloud 微服务与微服务对接心德

    导读 先简单介绍下背景,公司里的项目,有一块需要与公司里的其他项目组对接.我们这边用的注册中心Nacos,对方用的eureka,之前都是自己写接口,然后服务中引入这个接口工程,都是注册到同一个注册中心 ...

  8. Spring里面bean的依赖和继承

    继承 bean继承:两个类之间大多数的属性都相同,避免重复配置,通过bean标签的parent属性重用已有的Bean元素的配置信息 继承指的是配置信息的复用,和java类的继承没有关系 video.j ...

  9. 全网最适合入门的面向对象编程教程:10 类和对象的 Python 实现-类的继承和里氏替换原则,Python 模拟主机和传感器自定义类

    全网最适合入门的面向对象编程教程:10 类和对象的 Python 实现-类的继承和里氏替换原则,Python 模拟主机和传感器自定义类 摘要: 本文主要介绍了类的继承的基本概念和里氏替换原则,以模拟传 ...

  10. 疑难杂症(已解决) | 为什么出现python中tkinter创建界面需要一闪而过才进入主窗口?

    一.具体问题 如图所示,我编写了一个主窗口的程序(如下所示,有兴趣的可以自己复制后运行),发现需要先进入第一个窗口再进入主界面,这不符合逻辑. 代码区域(完整代码): from tkinter imp ...