计算机视觉中的边缘检测

边缘检测是计算机视觉中最重要的概念之一。这是一个很直观的概念,在一个图像上运行图像检测应该只输出边缘,与素描比较相似。我的目
标不仅是清晰地解释边缘检测是怎样工作的,同时也提供一个新而又容易的方法只需要最小工作来明显地提高边缘检测。

通过获得这些边缘,许多计算机算法才得以有可能实现,因为在一个场景中边缘包含着绝大部分(至少很多)的信息。

举个例子,我们都记得 Windows XP 的那个绿色小山坡和蓝色天空的背景。

当我们的大脑试图去理解这个场景时,我们知道这是草地,看起来很统一。然后,我们看到了飘着些许白云的天空。这些对象的每一个都是分离的,而且它们之间有一个边缘。这就是场景中为什么绝大部分的信息存在与边缘中。

这也是为什么边缘检测是计算机视觉中的重要概念。通过把图像减少到只剩下边缘,使得对于许多算法更容易识别、学习、或者处理场景。

边缘检测:滤波

边缘检测的大多数是基于滤波的。通常来说,滤波是一个消除的动作。比如:过滤水,是消除寄生虫。相似地,当我们尝试找到图像边缘时,我是在尝试消除掉除图像边缘之外的东西。

消除那些不是有用的边缘的图像部分,而留下合适的边缘也是困难所在。我怎么知道这是不是有用的边缘,比如,我对 Windows XP 背景运行 Canny edge dectector 程序,效果如下。

你能看到那些小草的细小刀刃似的边缘,这很让人讨厌,而且没有真正提供有用的信息。甚至那些云朵也不是非常清晰。现在,你能在大多数的 Canny edge dectector 上设置一些边界,这些边界设置了阈值(或者 非极大值抑制),所有的边缘必须满足这个阈值才能划分为“重要的”边缘。与其在 Canny edge 的阈值上区分,不如我们更广泛地来谈谈,并且搭建几个滤波器。

边缘检测:高斯滤波器

高斯滤波器是边缘检测最基础的滤波器之一,虽然还有其他的,但是高斯滤波器会贯穿这篇文章。高斯滤波器,正如其名,是一个基于高斯分布的滤波器。

它看起来像一个抛物线(除了在二维的情况)。通过矩阵乘法,高斯滤波器能被应用到每一个像素上。它实现的是混合效果,让最中心的像素尽量小基于它相邻的像素。举个例子,如对我的猫的图像运行一个均匀分布的高斯滤波器,我能够得到下面的图像:

5.jpg

你可以看到图像变得模糊了,高斯滤波器就是获取所有像素,让像素值的成分是与相邻像素有关。

为了让高斯滤波器在边缘检测中有效,我们可以使用从 x 和 y 方面求导出来的高斯滤波器。这也许听起来有点反直觉,或者不知所谓,但是如果我们看到这种导数高斯滤波器的图像,这种想法就很清晰了。

当你把一个高斯的 x 和 y 分量求导后,一个大的波峰 和波谷就出现了。如果你明白导数,思考下这种情况,你应该能很快想到。由于高斯函数峰上数值上的巨大变化,从而导致了高斯导数波峰和波谷的出现。

如果我们把上面的写成代码,那相当直接(至少对于 Matlab 和 Python 来说):

% Takes the derivative of a 5x5 gaussian, with a sigma
[hx, hy] = gradient(fspecial('gaussian',[5 5],sigma));

这就是了,一行代码就能得到我们所想要的高斯,然后对x 和 y 分量求导。

边缘检测:应用滤波器

我们已经有了两个高斯滤波器,我们把他们应用到图像中。我们同样使用非极大值限制,即如果不是极大值的话,就把像素值设置为0。换种说法就是消除噪声。

应用滤波器的代码如下:

% Convert an image to double for increased precision
img = double(img);
% Find two derived gaussians with respect to x and y
[hx, hy] = gradient(fspecial('gaussian',[5 5],sigma));
% Run the filters over the image, generating a filtered image
% Leaves x edges
gx = double(imfilter(img,hx,'replicate', 'conv'));
% Leaves y edges
gy = double(imfilter(img,hy,'replicate', 'conv'));
% Take the absolute value, and combine the x and y edges
mag = sqrt((gx .* gx) + (gy .* gy));
% Use non-maxima suppression
[mag, ] = max(mag, [], 3);

如果我们将它应用我的猫的一张图片,我我们就得到一下的图片:

有趣地是,我们同样也能这种方法应用到 RGB 图像上去,同样也会得到彩色的边缘。

普通的边缘滤波器应用到猫的RGB图像

这两张图片应该都能代表像素和它相邻之间像素的颜色的差异,只不过彩色图像有3层,而黑白图像只有1层。(层,翻译不是很好)

边缘检测:方向滤波器

为什么要限制我们自己仅仅使用绝对的 x 和 y 方向的滤波器呢?让我们也来构建一些方向滤波器。这个方法(或多或少)来源于 Freeman 和 Adelson 的《The design and use of steerable filters》论文,这个想法使我们能够把我们的高斯滤波器放置在不同的方向。

根本上,我们把我们的高斯滤波器放置到不同的方向上去,以基于与高斯相关的边缘的角度来创建不同数值。比如,如果我们把高斯函数放置到45度,应用到45度角的图像上,应该可以比在0度的高斯函数得到更高的数量级。

在这种情况下,我生成了几种不同的方向滤波器:

上行x分量,下行y分量

各种各样的高斯函数产生了相对于x 和 y 分量上的90、45、-45 和 22.5 度的滤波器。这也就产生了不同的边缘大小,尽管这些滤波器应该检测出相近的边缘。

我使用的代码与单个滤波器使用的代码几乎相同,但是我不同以往地把他们混合在一起。它看起来有点杂乱,但是我通过让我运行每个滤波器表达更明白来尽可能使它看起来更清晰。

% Create four filters
[hx, hy] = gradient(fspecial('gaussian',[5 5],sigma));
[hx1, hy1] = altOrientFilter1(hx, hy);
[hx2, hy2] = altOrientFilter2(hx, hy);
[hx3, hy3] = altOrientFilter3(hx, hy);% Run first gaussian filter on image
gx = double(imfilter(img,hx,'replicate', 'conv'));
gy = double(imfilter(img,hy,'replicate', 'conv'));
% Run second gaussian filter on image
gx1 = double(imfilter(img,hx1,'replicate', 'conv'));
gy1 = double(imfilter(img,hy1,'replicate', 'conv'));
% Run third gaussian filter on image
gx2 = double(imfilter(img,hx2,'replicate', 'conv'));
gy2 = double(imfilter(img,hy2,'replicate', 'conv'));
% Run fourth gaussian filter on image
gx3 = double(imfilter(img,hx3,'replicate', 'conv'));
gy3 = double(imfilter(img,hy3,'replicate', 'conv'));% Merge all filters
squareGD = (gx .* gx) + (gy .* gy);
squareGD = squareGD + (gx1 .* gx1) + (gy1 .* gy1);
squareGD = squareGD + (gx2 .* gx2) + (gy2 .* gy2);
squareGD = squareGD + (gx3 .* gx3) + (gy3 .* gy3);% Run non-maxima supression
[mag, ] = max(sqrt(squareGD), [], 3);

如果你靠近点看的话,你能看到数量大小的不同,特别是那些皱纹。如果我们混合了所有图像,我们就能得到一张轻微较好的边缘检测。

方向滤波器和非方向滤波器之间并没有很大的不同,但是我们也应该看到多种方向的结果有些许的提高。

边缘检测:提高彩色域

过去两年,我在不同的彩色域上做了大量的测试和实验。特别地是,Lab 彩色域是另一种描述图像的方式。比如,我们知道的RGB 和灰度图像,或者你甚至可能知道YUV空间。 Lab 彩色域与之非常相似。

我对Lab 彩色感兴趣的原因是它对产生场景的边缘有着优异的能力。

Lab 彩色空间的每个字母表示:

  • L —— Luminance亮度
  • a —— alpha —— 红到绿
  • b —— beta —— 黄到蓝

事实上,这些颜色通道非常适合发现颜色变化梯度,正自然而然地黄色很少出现另一个黄色周围,红色和绿色也是如此。(尽管我已经彻底证明了)。Lab 彩色空间与我们人类怎样察觉颜色中的亮度有很强的相关性。与RGB相反的是,在Lab 彩色空间中亮度有它自己的分离通道,这使得它能更好地处理颜色的差异,这些差异也是亮度与颜色相关之处。

为了最小化额外的代码,我们所要做的就是把输入的图像转化为Lab彩色空间的图像。你可以做一些最优化,不过你仅仅做了这额外的一步也能明显提高适宜的边缘检测。

% Convert an image to the Lab color space
colorTransform = makecform('srgb2lab');
img = applycform(rgbImg, colorTransform);% Make it double to improve representation
img = double(img);% Find x and y derivative of a 9x9 gaussian
[hx, hy] = gradient(fspecial('gaussian',[9 9],sigma));% Apply filters
gx = double(imfilter(img,hx,'replicate'));
gy = double(imfilter(img,hy,'replicate'));% Find absolute value
gSquared = sqrt(gx .* gx) + (gy .* gy);% Apply non-maxima suppression (find best points for edges)
[mag, ] = max(gSquared, [], 3);

如果我们将 Windows XP 小山坡的背景图像转换为Lab,我们将得到下面的图像:

Windows XP 背景的Lab空间图像

然后如果我们施加滤波器(非极大值抑制)将得到下面的图像,清晰的包含着草地、云、草地和天空的分界线的图象。

在Lab 空间上边缘检测

最终,如果我们运行非极大值抑制,那么我们将得到比本文开头提到的 Canny边缘检测器要好得多的边缘效果。

Lab 彩色空间边缘检测

平均来说,这种方法会比普通方法提高 10% 左右的边缘检测精度。这是对 The Berkeley Segmentation Dataset and Benchmark 运行 F-measure 测试得到的结果。

边缘检测:结语

有无数的方法去做边缘检测,这里讲述的方法绝不是最好、最容易实现、最容易解释的。

我使用这些方法解释它是因为我对它们很有兴趣。。。加上这是 UIUC的CS543课程《计算机视觉》布置的作业,所以你也在上这门课,请不要抄袭我的代码!

我已经把我们所有的实现都放到了 github 上了。包括用 C++ 的 OpenCV 实现。

然而,如果你想跟我的猫照相,这没什么问题。

建议阅读

  • PCA: Principal Component Analysis
  • Everyday Algorithms: Pancake Sort
  • Using Computer Vision to Improve EEG Signals
  • Introduction to Markov Processes
  • The Cache and Multithreading

参考文献

[1] Canny, John. “A computational approach to edge detection.” Pattern Analysis and Machine Intelligence, IEEE Transactions on 6 (1986): 679-698.

[2] Freeman, William T., and Edward H. Adelson. “The design and use of steerable filters.” IEEE Transactions on Pattern analysis and machine intelligence 13.9 (1991): 891-906.


这是本人课余时间的翻译,如有错误,还请耐心指出,谢谢!
原文链接请点击原文链接

计算机视觉中的边缘检测相关推荐

  1. 计算机视觉 专业术语,计算机视觉中常用的术语.doc

    计算机视觉中常用的术语 计算机视觉常用术语中英文对照(1) 2011-06-08 21:26 ??Artificial Intelligence 认知科学和神经科学Cognitive Science ...

  2. 深度学习在计算机视觉中的应用长篇综述

    深度学习在计算机视觉中的应用长篇综述 前言 2012年ImageNet比赛,使深度学习在计算机视觉领域在全世界名声大震,由此人工智能的全球大爆发.第一个研究CNN的专家使Yann LeCun,现就职于 ...

  3. 如何通过深度学习,完成计算机视觉中的所有工作?

    Mask-RCNN做对象检测和实例分割 作者 | George Seif 译者 | 天道酬勤,责编 | Carol 出品 | AI科技大本营(ID:rgznai100) Mask-RCNN做对象检测和 ...

  4. 计算机视觉中的自注意力

    点击上方"视学算法",选择加"星标"或"置顶" 重磅干货,第一时间送达 作者丨Branislav Holländer 来源丨CV技术指南 编 ...

  5. 理解计算机视觉中的损失函数

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 导读 损失函数在模型的性能中起着关键作用.选择正确的损失函数可以帮 ...

  6. 【ICML2021】计算机视觉中的自注意力机制教程,谷歌伯克利出品

    本教程将介绍自注意力机制在计算机视觉中的应用.Self-Attention在NLP中被广泛采用,完全注意的Transformer模型已经在很大程度上取代了RNN,现在被用于最先进的语言理解模型,如GP ...

  7. 图像处理和计算机视觉中的经典论文

    转自:http://www.cnblogs.com/moondark/archive/2012/04/20/2459594.html 感谢水木上同领域的同学分享,有了他的整理,让我很方便的获得了CV方 ...

  8. 图像处理与计算机视觉:基础,经典以及最近发展(3)计算机视觉中的信号处理与模式识别

    从本章开始,进入本文的核心章节.一共分三章,分别讲述信号处理与模式识别,图像处理与分析以及计算机视觉.与其说是讲述,不如说是一些经典文章的罗列以及自己的简单点评.与前一个版本不同的是,这次把所有的文章 ...

  9. 图像处理和计算机视觉中的经典论文(部分)

    自己视野狭小,不敢说全部,只是把自己熟悉的方向中的部分经典文章列出来了.经典的论文,读得怎么透都不过分.有人说关于配准的文章太多了,其实我也不太关注这方面,不过由于它们引用率都比较高,就都列出来了,不 ...

最新文章

  1. 玩远程 可视对讲系统几大新兴应用分析
  2. Java通过Pattern类使用正则表达式
  3. java程序中可以有几个构造方法_java中多个构造方法可以相互引用么?
  4. WinCE项目-UPS电源管理系统
  5. 关于内存的划分和传引用传参数的区别
  6. C语言atoi()函数:将字符串转换成int(整数)和sprintf和memset
  7. 让安全威胁无所遁形,全方位掌握攻击“前世今生”的黑科技来了
  8. 华北科技学院计算机科学与技术分数线,2019年华北科技学院优势专业排名及分数线...
  9. c#后台如何导出excel到本地_小程序导出数据到excel表,借助云开发后台实现excel数据的保存...
  10. oracle+dg常用命令,DG 日常管理命令汇总
  11. redis学习-摘抄
  12. Linux2.6用户空间堆栈区的分配与回收
  13. console.log()中的运算与打印事件
  14. 海康威视摄像头Android直播APP开发
  15. SpreadJS 2021 V14.1 Crack
  16. Web站点的欢迎页面 web.xml - welcome-file-list
  17. POJ 3080 Blue Jeans(KMP + 暴力)
  18. leetcode:954. 二倍数对数组
  19. Logcat的操作使用方法
  20. 【英语:基础高阶_经典外刊阅读】L3.长句子扒皮—如何快速寻找主干

热门文章

  1. PLSQL添加和删除字段
  2. html引入外部less文件,如何引用less文件?
  3. Java 并发编程之美:并发编程高级篇之一-chat
  4. html使用阿里图标库(iconfont)制作字体图标
  5. 对一级标题二级标题进行排序
  6. 国内IT公司病的有多重?技术圈交际花谈软件研发管理怪现状
  7. 【单片机原理及应用日志】用取模软件提取汉字字模,在LCD屏上显示界面
  8. 跨平台长连接组件设计及可插拔改造
  9. Linux 登陆 分辨率,Linux系统登陆前后 分辨率不一致的问题
  10. 【AI PC端算法优化】一,一步步优化RGB转灰度图算法